Skip to content

Commit

Permalink
Remove /datum/game_mode, we SSdynamic now [again] (tgstation#79965)
Browse files Browse the repository at this point in the history
I don't remember what was hard about this last time it took me like 20
minutes this time so I'm scared.

Removes dynamic simulations, only I have used them and it's a lot more
complicated now with this. I plan on making Dynamic simulations a part
of moth.fans anyway
  • Loading branch information
Mothblocks authored and Higgin committed Dec 12, 2023
1 parent f631638 commit e6485bd
Show file tree
Hide file tree
Showing 31 changed files with 340 additions and 541 deletions.
2 changes: 1 addition & 1 deletion code/__HELPERS/logging/dynamic.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Log to dynamic and message admins
/datum/game_mode/dynamic/proc/log_dynamic_and_announce(text)
/datum/controller/subsystem/dynamic/proc/log_dynamic_and_announce(text)
message_admins("DYNAMIC: [text]")
log_dynamic("[text]")

Expand Down
24 changes: 12 additions & 12 deletions code/__HELPERS/roundend.dm
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
CHECK_TICK

//Set news report and mode result
mode.set_round_result()
SSdynamic.set_round_result()

to_chat(world, span_infoplain(span_big(span_bold("<BR><BR><BR>The round has ended."))))
log_game("The round has ended.")
Expand Down Expand Up @@ -353,17 +353,17 @@ GLOBAL_LIST_INIT(achievements_unlocked, list())
//ignore this comment, it fixes the broken sytax parsing caused by the " above
else
parts += "[FOURSPACES]<i>Nobody died this shift!</i>"
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
parts += "[FOURSPACES]Threat level: [mode.threat_level]"
parts += "[FOURSPACES]Threat left: [mode.mid_round_budget]"
if(mode.roundend_threat_log.len)
parts += "[FOURSPACES]Threat edits:"
for(var/entry as anything in mode.roundend_threat_log)
parts += "[FOURSPACES][FOURSPACES][entry]<BR>"
parts += "[FOURSPACES]Executed rules:"
for(var/datum/dynamic_ruleset/rule in mode.executed_rules)
parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - <b>[rule.name]</b>: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat"

parts += "[FOURSPACES]Threat level: [SSdynamic.threat_level]"
parts += "[FOURSPACES]Threat left: [SSdynamic.mid_round_budget]"
if(SSdynamic.roundend_threat_log.len)
parts += "[FOURSPACES]Threat edits:"
for(var/entry as anything in SSdynamic.roundend_threat_log)
parts += "[FOURSPACES][FOURSPACES][entry]<BR>"
parts += "[FOURSPACES]Executed rules:"
for(var/datum/dynamic_ruleset/rule in SSdynamic.executed_rules)
parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - <b>[rule.name]</b>: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat"

return parts.Join("<br>")

/client/proc/roundend_report_file()
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/datum/game_mode/dynamic/proc/setup_hijacking()
/datum/controller/subsystem/dynamic/proc/setup_hijacking()
RegisterSignal(SSdcs, COMSIG_GLOB_PRE_RANDOM_EVENT, PROC_REF(on_pre_random_event))

/datum/game_mode/dynamic/proc/on_pre_random_event(datum/source, datum/round_event_control/round_event_control)
/datum/controller/subsystem/dynamic/proc/on_pre_random_event(datum/source, datum/round_event_control/round_event_control)
SIGNAL_HANDLER
if (!round_event_control.dynamic_should_hijack)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
return serialization

/// Updates the log for the current snapshots.
/datum/game_mode/dynamic/proc/update_log()
/datum/controller/subsystem/dynamic/proc/update_log()
var/list/serialized = list()
serialized["threat_level"] = threat_level
serialized["round_start_budget"] = initial_round_start_budget
Expand All @@ -84,7 +84,7 @@
rustg_file_write(json_encode(serialized), "[GLOB.log_directory]/dynamic.json")

/// Creates a new snapshot with the given rulesets chosen, and writes to the JSON output.
/datum/game_mode/dynamic/proc/new_snapshot(datum/dynamic_ruleset/ruleset_chosen)
/datum/controller/subsystem/dynamic/proc/new_snapshot(datum/dynamic_ruleset/ruleset_chosen)
var/datum/dynamic_snapshot/new_snapshot = new

new_snapshot.remaining_threat = mid_round_budget
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// Returns the world.time of the next midround injection.
/// Will return a cached result from `next_midround_injection`, the variable.
/// If that variable is null, will generate a new one.
/datum/game_mode/dynamic/proc/next_midround_injection()
/datum/controller/subsystem/dynamic/proc/next_midround_injection()
if (!isnull(next_midround_injection))
return next_midround_injection

Expand All @@ -16,7 +16,7 @@

return last_midround_injection_attempt + distance

/datum/game_mode/dynamic/proc/try_midround_roll()
/datum/controller/subsystem/dynamic/proc/try_midround_roll()
if (!forced_injection && next_midround_injection() > world.time)
return

Expand Down Expand Up @@ -90,7 +90,7 @@
log_dynamic_and_announce("No midround rulesets could be drafted. ([heavy_light_log_count])")

/// Gets the chance for a heavy ruleset midround injection, the dry_run argument is only used for forced injection.
/datum/game_mode/dynamic/proc/get_heavy_midround_injection_chance(dry_run)
/datum/controller/subsystem/dynamic/proc/get_heavy_midround_injection_chance(dry_run)
var/chance_modifier = 1
var/next_midround_roll = next_midround_injection() - SSticker.round_start_time

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
var/ruletype = ""
/// If set to TRUE, the rule won't be discarded after being executed, and dynamic will call rule_process() every time it ticks.
var/persistent = FALSE
/// If set to TRUE, dynamic mode will be able to draft this ruleset again later on. (doesn't apply for roundstart rules)
/// If set to TRUE, dynamic will be able to draft this ruleset again later on. (doesn't apply for roundstart rules)
var/repeatable = FALSE
/// If set higher than 0 decreases weight by itself causing the ruleset to appear less often the more it is repeated.
var/repeatable_weight_decrease = 2
Expand Down Expand Up @@ -41,7 +41,7 @@
var/required_candidates = 0
/// 0 -> 9, probability for this rule to be picked against other rules. If zero this will effectively disable the rule.
var/weight = 5
/// Threat cost for this rule, this is decreased from the mode's threat when the rule is executed.
/// Threat cost for this rule, this is decreased from the threat level when the rule is executed.
var/cost = 0
/// Cost per level the rule scales up.
var/scaling_cost = 0
Expand All @@ -51,13 +51,11 @@
var/total_cost = 0
/// A flag that determines how the ruleset is handled. Check __DEFINES/dynamic.dm for an explanation of the accepted values.
var/flags = NONE
/// Pop range per requirement. If zero defaults to mode's pop_per_requirement.
/// Pop range per requirement. If zero defaults to dynamic's pop_per_requirement.
var/pop_per_requirement = 0
/// Requirements are the threat level requirements per pop range.
/// With the default values, The rule will never get drafted below 10 threat level (aka: "peaceful extended"), and it requires a higher threat level at lower pops.
var/list/requirements = list(40,30,20,10,10,10,10,10,10,10)
/// Reference to the mode, use this instead of SSticker.mode.
var/datum/game_mode/dynamic/mode = null
/// If a role is to be considered another for the purpose of banning.
var/antag_flag_override = null
/// If set, will check this preference instead of antag_flag.
Expand Down Expand Up @@ -92,8 +90,6 @@
// side effects here. Dynamic rulesets should be stateless anyway.
SHOULD_NOT_OVERRIDE(TRUE)

mode = SSticker.mode

..()

/datum/dynamic_ruleset/roundstart // One or more of those drafted at roundstart
Expand Down Expand Up @@ -135,7 +131,7 @@

/// Sets the current threat indices and returns true if we're inside of them
/datum/dynamic_ruleset/proc/is_valid_threat(population, threat_level)
pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement
pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : SSdynamic.pop_per_requirement
indice_pop = min(requirements.len,round(population/pop_per_requirement)+1)
return threat_level >= requirements[indice_pop]

Expand All @@ -148,14 +144,14 @@
return 0

var/antag_fraction = 0
for(var/_ruleset in (mode.executed_rules + list(src))) // we care about the antags we *will* assign, too
for(var/_ruleset in (SSdynamic.executed_rules + list(src))) // we care about the antags we *will* assign, too
var/datum/dynamic_ruleset/ruleset = _ruleset
antag_fraction += ((1 + ruleset.scaled_times) * ruleset.get_antag_cap(population)) / mode.roundstart_pop_ready
antag_fraction += ((1 + ruleset.scaled_times) * ruleset.get_antag_cap(population)) / SSdynamic.roundstart_pop_ready

for(var/i in 1 to max_scale)
if(antag_fraction < 0.25)
scaled_times += 1
antag_fraction += get_antag_cap(population) / mode.roundstart_pop_ready // we added new antags, gotta update the %
antag_fraction += get_antag_cap(population) / SSdynamic.roundstart_pop_ready // we added new antags, gotta update the %

return scaled_times * scaling_cost

Expand All @@ -170,7 +166,7 @@
/datum/dynamic_ruleset/proc/rule_process()
return

/// Called on game mode pre_setup for roundstart rulesets.
/// Called on pre_setup for roundstart rulesets.
/// Do everything you need to do before job is assigned here.
/// IMPORTANT: ASSIGN special_role HERE
/datum/dynamic_ruleset/proc/pre_execute()
Expand Down Expand Up @@ -206,15 +202,15 @@
/// Runs from gamemode process() if ruleset fails to start, like delayed rulesets not getting valid candidates.
/// This one only handles refunding the threat, override in ruleset to clean up the rest.
/datum/dynamic_ruleset/proc/clean_up()
mode.refund_threat(cost + (scaled_times * scaling_cost))
mode.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]. Failed to execute."
SSdynamic.refund_threat(cost + (scaled_times * scaling_cost))
SSdynamic.threat_log += "[worldtime2text()]: [ruletype] [name] refunded [cost + (scaled_times * scaling_cost)]. Failed to execute."

/// Gets weight of the ruleset
/// Note that this decreases weight if repeatable is TRUE and repeatable_weight_decrease is higher than 0
/// Note: If you don't want repeatable rulesets to decrease their weight use the weight variable directly
/datum/dynamic_ruleset/proc/get_weight()
if(repeatable && weight > 1 && repeatable_weight_decrease > 0)
for(var/datum/dynamic_ruleset/DR in mode.executed_rules)
for(var/datum/dynamic_ruleset/DR in SSdynamic.executed_rules)
if(istype(DR, type))
weight = max(weight-repeatable_weight_decrease,1)
return weight
Expand All @@ -233,7 +229,7 @@
/datum/dynamic_ruleset/proc/trim_candidates()
return

/// Set mode result and news report here.
/// Set mode_result and news report here.
/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET
/datum/dynamic_ruleset/proc/round_result()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
if (M.mind && (M.mind.assigned_role.title in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role.title in restricted_roles)))
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it

var/threat = round(mode.threat_level/10)
var/threat = round(SSdynamic.threat_level/10)
var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED
if (!ruleset_forced && job_check < required_enemies[threat])
log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
if (M.mind && (M.mind.assigned_role.title in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role.title in restricted_roles)))
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it

var/threat = round(mode.threat_level/10)
var/threat = round(SSdynamic.threat_level/10)
var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED
if (!ruleset_forced && job_check < required_enemies[threat])
log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found")
Expand All @@ -132,23 +132,23 @@
message_admins("Possible volunteers was 0. This shouldn't appear, because of ready(), unless you forced it!")
return

mode.log_dynamic_and_announce("Polling [possible_volunteers.len] players to apply for the [name] ruleset.")
candidates = poll_ghost_candidates("The mode is looking for volunteers to become [antag_flag] for [name]", antag_flag_override, antag_flag || antag_flag_override, poll_time = 300)
SSdynamic.log_dynamic_and_announce("Polling [possible_volunteers.len] players to apply for the [name] ruleset.")
candidates = poll_ghost_candidates("Looking for volunteers to become [antag_flag] for [name]", antag_flag_override, antag_flag || antag_flag_override, poll_time = 300)

if(!candidates || candidates.len <= 0)
mode.log_dynamic_and_announce("The ruleset [name] received no applications.")
mode.executed_rules -= src
SSdynamic.log_dynamic_and_announce("The ruleset [name] received no applications.")
SSdynamic.executed_rules -= src
attempt_replacement()
return

mode.log_dynamic_and_announce("[candidates.len] players volunteered for [name].")
SSdynamic.log_dynamic_and_announce("[candidates.len] players volunteered for [name].")
review_applications()

/// Here is where you can check if your ghost applicants are valid for the ruleset.
/// Called by send_applications().
/datum/dynamic_ruleset/midround/from_ghosts/proc/review_applications()
if(candidates.len < required_applicants)
mode.executed_rules -= src
SSdynamic.executed_rules -= src
return
for (var/i = 1, i <= required_candidates, i++)
if(candidates.len <= 0)
Expand Down Expand Up @@ -200,12 +200,12 @@
/datum/dynamic_ruleset/midround/from_ghosts/proc/attempt_replacement()
var/datum/dynamic_ruleset/midround/from_living/autotraitor/sleeper_agent = new

mode.configure_ruleset(sleeper_agent)
SSdynamic.configure_ruleset(sleeper_agent)

if (!mode.picking_specific_rule(sleeper_agent))
if (!SSdynamic.picking_specific_rule(sleeper_agent))
return

mode.picking_specific_rule(/datum/dynamic_ruleset/latejoin/infiltrator)
SSdynamic.picking_specific_rule(/datum/dynamic_ruleset/latejoin/infiltrator)

///subtype to handle checking players
/datum/dynamic_ruleset/midround/from_living
Expand Down Expand Up @@ -378,7 +378,7 @@
var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5)

/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat_level=0)
if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules)
if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in SSdynamic.executed_rules)
return FALSE // Unavailable if nuke ops were already sent at roundstart
indice_pop = min(operative_cap.len, round(living_players.len/5)+1)
required_candidates = operative_cap[indice_pop]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,9 +604,9 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
. = ..()
message_admins("Starting a round of extended.")
log_game("Starting a round of extended.")
mode.spend_roundstart_budget(mode.round_start_budget)
mode.spend_midround_budget(mode.mid_round_budget)
mode.threat_log += "[worldtime2text()]: Extended ruleset set threat to 0."
SSdynamic.spend_roundstart_budget(SSdynamic.round_start_budget)
SSdynamic.spend_midround_budget(SSdynamic.mid_round_budget)
SSdynamic.threat_log += "[worldtime2text()]: Extended ruleset set threat to 0."
return TRUE

//////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
/// This is used for impactful events like traitors hacking and creating more threat, or a revolutions victory.
/// It tries to spawn a heavy midround if possible, otherwise it will trigger a "bad" random event after a short period.
/// Calling this function will not use up any threat.
/datum/game_mode/dynamic/proc/unfavorable_situation()
/datum/controller/subsystem/dynamic/proc/unfavorable_situation()
SHOULD_NOT_SLEEP(TRUE)

INVOKE_ASYNC(src, PROC_REF(_unfavorable_situation))

/datum/game_mode/dynamic/proc/_unfavorable_situation()
/datum/controller/subsystem/dynamic/proc/_unfavorable_situation()
var/static/list/unfavorable_random_events = list()
if (!length(unfavorable_random_events))
unfavorable_random_events = generate_unfavourable_events()
Expand All @@ -24,7 +24,7 @@
picking_specific_rule(heavy_ruleset, forced = TRUE, ignore_cost = TRUE)

/// Return a valid heavy dynamic ruleset, or an empty list if there's no time to run any rulesets
/datum/game_mode/dynamic/proc/generate_unfavourable_heavy_rulesets()
/datum/controller/subsystem/dynamic/proc/generate_unfavourable_heavy_rulesets()
if (EMERGENCY_PAST_POINT_OF_NO_RETURN)
return list()

Expand Down Expand Up @@ -58,7 +58,7 @@
return possible_heavies

/// Filter the below list by which events can actually run on this map
/datum/game_mode/dynamic/proc/generate_unfavourable_events()
/datum/controller/subsystem/dynamic/proc/generate_unfavourable_events()
var/static/list/unfavorable_random_events = list(
/datum/round_event_control/earthquake,
/datum/round_event_control/immovable_rod,
Expand Down
Loading

0 comments on commit e6485bd

Please sign in to comment.