[s] Fixes an issue with dynamic late spawning (#28047)

* [s] Fixes an issue with dynamic spawning

* shit quick fix
This commit is contained in:
Contrabang
2025-01-21 01:05:12 +00:00
committed by GitHub
parent 08d4ab79a0
commit 8b817aa075
3 changed files with 61 additions and 16 deletions
+50 -8
View File
@@ -49,6 +49,8 @@
var/antag_amount = 0
/// All of the minds that we will make into our antagonist type
var/list/datum/mind/pre_antags = list()
/// If non-zero, how long from the start of the game should a latespawn for this role occur?
var/latespawn_time
/datum/ruleset/Destroy(force, ...)
stack_trace("[src] ([type]) was destroyed.")
@@ -63,7 +65,7 @@
/datum/ruleset/proc/antagonist_possible(budget)
return budget >= antag_cost
/datum/ruleset/proc/pre_setup()
/datum/ruleset/proc/roundstart_pre_setup()
if(antag_amount == 0)
return
if(antag_amount < 0)
@@ -81,7 +83,7 @@
for(var/datum/mind/antag as anything in possible_antags)
if(antag_amount <= 0)
break
if(!can_apply(antag))
if(!roundstart_can_apply(antag))
continue
pre_antags += antag
if(assign_job_role)
@@ -94,7 +96,7 @@
refund("Missing [antag_amount] antagonists for [src] ruleset.")
return antag_cost * antag_amount // shitty refund for now
/datum/ruleset/proc/can_apply(datum/mind/antag)
/datum/ruleset/proc/roundstart_can_apply(datum/mind/antag)
if(EXCLUSIVE_OR(antag.current.client.prefs.active_character.species in banned_species, banned_species_only))
SEND_SIGNAL(src, COMSIG_RULESET_FAILED_SPECIES)
return FALSE
@@ -102,7 +104,7 @@
return FALSE
return TRUE
/datum/ruleset/proc/post_setup(datum/game_mode/dynamic)
/datum/ruleset/proc/roundstart_post_setup(datum/game_mode/dynamic)
for(var/datum/mind/antag as anything in pre_antags)
antag.add_antag_datum(antagonist_type)
@@ -113,6 +115,47 @@
// Currently unimplemented. Will be useful for a possible future PR where latejoin antagonists are factored in.
return
/datum/ruleset/proc/get_latejoin_players()
var/list/candidates = list()
// Assemble a list of active players without jobbans.
for(var/mob/living/carbon/human/player in GLOB.player_list)
// Has a mind
if(!player.mind)
continue
// Connected and not AFK
if(!player.client || (locate(player) in SSafk.afk_players))
continue
// Not antag-banned and not specific antag banned
if(jobban_isbanned(player, ROLE_SYNDICATE) || jobban_isbanned(player, antagonist_type::job_rank))
continue
// Make sure they want to play antag, and that they're not already something (off station or antag)
if(player.client.skip_antag || player.mind.offstation_role || player.mind.special_role)
continue
// Make sure they actually want to be this antagonist
if(!(antagonist_type::job_rank in player.client.prefs.be_special))
continue
// Make sure their species CAN be this antagonist
if(EXCLUSIVE_OR(player.dna.species.name in banned_species, banned_species_only))
continue
// Make sure they're not in a banned job
if(player.mind.assigned_role in banned_jobs)
continue
candidates += player.mind
return shuffle(candidates)
/datum/ruleset/proc/latespawn(datum/game_mode/dynamic/dynamic)
// latespawning is only used by traitors at this point, so we're just going to be naive and allocate all budget when this proc is called.
var/late_antag_amount = floor(dynamic.budget_overflow / antag_cost)
dynamic.budget_overflow -= (late_antag_amount * antag_cost)
var/list/datum/mind/possible_antags = get_latejoin_players()
for(var/i in 1 to late_antag_amount)
var/datum/mind/antag = pick_n_take(possible_antags)
antag.add_antag_datum(antagonist_type)
/datum/ruleset/traitor
name = "Traitor"
ruleset_weight = 11
@@ -120,15 +163,14 @@
antag_weight = 2
antagonist_type = /datum/antagonist/traitor
/datum/ruleset/traitor/post_setup(datum/game_mode/dynamic)
var/random_time = rand(5 MINUTES, 15 MINUTES)
/datum/ruleset/traitor/roundstart_post_setup(datum/game_mode/dynamic)
latespawn_time = rand(5 MINUTES, 15 MINUTES)
for(var/datum/mind/antag as anything in pre_antags)
var/datum/antagonist/traitor/traitor_datum = new antagonist_type()
if(ishuman(antag.current))
traitor_datum.delayed_objectives = TRUE
traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), random_time, TIMER_DELETE_ME)
traitor_datum.addtimer(CALLBACK(traitor_datum, TYPE_PROC_REF(/datum/antagonist/traitor, reveal_delayed_objectives)), latespawn_time, TIMER_DELETE_ME)
antag.add_antag_datum(traitor_datum)
addtimer(CALLBACK(dynamic, TYPE_PROC_REF(/datum/game_mode, fill_antag_slots)), random_time)
/datum/ruleset/vampire
name = "Vampire"
+4 -7
View File
@@ -3,7 +3,6 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
/datum/game_mode/dynamic
name = "Dynamic"
config_tag = "dynamic"
secondary_restricted_jobs = list("AI")
required_players = 10
/// Non-implied rulesets in play
var/list/datum/ruleset/rulesets = list()
@@ -126,7 +125,7 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
for(var/datum/ruleset/ruleset in (rulesets + implied_rulesets)) // rulesets first, then implied rulesets
// log_dynamic("Applying [ruleset.antag_amount] [ruleset.name]\s.")
budget_overflow += ruleset.pre_setup()
budget_overflow += ruleset.roundstart_pre_setup()
// log_dynamic("Budget overflow: [budget_overflow].")
// for the future, maybe try readding antagonists with apply_antag_budget(budget_overflow)
@@ -137,13 +136,11 @@ GLOBAL_LIST_EMPTY(dynamic_forced_rulesets)
for(var/datum/ruleset/ruleset in (rulesets + implied_rulesets))
// if(length(ruleset.pre_antags))
// log_dynamic("Making antag datums for [ruleset.name] ruleset.")
ruleset.post_setup(src)
ruleset.roundstart_post_setup(src)
if(ruleset.latespawn_time)
addtimer(CALLBACK(ruleset, TYPE_PROC_REF(/datum/ruleset, latespawn), src), ruleset.latespawn_time)
..()
/datum/game_mode/dynamic/traitors_to_add()
. = floor(budget_overflow / /datum/ruleset/traitor::antag_cost)
budget_overflow -= (. * /datum/ruleset/traitor::antag_cost)
/datum/game_mode/dynamic/latespawn(mob)
. = ..()
budget_overflow++
+7 -1
View File
@@ -319,7 +319,10 @@
// Less if there are not enough valid players in the game entirely to make recommended_enemies.
// Just the above proc but for alive players
/// Gets all alive players for a specific role. Disables offstation roles by default
/**
* DEPRECATED!
* Gets all alive players for a specific role. Disables offstation roles by default
*/
/datum/game_mode/proc/get_alive_players_for_role(role, override_jobbans = FALSE, allow_offstation_roles = FALSE)
var/list/players = list()
var/list/candidates = list()
@@ -645,6 +648,9 @@
/datum/game_mode/proc/traitors_to_add()
return 0
/**
* DEPRECATED!
*/
/datum/game_mode/proc/fill_antag_slots()
var/traitors_to_add = 0