This commit is contained in:
Putnam
2019-12-21 08:31:44 -08:00
186 changed files with 2192 additions and 1395 deletions
+22 -1
View File
@@ -303,6 +303,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
/datum/game_mode/dynamic/proc/log_threat(var/log_str,var/verbose = FALSE)
threat_log_verbose += ("[worldtime2text()]: "+log_str)
SSblackbox.record_feedback("tally","dynamic_threat_log",1,log_str)
if(!verbose)
threat_log += log_str
@@ -332,6 +333,10 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
peaceful_percentage = round(LORENTZ_CUMULATIVE_DISTRIBUTION(relative_threat, GLOB.dynamic_curve_centre, GLOB.dynamic_curve_width), 0.01)*100
threat = threat_level
SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Initial threat level")
SSblackbox.record_feedback("tally","dynamic_threat",GLOB.dynamic_curve_centre,"Curve centre")
SSblackbox.record_feedback("tally","dynamic_threat",GLOB.dynamic_curve_width,"Curve width")
SSblackbox.record_feedback("tally","dynamic_threat",peaceful_percentage,"Percent of same-vote rounds that are more peaceful")
/datum/game_mode/dynamic/can_start()
message_admins("Dynamic mode parameters for the round:")
@@ -343,6 +348,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
if(GLOB.dynamic_forced_threat_level >= 0)
threat_level = round(GLOB.dynamic_forced_threat_level, 0.1)
threat = threat_level
SSblackbox.record_feedback("tally","dynamic_threat",threat_level,"Threat level (forced by admins)")
else
generate_threat()
@@ -388,7 +394,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
if (roundstart_rules.len <= 0)
log_game("DYNAMIC: [roundstart_rules.len] rules.")
return TRUE
SSblackbox.record_feedback("tally","dynamic",roundstart_rules.len,"Roundstart rules considered")
SSblackbox.record_feedback("tally","dynamic",roundstart_rules.len,"Players readied up")
if(GLOB.dynamic_forced_roundstart_ruleset.len > 0)
rigged_roundstart()
else
@@ -535,6 +542,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
if(rule.execute())
if(rule.persistent)
current_rules += rule
SSblackbox.record_feedback("associative","dynamic_rulesets",1,rule.get_blackbox_info())
return TRUE
rule.clean_up() // Refund threat, delete teams and so on.
executed_rules -= rule
@@ -613,6 +621,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
else if(new_rule.flags & ONLY_RULESET)
only_ruleset_executed = TRUE
log_game("DYNAMIC: Making a call to a specific ruleset...[new_rule.name]!")
SSblackbox.record_feedback("associative","dynamic_rulesets",1,new_rule.get_blackbox_info())
executed_rules += new_rule
if (new_rule.persistent)
current_rules += new_rule
@@ -637,6 +646,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
message_admins("[key_name(M)] joined the station, and was selected by the [rule.name] ruleset.")
log_game("DYNAMIC: [key_name(M)] joined the station, and was selected by the [rule.name] ruleset.")
executed_rules += rule
SSblackbox.record_feedback("associative","dynamic_rulesets",1,rule.get_blackbox_info())
rule.candidates.Cut()
if (rule.persistent)
current_rules += rule
@@ -653,6 +663,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
for (var/datum/dynamic_ruleset/rule in current_rules)
if(rule.rule_process() == RULESET_STOP_PROCESSING) // If rule_process() returns 1 (RULESET_STOP_PROCESSING), stop processing.
current_rules -= rule
SSblackbox.record_feedback("tally","dynamic",1,"Rulesets finished")
SSblackbox.record_feedback("associative","dynamic_rulesets_finished",1,rule.get_blackbox_info())
storyteller.do_process()
@@ -673,13 +685,16 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
update_playercounts()
if (get_injection_chance())
SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections")
var/list/drafted_rules = storyteller.midround_draft()
if (drafted_rules.len > 0)
SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
picking_midround_latejoin_rule(drafted_rules)
else
midround_injection_cooldown = (midround_injection_cooldown + world.time)/2
if(event_injection_cooldown < world.time)
SSblackbox.record_feedback("tally","dynamic",1,"Attempted event injections")
var/event_injection_cooldown_middle = 0.5*(GLOB.dynamic_event_delay_max + GLOB.dynamic_event_delay_min)
event_injection_cooldown = (round(CLAMP(EXP_DISTRIBUTION(event_injection_cooldown_middle), GLOB.dynamic_event_delay_min, GLOB.dynamic_event_delay_max)) + world.time)
message_admins("DYNAMIC: Doing event injection.")
@@ -687,6 +702,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
update_playercounts()
var/list/drafted_rules = storyteller.event_draft()
if(drafted_rules.len > 0)
SSblackbox.record_feedback("tally","dynamic",1,"Successful event injections")
picking_midround_latejoin_rule(drafted_rules)
/// Updates current_players.
@@ -777,14 +793,17 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
forced_latejoin_rule = null
else if (latejoin_injection_cooldown < world.time && prob(get_injection_chance()))
SSblackbox.record_feedback("tally","dynamic",1,"Attempted latejoin injections")
var/list/drafted_rules = storyteller.latejoin_draft(newPlayer)
if (drafted_rules.len > 0 && picking_midround_latejoin_rule(drafted_rules))
SSblackbox.record_feedback("tally","dynamic",1,"Successful latejoin injections")
var/latejoin_injection_cooldown_middle = 0.5*(GLOB.dynamic_latejoin_delay_max + GLOB.dynamic_latejoin_delay_min)
latejoin_injection_cooldown = round(CLAMP(EXP_DISTRIBUTION(latejoin_injection_cooldown_middle), GLOB.dynamic_latejoin_delay_min, GLOB.dynamic_latejoin_delay_max)) + world.time
/// Refund threat, but no more than threat_level.
/datum/game_mode/dynamic/proc/refund_threat(regain)
threat = min(threat_level,threat+regain)
SSblackbox.record_feedback("tally","dynamic_threat",regain,"Refunded threat")
log_threat("[regain] refunded. Threat is now [threat].", verbose = TRUE)
/// Generate threat and increase the threat_level if it goes beyond, capped at 100
@@ -792,11 +811,13 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, null)
threat = min(100, threat+gain)
if(threat > threat_level)
threat_level = threat
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat")
log_threat("[gain] created. Threat is now [threat] and threat level is now [threat_level].", verbose = TRUE)
/// Expend threat, can't fall under 0.
/datum/game_mode/dynamic/proc/spend_threat(cost)
threat = max(threat-cost,0)
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat spent")
log_threat("[cost] spent. Threat is now [threat].", verbose = TRUE)
/// Turns the value generated by lorentz distribution to threat value between 0 and 100.
@@ -82,6 +82,9 @@
var/delay = 0
/// List of tags for use in storytellers.
var/list/property_weights = list()
/// Whether or not recent-round weight values are taken into account for this ruleset.
/// Weight reduction uses the same values as secret's recent-round mode weight reduction.
var/always_max_weight = FALSE
/datum/dynamic_ruleset/New()
..()
@@ -93,8 +96,15 @@
var/costs = CONFIG_GET(keyed_list/dynamic_cost)
var/requirementses = CONFIG_GET(keyed_list/dynamic_requirements) // can't damn well use requirements
var/high_population_requirements = CONFIG_GET(keyed_list/dynamic_high_population_requirement)
var/list/repeated_mode_adjust = CONFIG_GET(number_list/repeated_mode_adjust)
if(config_tag in weights)
weight = weights[config_tag]
var/weight_mult = 1
if(!always_max_weight && SSpersistence.saved_dynamic_rules.len == 3 && repeated_mode_adjust.len == 3)
var/saved_dynamic_rules = SSpersistence.saved_dynamic_rules
for(var/i in 1 to 3)
if(config_tag in saved_dynamic_rules[i])
weight_mult -= (repeated_mode_adjust[i]/100)
weight = weights[config_tag] * weight_mult
if(config_tag in costs)
cost = costs[config_tag]
if(config_tag in requirementses)
@@ -117,12 +127,15 @@
/// If your rule has extra checks, such as counting security officers, do that in ready() instead
/datum/dynamic_ruleset/proc/acceptable(population = 0, threat_level = 0)
if(minimum_players > population)
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to low pop")
return FALSE
if(maximum_players > 0 && population > maximum_players)
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to high pop")
return FALSE
if (population >= GLOB.dynamic_high_pop_limit)
indice_pop = 10
if(threat_level < high_population_requirement)
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat level")
log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[high_population_requirement]")
return FALSE
else
@@ -134,6 +147,7 @@
log_game("DYNAMIC: requirements and antag_cap lists have different lengths in ruleset [name]. Likely config issue, report this.")
indice_pop = min(requirements.len,round(population/pop_per_requirement)+1)
if(threat_level < requirements[indice_pop])
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough threat level")
log_game("DYNAMIC: [name] did not reach threat level threshold: [threat_level]/[requirements[indice_pop]]")
return FALSE
else
@@ -180,6 +194,7 @@
/// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail!
/datum/dynamic_ruleset/proc/ready(forced = 0)
if (required_candidates > candidates.len)
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough candidates")
return FALSE
return TRUE
@@ -214,6 +229,24 @@
/datum/dynamic_ruleset/proc/check_finished()
return FALSE
/// Returns a list to be displayed on statbus.
/datum/dynamic_ruleset/proc/get_blackbox_info()
var/list/ruleset_data = list()
ruleset_data["name"] = name
ruleset_data["rule_type"] = ruletype
ruleset_data["cost"] = total_cost
ruleset_data["weight"] = weight
ruleset_data["scaled_times"] = scaled_times
ruleset_data["antagonist_type"] = antag_datum
ruleset_data["population_tier"] = indice_pop
ruleset_data["assigned"] = list()
for (var/datum/mind/M in assigned)
var/assigned_data = list()
assigned_data["key"] = M.key
assigned_data["name"] = M.name
ruleset_data["assigned"] += list(assigned_data)
return ruleset_data
//////////////////////////////////////////////
// //
// ROUNDSTART RULESETS //
@@ -3,6 +3,17 @@
var/typepath // typepath of the event
var/triggering
/datum/dynamic_ruleset/event/get_blackbox_info()
var/list/ruleset_data = list()
ruleset_data["name"] = name
ruleset_data["rule_type"] = ruletype
ruleset_data["cost"] = total_cost
ruleset_data["weight"] = weight
ruleset_data["scaled_times"] = scaled_times
ruleset_data["event_type"] = typepath
ruleset_data["population_tier"] = indice_pop
return ruleset_data
/datum/dynamic_ruleset/event/execute()
var/datum/round_event/E = new typepath()
E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
@@ -26,6 +37,7 @@
var/threat = round(mode.threat_level/10)
if (job_check < required_enemies[threat])
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles")
return FALSE
return TRUE
@@ -129,6 +141,7 @@
high_population_requirement = 5
repeatable = TRUE
property_weights = list("story_potential" = 5, "extended" = 1)
always_max_weight = TRUE
//////////////////////////////////////////////
// //
@@ -151,12 +164,15 @@
/datum/dynamic_ruleset/event/meteor_wave/ready()
if(mode.threat_level > 40 && mode.threat >= 25 && prob(20))
name = "Meteor Wave: Threatening"
cost = 25
typepath = /datum/round_event/meteor_wave/threatening
else if(mode.threat_level > 50 && mode.threat >= 40 && prob(30))
name = "Meteor Wave: Catastrophic"
cost = 40
typepath = /datum/round_event/meteor_wave/catastrophic
else
name = "Meteor Wave: Normal"
cost = 15
typepath = /datum/round_event/meteor_wave
return ..()
@@ -294,6 +310,7 @@
high_population_requirement = 5
repeatable = TRUE
property_weights = list("extended" = 1, "chaos" = 1)
always_max_weight = TRUE
/datum/dynamic_ruleset/event/space_dust
name = "Minor Space Dust"
@@ -308,6 +325,7 @@
high_population_requirement = 5
repeatable = TRUE
property_weights = list("extended" = 1)
always_max_weight = TRUE
/datum/dynamic_ruleset/event/major_dust
name = "Major Space Dust"
@@ -350,6 +368,7 @@
high_population_requirement = 5
repeatable = TRUE
property_weights = list("extended" = 1)
always_max_weight = TRUE
/datum/dynamic_ruleset/event/radiation_storm
name = "Radiation Storm"
@@ -36,9 +36,9 @@
continue // Dead players cannot count as opponents
if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role 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)
if (job_check < required_enemies[threat])
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles")
return FALSE
return ..()
@@ -71,6 +71,7 @@
flags = TRAITOR_RULESET
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
always_max_weight = TRUE
//////////////////////////////////////////////
// //
@@ -87,6 +87,7 @@
var/threat = round(mode.threat_level/10)
if (job_check < required_enemies[threat])
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough enemy roles")
return FALSE
return TRUE
@@ -180,6 +181,7 @@
high_population_requirement = 15
flags = TRAITOR_RULESET
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1)
always_max_weight = TRUE
/datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0)
var/player_count = mode.current_players[CURRENT_LIVING_PLAYERS].len
@@ -294,6 +296,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
if(GLOB.wizardstart.len == 0)
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
@@ -357,6 +360,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
@@ -394,6 +398,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
@@ -426,6 +431,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
@@ -527,6 +533,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE)
if (required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
return ..()
@@ -566,6 +573,7 @@
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
return FALSE
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
var/turf/T = get_turf(L)
@@ -614,6 +622,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
@@ -666,6 +675,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
team = new /datum/team/abductor_team
if(team.team_number > ABDUCTOR_MAX_TEAMS)
@@ -706,6 +716,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE)
if(required_candidates > (dead_players.len + list_observers.len))
SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
return FALSE
if(!spawn_loc)
var/list/spawn_locs = list()
@@ -22,6 +22,7 @@
high_population_requirement = 40
antag_cap = list(1,1,1,1,2,2,2,2,3,3)
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 1, "valid" = 1)
always_max_weight = TRUE
var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec)
/datum/dynamic_ruleset/roundstart/traitor/pre_execute()