From 58900797ae8cac9988b5616ea78255713131c89b Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 6 Nov 2019 18:55:54 -0700 Subject: [PATCH 1/5] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 101 +++++++++++++++++++------------ 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 17e26e66af..d59689b19e 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -305,48 +305,73 @@ // The odds become: // Player A: 150 / 250 = 0.6 = 60% // Player B: 100 / 250 = 0.4 = 40% -/datum/game_mode/proc/antag_pick(list/datum/candidates) + +//Use return list if you want a list, with the arg being the number you want returned. +//WARNING: THIS PROC DOES NOT TAKE INTO ACCOUNT WHAT SSPersistence ALREADY HAS FOR "ADJUST ANTAG REP". If this is used more than once +//and the person rolls more than once, they will not get even more deduction! +/datum/game_mode/proc/antag_pick(list/datum/mind/candidates, return_list = FALSE, fail_default_pick = TRUE) if(!CONFIG_GET(flag/use_antag_rep)) // || candidates.len <= 1) return pick(candidates) - // Tickets start at 100 - var/DEFAULT_ANTAG_TICKETS = CONFIG_GET(number/default_antag_tickets) + //whoever named the config entries is a bad person :( - // You may use up to 100 extra tickets (double your odds) - var/MAX_TICKETS_PER_ROLL = CONFIG_GET(number/max_tickets_per_roll) - - - var/total_tickets = 0 - - MAX_TICKETS_PER_ROLL += DEFAULT_ANTAG_TICKETS - - var/p_ckey - var/p_rep - - for(var/datum/mind/mind in candidates) - p_ckey = ckey(mind.key) - total_tickets += min(SSpersistence.antag_rep[p_ckey] + DEFAULT_ANTAG_TICKETS, MAX_TICKETS_PER_ROLL) - - var/antag_select = rand(1,total_tickets) - var/current = 1 - - for(var/datum/mind/mind in candidates) - p_ckey = ckey(mind.key) - p_rep = SSpersistence.antag_rep[p_ckey] - - var/previous = current - var/spend = min(p_rep + DEFAULT_ANTAG_TICKETS, MAX_TICKETS_PER_ROLL) - current += spend - - if(antag_select >= previous && antag_select <= (current-1)) - SSpersistence.antag_rep_change[p_ckey] = -(spend - DEFAULT_ANTAG_TICKETS) - -// WARNING("AR_DEBUG: Player [mind.key] won spending [spend] tickets from starting value [SSpersistence.antag_rep[p_ckey]]") - - return mind - - WARNING("Something has gone terribly wrong. /datum/game_mode/proc/antag_pick failed to select a candidate. Falling back to pick()") - return pick(candidates) + //Tickets you get for free + var/free_tickets = CONFIG_GET(number/default_antag_tickets) + //Max extra tickets you can use + var/additional_tickets = CONFIG_GET(number/max_tickets_per_roll) + + var/list/ckey_to_mind = list() //this is admittedly shitcode but I'm webediting + var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory + var/list/curr_tickets = list() + var/list/spend_tickets = list() + for(var/datum/mind/M in candidates) + var/mind_ckey = ckey(M.key) + var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll + spend_tickets[mind_ckey] = can_spend + var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free + if(amount <= 0) //if they don't have any + continue //too bad! + curr_tickets[mind_ckey] = amount + ckey_to_mind[mind_ckey] = M //make sure we can look them up after picking + + if(!return_list) //return a single guy + var/ckey + if(length(curr_tickets)) + ckey = pickweight(curr_tickets) + SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what they spent + var/mind = ckey_to_mind[ckey] //we want their mind + if(!mind) + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + if(fail_default_pick) + mind = pick(candidates) + return mind + else //the far more efficient and proper use of this, to get a list + var/list/rolled = list() + for(var/i in 1 to return_list) + if(!length(curr_tickets)) //ah heck, we're out of candidates.. + break + var/ckey = pickweight(curr_tickets) //pick + rolled += ckey //add + curr_tickets -= ckey //don't roll them again + if(!length(rolled)) + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + var/list/failed = list() + if(fail_default_pick) + var/list/C = candidates.Copy() + for(var/i in 1 to return_list) + if(!length(C)) + break + failed += pick_n_take(C) + return failed //Wew, no one qualified! + for(var/i in 1 to length(rolled)) + var/ckey = rolled[i] + SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what all of the folks who rolled spent + rolled[i] = ckey_to_mind[ckey] //whoever called us wants minds, not ckeys + return rolled /datum/game_mode/proc/get_players_for_role(role) var/list/players = list() From c8a8e20f42408bf7c1b61d19eb261fb808852ff0 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 6 Nov 2019 19:02:27 -0700 Subject: [PATCH 2/5] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index d59689b19e..0ea37a1158 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -321,13 +321,11 @@ var/additional_tickets = CONFIG_GET(number/max_tickets_per_roll) var/list/ckey_to_mind = list() //this is admittedly shitcode but I'm webediting - var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory - var/list/curr_tickets = list() - var/list/spend_tickets = list() + var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory. how many tickets someone has stored + var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets for(var/datum/mind/M in candidates) var/mind_ckey = ckey(M.key) var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll - spend_tickets[mind_ckey] = can_spend var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free if(amount <= 0) //if they don't have any continue //too bad! @@ -338,7 +336,7 @@ var/ckey if(length(curr_tickets)) ckey = pickweight(curr_tickets) - SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what they spent + SSpersistence.antag_rep_change[ckey] = -(curr_tickets[ckey] - free_tickets) //deduct what they spent var/mind = ckey_to_mind[ckey] //we want their mind if(!mind) var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" @@ -349,11 +347,13 @@ return mind else //the far more efficient and proper use of this, to get a list var/list/rolled = list() + var/list/spend_tickets = list() for(var/i in 1 to return_list) if(!length(curr_tickets)) //ah heck, we're out of candidates.. break var/ckey = pickweight(curr_tickets) //pick rolled += ckey //add + spend_tickets[ckey] = curr_tickets[ckey] - free_tickets curr_tickets -= ckey //don't roll them again if(!length(rolled)) var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" From a24df4c2e453de6634223d815a926d0e7fe05695 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 6 Nov 2019 19:10:25 -0700 Subject: [PATCH 3/5] allow_zero_if_insufficient --- code/game/gamemodes/game_mode.dm | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 0ea37a1158..b106b5b769 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -309,7 +309,10 @@ //Use return list if you want a list, with the arg being the number you want returned. //WARNING: THIS PROC DOES NOT TAKE INTO ACCOUNT WHAT SSPersistence ALREADY HAS FOR "ADJUST ANTAG REP". If this is used more than once //and the person rolls more than once, they will not get even more deduction! -/datum/game_mode/proc/antag_pick(list/datum/mind/candidates, return_list = FALSE, fail_default_pick = TRUE) +//More efficient if you use return list instead of calling this multiple times +//fail_default_pick makes it use pick() instead of antag rep if it can't find anyone +//allow_zero_if_insufficient allows it to pick people with zero rep if there isn't enough antags +/datum/game_mode/proc/antag_pick(list/datum/mind/candidates, return_list = FALSE, fail_default_pick = TRUE, allow_zero_if_insufficient = TRUE) if(!CONFIG_GET(flag/use_antag_rep)) // || candidates.len <= 1) return pick(candidates) @@ -323,12 +326,14 @@ var/list/ckey_to_mind = list() //this is admittedly shitcode but I'm webediting var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory. how many tickets someone has stored var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets + var/list/datum/mind/insufficient = list() //who got cucked out of an antag roll due to not having *any* tickets for(var/datum/mind/M in candidates) var/mind_ckey = ckey(M.key) var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free if(amount <= 0) //if they don't have any - continue //too bad! + insufficient += M //too bad! + continue curr_tickets[mind_ckey] = amount ckey_to_mind[mind_ckey] = M //make sure we can look them up after picking @@ -339,11 +344,14 @@ SSpersistence.antag_rep_change[ckey] = -(curr_tickets[ckey] - free_tickets) //deduct what they spent var/mind = ckey_to_mind[ckey] //we want their mind if(!mind) - var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" - message_admins(warning) - log_game(warning) - if(fail_default_pick) - mind = pick(candidates) + if(allow_zero_if_insufficient) //last chance + mind = pick(insufficient) + if(!mind) //still none + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + if(fail_default_pick) + mind = pick(candidates) return mind else //the far more efficient and proper use of this, to get a list var/list/rolled = list() @@ -355,7 +363,15 @@ rolled += ckey //add spend_tickets[ckey] = curr_tickets[ckey] - free_tickets curr_tickets -= ckey //don't roll them again - if(!length(rolled)) + var/missing = return_list - length(rolled) + var/list/add + if((mising > 0) && allow_zero_if_insufficient) //need more.. + for(var/i in 1 to missing) + if(!length(insufficient)) + break //still not enough + var/datum/mind/M = pick_n_take(insufficient) + add += M + if(!length(rolled) && !length(add)) //if no one could normally roll AND no one can zero roll var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" message_admins(warning) log_game(warning) @@ -371,6 +387,8 @@ var/ckey = rolled[i] SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what all of the folks who rolled spent rolled[i] = ckey_to_mind[ckey] //whoever called us wants minds, not ckeys + if(add) + rolled += add return rolled /datum/game_mode/proc/get_players_for_role(role) From 4491708d0dde7a825ea1d6bf8256414021d17654 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 6 Nov 2019 19:19:31 -0700 Subject: [PATCH 4/5] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index b106b5b769..64a4a80e0a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -342,16 +342,13 @@ if(length(curr_tickets)) ckey = pickweight(curr_tickets) SSpersistence.antag_rep_change[ckey] = -(curr_tickets[ckey] - free_tickets) //deduct what they spent - var/mind = ckey_to_mind[ckey] //we want their mind - if(!mind) - if(allow_zero_if_insufficient) //last chance - mind = pick(insufficient) - if(!mind) //still none - var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" - message_admins(warning) - log_game(warning) - if(fail_default_pick) - mind = pick(candidates) + var/mind = ckey_to_mind[ckey] || (allow_zero_if_insufficient? pick(insufficient) : null) //we want their mind + if(!mind) //no mind + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + if(fail_default_pick) + mind = pick(candidates) return mind else //the far more efficient and proper use of this, to get a list var/list/rolled = list() From 95b9dd61a8f4fdabe1276091559f210a5e3e2c92 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Tue, 19 Nov 2019 13:01:06 -0700 Subject: [PATCH 5/5] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 64a4a80e0a..82ac3198ea 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -362,7 +362,7 @@ curr_tickets -= ckey //don't roll them again var/missing = return_list - length(rolled) var/list/add - if((mising > 0) && allow_zero_if_insufficient) //need more.. + if((missing > 0) && allow_zero_if_insufficient) //need more.. for(var/i in 1 to missing) if(!length(insufficient)) break //still not enough