Skip to content

Commit

Permalink
[MIRROR] Implements dynamic scaling for spies (#2383)
Browse files Browse the repository at this point in the history
* Implements dynamic scaling for spies (#82961)

## About The Pull Request

Implements dynamic scaling for spies. 

TL;DR On average less spawn, but there is a chance it scales up to add
even more.

Old


![image](https://github.com/tgstation/tgstation/assets/51863163/5ecdf146-7922-42ea-8051-8a30cddde7a6)

New


![image](https://github.com/tgstation/tgstation/assets/51863163/ce9f51a1-4d99-4fe7-be65-32003fbec605)

## Why It's Good For The Game

Maybe more dynamic rounds? Just for testing really

## Changelog

:cl: Melbert
qol: Spies may spawn in less numbers, but rarely may also spawn in more
numbers.
/:cl:

* Implements dynamic scaling for spies

---------

Co-authored-by: MrMelbert <[email protected]>
  • Loading branch information
2 people authored and StealsThePRs committed May 8, 2024
1 parent 009ca91 commit 0580300
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
21 changes: 17 additions & 4 deletions code/controllers/subsystem/dynamic/dynamic_rulesets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -140,28 +140,41 @@
/// This function is here to ensure the antag ratio is kept under control while scaling up.
/// Returns how much threat to actually spend in the end.
/datum/dynamic_ruleset/proc/scale_up(population, max_scale)
SHOULD_NOT_OVERRIDE(TRUE)
if (!scaling_cost)
return 0

var/antag_fraction = 0
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)) / SSdynamic.roundstart_pop_ready
for(var/datum/dynamic_ruleset/ruleset as anything in (SSdynamic.executed_rules + list(src))) // we care about the antags we *will* assign, too
antag_fraction += ruleset.get_antag_cap_scaling_included(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) / SSdynamic.roundstart_pop_ready // we added new antags, gotta update the %
antag_fraction += get_scaling_antag_cap(population) / SSdynamic.roundstart_pop_ready // we added new antags, gotta update the %

return scaled_times * scaling_cost

/// Returns how many more antags to add while scaling with a given population.
/// By default rulesets scale linearly, but you can override this to make them scale differently.
/datum/dynamic_ruleset/proc/get_scaling_antag_cap(population)
return get_antag_cap(population)

/// Returns what the antag cap with the given population is.
/datum/dynamic_ruleset/proc/get_antag_cap(population)
SHOULD_NOT_OVERRIDE(TRUE)
if (isnum(antag_cap))
return antag_cap

return CEILING(population / antag_cap["denominator"], 1) + (antag_cap["offset"] || 0)

/// Gets the 'final' antag cap for this ruleset, which is the base cap plus the scaled cap.
/datum/dynamic_ruleset/proc/get_antag_cap_scaling_included(population)
SHOULD_NOT_OVERRIDE(TRUE)
var/base_cap = get_antag_cap(population)
var/modded_cap = scaled_times * get_scaling_antag_cap(population)
return base_cap + modded_cap

/// This is called if persistent variable is true everytime SSTicker ticks.
/datum/dynamic_ruleset/proc/rule_process()
return
Expand Down
25 changes: 12 additions & 13 deletions code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)

/datum/dynamic_ruleset/roundstart/traitor/pre_execute(population)
. = ..()
var/num_traitors = get_antag_cap(population) * (scaled_times + 1)
for (var/i = 1 to num_traitors)
for (var/i in 1 to get_antag_cap_scaling_included(population))
if(candidates.len <= 0)
break
var/mob/M = pick_n_take(candidates)
Expand Down Expand Up @@ -121,7 +120,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
/datum/dynamic_ruleset/roundstart/traitorbro/pre_execute(population)
. = ..()

for (var/_ in 1 to get_antag_cap(population) * (scaled_times + 1))
for (var/i in 1 to get_antag_cap_scaling_included(population))
var/mob/candidate = pick_n_take(candidates)
if (isnull(candidate))
break
Expand Down Expand Up @@ -171,8 +170,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)

/datum/dynamic_ruleset/roundstart/changeling/pre_execute(population)
. = ..()
var/num_changelings = get_antag_cap(population) * (scaled_times + 1)
for (var/i = 1 to num_changelings)
for (var/i in 1 to get_antag_cap_scaling_included(population))
if(candidates.len <= 0)
break
var/mob/M = pick_n_take(candidates)
Expand Down Expand Up @@ -717,13 +715,15 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
required_candidates = 3 // lives or dies by there being a few spies
weight = 5
cost = 8
scaling_cost = 101 // see below
minimum_players = 8
antag_cap = list("denominator" = 8, "offset" = 1) // should have quite a few spies to work against each other
scaling_cost = 4
minimum_players = 10
antag_cap = list("denominator" = 20, "offset" = 1)
requirements = list(8, 8, 8, 8, 8, 8, 8, 8, 8, 8)
/// What fraction is added to the antag cap for each additional scale
var/fraction_per_scale = 0.2

/datum/dynamic_ruleset/roundstart/spies/pre_execute(population)
for(var/i in 1 to get_antag_cap(population) * (scaled_times + 1))
for(var/i in 1 to get_antag_cap_scaling_included(population))
if(length(candidates) <= 0)
break
var/mob/picked_player = pick_n_take(candidates)
Expand All @@ -733,7 +733,6 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
GLOB.pre_setup_antags += picked_player.mind
return TRUE

/datum/dynamic_ruleset/roundstart/spies/scale_up(population, max_scale)
// Disabled (at least until dynamic can handle scaling this better)
// Because spies have a very low demoninator, this can easily spawn like 30 of them
return 0
// Scaling adds a fraction of the amount of additional spies rather than the full amount.
/datum/dynamic_ruleset/roundstart/spies/get_scaling_antag_cap(population)
return ceil(..() * fraction_per_scale)

0 comments on commit 0580300

Please sign in to comment.