More dynamic fixes, AKA if Ghommie keeps merging without telling me I will maybe get irate (#11688)
* Starting a replacement of how threat works. * no, we do it this way * Added threat levels to jobs * Added threat to... a lot. * Updated for traitor classes. * Fixed errors, except for one. It's consistently giving me "maximum number of internal arrays exceeded (65535)". I have no idea what could be causing this. * Added type annotation to GetJob. * This one I should change though * wow how'd that happen * spammable means low threat * Made story threat have initial threat level on average * Made somet rulesets force if they won the vote * ) * Gave EVERY job threat, added a config for it. * Rebalanced some numbers * Update code/game/gamemodes/dynamic/dynamic_storytellers.dm Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com> * Removes mush threat * Makes devil threat scale with form * reviewing reviewer's review of reviewer * Gutlunches can be friendly spawned, so no * Also made forced-friendly mobs not count * null checks better * Made antag threats in config, too * various fixes * Another couple dynamic fixes * Made an admin message chunk all one line. * Make roundstarts ignore current threat It's not even calculated yet, so this is probably better. * Minimum pop for chaotic/teamwork. * More conveyance issues, removed superfluous threat costs * More conveyance and tweaks * Makes storyteller min players use all players instead of ready * Lowered chaos weight with chaotic * Blob now has correct cost Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -368,12 +368,16 @@
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
|
||||
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
|
||||
if(probability <= 0)
|
||||
continue
|
||||
if(length(GLOB.player_list) < min_players)
|
||||
continue
|
||||
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
|
||||
@@ -92,3 +92,7 @@
|
||||
/datum/config_entry/keyed_list/storyteller_weight
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
/datum/config_entry/keyed_list/storyteller_min_players
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
@@ -127,6 +127,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
var/only_ruleset_executed = FALSE
|
||||
/// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop.
|
||||
var/antags_rolled = 0
|
||||
// Arbitrary threat addition, for fudging purposes.
|
||||
var/added_threat = 50
|
||||
|
||||
/datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this.
|
||||
..()
|
||||
@@ -172,9 +174,9 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
else
|
||||
dat += "none.<br>"
|
||||
dat += "<br>Injection Timers: (<b>[storyteller.get_injection_chance(TRUE)]%</b> chance)<BR>"
|
||||
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
|
||||
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
|
||||
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
|
||||
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
|
||||
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
|
||||
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
|
||||
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
|
||||
|
||||
/datum/game_mode/dynamic/Topic(href, href_list)
|
||||
@@ -511,7 +513,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
starting_rule.trim_candidates()
|
||||
starting_rule.scale_up(extra_rulesets_amount, threat)
|
||||
if (starting_rule.pre_execute())
|
||||
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> -[starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
|
||||
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> [starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
|
||||
if(starting_rule.flags & HIGHLANDER_RULESET)
|
||||
highlander_executed = TRUE
|
||||
else if(starting_rule.flags & ONLY_RULESET)
|
||||
@@ -605,7 +607,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat)))
|
||||
new_rule.trim_candidates()
|
||||
if (new_rule.ready(forced))
|
||||
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> -[new_rule.cost] threat", verbose = TRUE)
|
||||
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> [new_rule.cost] threat", verbose = TRUE)
|
||||
if (new_rule.execute()) // This should never fail since ready() returned 1
|
||||
if(new_rule.flags & HIGHLANDER_RULESET)
|
||||
highlander_executed = TRUE
|
||||
@@ -625,7 +627,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
var/datum/dynamic_ruleset/rule = sent_rule
|
||||
if (rule.execute())
|
||||
log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].")
|
||||
log_threat("[rule.ruletype] [rule.name] spent [rule.cost]", verbose = TRUE)
|
||||
log_threat("[rule.ruletype] [rule.name] added [rule.cost]", verbose = TRUE)
|
||||
if(rule.flags & HIGHLANDER_RULESET)
|
||||
highlander_executed = TRUE
|
||||
else if(rule.flags & ONLY_RULESET)
|
||||
@@ -712,8 +714,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
current_players[CURRENT_OBSERVERS].Add(M)
|
||||
continue
|
||||
current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
|
||||
threat = storyteller.calculate_threat() + 50 // 50 is the centerpoint, so we want it to be around 50
|
||||
|
||||
threat = storyteller.calculate_threat() + added_threat
|
||||
/// Removes type from the list
|
||||
/datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type)
|
||||
for(var/I in type_list)
|
||||
@@ -766,20 +767,20 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
/// Increase the threat level.
|
||||
/datum/game_mode/dynamic/proc/create_threat(gain)
|
||||
threat_level += gain
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat")
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat level")
|
||||
log_threat("[gain] created. Threat level is now [threat_level].", verbose = TRUE)
|
||||
|
||||
/// Decrease the threat level.
|
||||
/datum/game_mode/dynamic/proc/remove_threat(loss)
|
||||
threat_level -= loss
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat")
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat level")
|
||||
log_threat("[loss] removed. Threat level is now [threat_level].", verbose = TRUE)
|
||||
|
||||
/// Fill up more of the threat level.
|
||||
/datum/game_mode/dynamic/proc/spend_threat(cost)
|
||||
threat += cost
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat spent")
|
||||
log_threat("[cost] spent. Threat is now [threat].", verbose = TRUE)
|
||||
added_threat += cost
|
||||
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat added")
|
||||
log_threat("[cost] added. Threat is now [threat].", verbose = TRUE)
|
||||
|
||||
/// Turns the value generated by lorentz distribution to threat value between 0 and 100.
|
||||
/datum/game_mode/dynamic/proc/lorentz_to_threat(x)
|
||||
|
||||
@@ -415,7 +415,7 @@
|
||||
required_candidates = 1
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/clockcult)
|
||||
weight = 4
|
||||
cost = 10
|
||||
cost = 20
|
||||
requirements = list(101,101,101,80,60,50,50,50,50,50)
|
||||
high_population_requirement = 50
|
||||
repeatable = TRUE
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/weight = 3 // Weights for randomly picking storyteller. Multiplied by score after voting.
|
||||
var/event_frequency_lower = 6 MINUTES // How rare events will be, at least.
|
||||
var/event_frequency_upper = 20 MINUTES // How rare events will be, at most.
|
||||
var/min_players = -1 // How many players are required for this one to start.
|
||||
var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic.
|
||||
|
||||
/**
|
||||
@@ -114,7 +115,7 @@ Property weights are:
|
||||
/datum/dynamic_storyteller/proc/roundstart_draft()
|
||||
var/list/drafted_rules = list()
|
||||
for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules)
|
||||
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level) && mode.threat >= rule.cost) // If we got the population and threat required
|
||||
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level)) // If we got the population and threat required
|
||||
rule.candidates = mode.candidates.Copy()
|
||||
rule.trim_candidates()
|
||||
if (rule.ready() && rule.candidates.len > 0)
|
||||
@@ -195,11 +196,12 @@ Property weights are:
|
||||
config_tag = "chaotic"
|
||||
curve_centre = 10
|
||||
desc = "High chaos modes. Revs, wizard, clock cult. Multiple antags at once. Chaos is kept up all round."
|
||||
property_weights = list("extended" = -1, "chaos" = 2)
|
||||
property_weights = list("extended" = -1, "chaos" = 1)
|
||||
weight = 1
|
||||
event_frequency_lower = 2 MINUTES
|
||||
event_frequency_upper = 10 MINUTES
|
||||
flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON
|
||||
min_players = 40
|
||||
var/refund_cooldown = 0
|
||||
|
||||
/datum/dynamic_storyteller/chaotic/do_process()
|
||||
@@ -221,6 +223,7 @@ Property weights are:
|
||||
curve_centre = 2
|
||||
curve_width = 1.5
|
||||
weight = 2
|
||||
min_players = 30
|
||||
flags = WAROPS_ALWAYS_ALLOWED
|
||||
property_weights = list("valid" = 3, "trust" = 5)
|
||||
|
||||
|
||||
@@ -74,12 +74,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
|
||||
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
|
||||
|
||||
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
|
||||
if(istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
var/datum/game_mode/dynamic/mode = SSticker.mode
|
||||
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
|
||||
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
|
||||
mode.spend_threat(threat_spent)
|
||||
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
|
||||
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
if(is_dynamic)
|
||||
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
|
||||
mode.spend_threat(threat_spent)
|
||||
mode.log_threat("[T.owner.name] spent [threat_spent] on an assassination target.")
|
||||
mode.log_threat("[T.owner.name] added [threat_spent] on an assassination target.")
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
|
||||
Reference in New Issue
Block a user