57 lines
3.4 KiB
Markdown
57 lines
3.4 KiB
Markdown
# DYNAMIC
|
|
|
|
Tries to keep the round at a certain level of action, based on the round's "threat level".
|
|
|
|
## ROUNDSTART
|
|
|
|
Dynamic rolls threat based on a special sauce formula:
|
|
"dynamic_curve_width \* tan((rand() - 0.5) \* 180) + dynamic_curve_centre"
|
|
|
|
Midround injection cooldowns are set using exponential distribution between 15 minutes and 35 minutes. This value is then added to world.time and assigned to the injection cooldown variables.
|
|
|
|
Latejoins are aggressively assigned whenever possible, to keep the round at a certain threat level.
|
|
|
|
rigged_roundstart() is called instead if there are forced rules (an admin set the mode)
|
|
|
|
can_start() -> pre_setup() -> roundstart() OR rigged_roundstart() -> picking_roundstart_rule(drafted_rules) -> post_setup()
|
|
|
|
## PROCESS
|
|
|
|
Calls rule_process on every rule which is in the current_rules list.
|
|
Every sixty seconds, update_playercounts()
|
|
Midround injection time is checked against world.time to see if an injection should happen.
|
|
If midround injection time is lower than world.time, it updates playercounts again, then tries to inject and generates a new cooldown regardless of whether a rule is picked.
|
|
|
|
## LATEJOIN
|
|
|
|
make_antag_chance(newPlayer) -> [For each latespawn rule...]
|
|
-> acceptable(living players, threat_level) -> trim_candidates() -> ready(forced=FALSE)
|
|
**If true, add to drafted rules
|
|
**NOTE the new_player.dm AttemptLateSpawn() calls OnPostSetup for all roles (unless assigned role is MODE)
|
|
[After collecting all draftble rules...]
|
|
-> picking_latejoin_ruleset(drafted_rules) -> spend threat -> ruleset.execute()
|
|
## MIDROUND
|
|
process() -> [For each midround rule...]
|
|
-> acceptable(living players, threat_level) -> trim_candidates() -> ready(forced=FALSE)
|
|
[After collecting all draftble rules...]
|
|
-> picking_midround_ruleset(drafted_rules) -> spend threat -> ruleset.execute()
|
|
## FORCED
|
|
For latejoin, it simply sets forced_latejoin_rule
|
|
make_antag_chance(newPlayer) -> trim_candidates() -> ready(forced=TRUE) **NOTE no acceptable() call
|
|
For midround, calls the below proc with forced = TRUE
|
|
picking_specific_rule(ruletype,forced) -> forced OR acceptable(living_players, threat_level) -> trim_candidates() -> ready(forced) -> spend threat -> execute()
|
|
**NOTE specific rule can be called by RS traitor->MR autotraitor w/ forced=FALSE
|
|
**NOTE that due to short circuiting acceptable() need not be called if forced.
|
|
## RULESET
|
|
acceptable(population,threat) just checks if enough threat_level for population indice.
|
|
**NOTE that we currently only send threat_level as the second arg, not threat.
|
|
ready(forced) checks if enough candidates and calls the map's map_ruleset(dynamic_ruleset) at the parent level
|
|
trim_candidates() varies significantly according to the ruleset type
|
|
Roundstart: All candidates are new_player mobs. Check them for standard stuff: connected, desire role, not banned, etc.
|
|
**NOTE Roundstart deals with both candidates (trimmed list of valid players) and mode.candidates (everyone readied up). Don't confuse them!
|
|
Latejoin: Only one candidate, the latejoiner. Standard checks.
|
|
Midround: Instead of building a single list candidates, candidates contains four lists: living, dead, observing, and living antags. Standard checks in trim_list(list).
|
|
Midround - Rulesets have additional types
|
|
/from_ghosts: execute() -> send_applications() -> review_applications() -> finish_setup(mob/newcharacter, index) -> setup_role(role)
|
|
**NOTE: execute() here adds dead players and observers to candidates list
|