Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/role preference options #1142

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5e549e3
allow role avoiding, role RNG optimized
EntranceJew Dec 10, 2023
9ff6bab
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 18, 2023
fdd18d7
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 19, 2023
9121aa3
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 19, 2023
0cad328
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 19, 2023
bc466e5
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
5de648e
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
845348c
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
2c72f38
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
393f6f3
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
24cc875
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 20, 2023
988ea27
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 22, 2023
3b3b866
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 22, 2023
f718dc8
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 23, 2023
c3d9fde
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 25, 2023
af3e270
allow role avoiding, role RNG optimized
EntranceJew Dec 10, 2023
ea96711
Merge remote-tracking branch 'origin/feature/role-preference-options'…
EntranceJew Dec 25, 2023
6292d93
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 27, 2023
15b40ce
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 27, 2023
43d8d3d
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 30, 2023
9a1b12b
Merge branch 'master' into feature/role-preference-options
EntranceJew Dec 31, 2023
3d2274a
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 4, 2024
8e9f04f
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 7, 2024
e97f203
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 8, 2024
dfd5605
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 8, 2024
a98d02d
changelog migrate
EntranceJew Jan 8, 2024
5af37d2
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 10, 2024
dae87eb
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 11, 2024
aaa1f19
Merge branch 'master' into feature/role-preference-options
EntranceJew Jan 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ All notable changes to TTT2 will be documented here. Inspired by [keep a changel
- Moved reset buttons onto the left (by @a7f3)
- Added ammo icons to the weapon switch HUD and player status HUD elements (by @EntranceJew)
- Changed the disguiser icon to be more fitting (by @TimGoll)
- Role selection RNG improvements (by @EntranceJew):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also in my opinion there are no RNG improvements, as you said in this PR, it generally only "made dead code not dead"

- Uses `Player:CanSelectRole()` now instead of duplicating logic.
- Option for server to disregard player role selection preferences.
- Players can choose to avoid Traitor, in addition to the other base classes.

### Fixed

Expand Down
22 changes: 16 additions & 6 deletions gamemodes/terrortown/gamemode/server/sv_player_ext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -759,13 +759,23 @@ end
-- @return boolean
-- @realm server
function plymeta:CanSelectRole(roleData, choice_count, role_count)
local min_karmas = ConVarExists("ttt_" .. roleData.name .. "_karma_min") and GetConVar("ttt_" .. roleData.name .. "_karma_min"):GetInt() or 0
-- if there aren't enough players anymore to have a greater role variety
if choice_count <= role_count then return true end

return (
choice_count <= role_count
or self:GetBaseKarma() > min_karmas and GAMEMODE.LastRole[self:SteamID64()] == ROLE_INNOCENT
or math.random(3) == 2
) and (choice_count <= role_count or not self:GetAvoidRole(roleData.index))
-- and the player doesn't avoid this role
local allowRoleAvoiding = GetConVar("ttt2_roles_allow_avoiding"):GetBool()
if allowRoleAvoiding and self:GetAvoidRole(roleData.index) then return false end

-- or the player has enough karma
local minKarmaCVar = GetConVar("ttt_" .. roleData.name .. "_karma_min")
local minKarma = minKarmaCVar and minKarmaCVar:GetInt() or 0
if KARMA.cv.enabled:GetBool() and self:GetBaseKarma() > minKarma then return true end

-- or if the randomness decides
local trickleRate = roleselection.trickleDownRate
if trickleRate > 0 and math.random(trickleRate) == 1 then return true end

return false
end

---
Expand Down
56 changes: 24 additions & 32 deletions gamemodes/terrortown/gamemode/server/sv_roleselection.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ roleselection.finalRoles = {}
roleselection.selectableRoles = nil
roleselection.baseroleLayers = {}
roleselection.subroleLayers = {}
roleselection.trickleDownRate = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still can have a sane default, as it was there before too with the random(3) == 2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still 0, should be at least 3.


-- Convars
roleselection.cv = {
Expand All @@ -33,7 +34,7 @@ roleselection.cv = {

---
-- @realm server
ttt_max_baseroles_pct = CreateConVar("ttt_max_baseroles_pct", "0", {FCVAR_NOTIFY, FCVAR_ARCHIVE}, "Maximum amount of different baseroles based on player amount. ttt_max_baseroles needs to be 0")
ttt_max_baseroles_pct = CreateConVar("ttt_max_baseroles_pct", "0", {FCVAR_NOTIFY, FCVAR_ARCHIVE}, "Maximum amount of different baseroles based on player amount. ttt_max_baseroles needs to be 0"),
}

-- saving and loading
Expand Down Expand Up @@ -572,10 +573,14 @@ local function SetSubRoles(plys, availableRoles, selectableRoles, selectedForced
local plysAmount = #plys
local availableRolesAmount = #availableRoles
local tmpSelectableRoles = table.Copy(selectableRoles)
-- plys are already shuffled, continue with existing priority
local newPlys = table.Copy(plys)

while plysAmount > 0 and availableRolesAmount > 0 do
local pick = math.random(plysAmount)
local ply = plys[pick]
for i = #newPlys, 1, -1 do
Comment on lines -576 to +579
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The for loop here also has the wrong behaviour. It only goes through every player once. But it could be that some players are not assigned.

if not (plysAmount > 0 and availableRolesAmount > 0) then
break
end
local ply = plys[i]

local rolePick = math.random(availableRolesAmount)
local subrole = availableRoles[rolePick]
Expand All @@ -586,16 +591,8 @@ local function SetSubRoles(plys, availableRoles, selectableRoles, selectedForced
roleCount = roleCount - selectedForcedRoles[subrole]
end

local minKarmaCVar = GetConVar("ttt_" .. roleData.name .. "_karma_min")
local minKarma = minKarmaCVar and minKarmaCVar:GetInt() or 0

-- give this player the role if
if plysAmount <= roleCount -- or there aren't enough players anymore to have a greater role variety
or ply:GetBaseKarma() > minKarma -- or the player has enough karma
and not ply:GetAvoidRole(subrole) -- and the player doesn't avoid this role
or math.random(3) == 2 -- or if the randomness decides
then
table.remove(plys, pick)
if ply:CanSelectRole(roleData, plysAmount, availableRolesAmount) then
table.remove(newPlys, i)

roleselection.finalRoles[ply] = subrole

Expand Down Expand Up @@ -782,30 +779,22 @@ end
local function SelectBaseRolePlayers(plys, subrole, roleAmount)
local curRoles = 0
local plysList = {}
local roleData = roles.GetByIndex(subrole)

local minKarmaCVar = GetConVar("ttt_" .. roles.GetByIndex(subrole).name .. "_karma_min")
local min_karmas = minKarmaCVar and minKarmaCVar:GetInt() or 0

while curRoles < roleAmount and #plys > 0 do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesnt removing this while loop here means, that players might not get a role in this pass?

As far as I can see, the "CanSelectRole" method can most often just return false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also unsure about what this change implies for the selection process further down.

We need to think of the assumptions, that were made for what this function does codewise.
It always tries to assign players to the given subrole until roleAmount of players received the role.
This is now not the case anymore and we need to check if that is assumed to happen here and if other functionality relies on that to happen etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(After requested Review)
Isnt this still having the same problem here?
Exchanging the while loop with a for loop seems like different behaviour?

-- select random index in plys table
local pick = math.random(#plys)

for i = #plys, 1, -1 do
-- the player we consider
local ply = plys[pick]

-- give this player the role if
if subrole == ROLE_INNOCENT -- this role is an innocent role
or #plys <= roleAmount -- or there aren't enough players anymore to have a greater role variety
or ply:GetBaseKarma() > min_karmas -- or the player has enough karma
and not ply:GetAvoidRole(subrole) -- and the player doesn't avoid this role
or math.random(3) == 2 -- or if the randomness decides
then
table.remove(plys, pick)
local ply = plys[i]
-- do not unbrace this
if not (curRoles < roleAmount and #plys > 0) then break end
EntranceJew marked this conversation as resolved.
Show resolved Hide resolved

if subrole == ROLE_INNOCENT or ply:CanSelectRole(roleData, #plys, roleAmount) then
curRoles = curRoles + 1
plysList[curRoles] = ply

roleselection.finalRoles[ply] = subrole -- give the player the final baserole (maybe he will receive his subrole later)
-- give the player the final baserole (maybe he will receive his subrole later)
roleselection.finalRoles[ply] = subrole

table.remove(plys, i)
end
end

Expand All @@ -826,6 +815,9 @@ function roleselection.SelectRoles(plys, maxPlys)

plys = roleselection.GetSelectablePlayers(plys or player.GetAll())

-- Randomize role assignment by shuffling the list early.
table.Shuffle(plys)

maxPlys = maxPlys or #plys

if maxPlys < 2 then return end -- we don't need to select anything if there is just one player
Expand Down
4 changes: 4 additions & 0 deletions gamemodes/terrortown/gamemode/shared/sh_rolelayering.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

rolelayering = {}

---
-- @realm shared
CreateConVar("ttt2_roles_allow_avoiding", "1", {FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_REPLICATED}, "If enabled, players will be allowed to avoid specific roles.")

local function SendLayerData(layerTable)
local layerTableSize = #layerTable

Expand Down
6 changes: 5 additions & 1 deletion lua/terrortown/entities/roles/traitor/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ function ROLE:PreInitialize()
pct = 0.4,
maximum = 32,
minPlayers = 1,

traitorButton = 1,

credits = 2,
creditsAwardDeadEnable = 1,
creditsAwardKillEnable = 1
creditsAwardKillEnable = 1,

togglable = true
}
end
5 changes: 5 additions & 0 deletions lua/terrortown/lang/en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2074,6 +2074,11 @@ L.label_keyhelper_ammo_drop = "drop ammo from selected weapon out of clip"
-- 2023-11-18
L.entity_pickup_owner_only = "Only the owner can pick this up"

-- 2023-11-20
L.help_ttt_role_avoid_disabled = "WARNING! Role avoidance is disabled on this server, but you can still change your settings here."
L.label_roles_allow_avoiding = "Allow Avoiding Roles"
L.help_roles_allow_avoiding = "If enabled, allows players to opt out of specific roles from within the Avoid Role Selection menu."

-- 2023-12-18
L.body_confirm_one = "{finder} confirmed the death of {victim}."
L.body_confirm_more = "{finder} confirmed the {count} deaths of: {victims}."
9 changes: 9 additions & 0 deletions lua/terrortown/menus/gamemode/administration/roles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ function CLGAMEMODESUBMENU:Populate(parent)
master = masterEnb
})

form:MakeHelp({
label = "help_roles_allow_avoiding"
})

form:MakeCheckBox({
serverConvar = "ttt2_roles_allow_avoiding",
label = "label_roles_allow_avoiding"
})

local form2 = vgui.CreateTTT2Form(parent, "header_roles_reward_credits")

form2:MakeHelp({
Expand Down
7 changes: 7 additions & 0 deletions lua/terrortown/menus/gamemode/gameplay/avoidroles.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ CLGAMEMODESUBMENU.title = "submenu_gameplay_avoidroles_title"
function CLGAMEMODESUBMENU:Populate(parent)
local form = vgui.CreateTTT2Form(parent, "header_roleselection")

if GetConVar("ttt2_roles_allow_avoiding"):GetBool() then
form:MakeHelp({
label = "help_ttt_role_avoid_disabled"
})
end


local roles = roles.GetList()

for i = 1, #roles do
Expand Down