Skip to content

Commit

Permalink
Adds Latejoin scaling to Vendors and ASRS (#4939)
Browse files Browse the repository at this point in the history
# About the pull request

<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

Simply fixes a few bugs, and makes it so Latejoiners contribute to ASRS
Funds and Vendors stock of the main vendors (attachies, utilities,
uniform, and reqs') much like they do contribute to larva count. See the
CL for full details.

Balance overview:
* ASRS budget and dynamic vendors (attachies, utility, gear, ammo) now
get resupplied by latejoins at 60% of roundstart rate.
* 33% less supply points per marine. This applies to both amount of
Vendors' stock, and to ASRS budget - roundstart and latejoin.
* Basic vendors like Squad Preps Weapons Rack do not use the dynamic
scaling.
 * Marines' own ordering points are not affected by these changes.
 * ASRS random supplying is already scaled and unaffected.

I didn't really feel the strength to mass edit all ~500 scale() usage in
codebase and risk to collateral the others, so affected vendors retain
it for everything but floating point values.

Some vendor multipliers had to be edited so they can scale linearly
`(0.1 * scale + 1) ---> 0.25, i'd add a static modifier but this vendor
code is already a mess.

This is overall potentially a big marine supply buff, although it nerfs
them at roundstart due to bugfixes. Related numbers might need to be
adjusted.

# Explain why it's good for the game
Less dependency on roundstart amount of players, smoothing the game so
it's easier to balance. More gradual scaling as people join. More Reqs
work despite more supplies.

# Testing Photographs and Procedure
Tested chain spawning and that the vendors and ASRS amounts increased in
appropriate amounts.


# Changelog
:cl:
fix: Cryoing someone now properly takes into account role weights for
the purpose of latejoin larvas. This should very slightly increase
larvas amount.
fix: Roundstart distributed amount of gear and ASRS points now takes
shipside role weights into account. This should moderately decrease
budget and starting gear.
fix: Roundstart distributed amount of gear and ASRS points does not
count Survivors and Monkeys anymore. This should moderatly decrease
budget and starting gear.
add: Main marine vendors and ASRS now get matching supply for every
additional marine latejoining, similar to larvas. This should be a
substantial increase over the course of a round. Supplies given are 60%
of what a roundstart marine would give.
balance: Amount of gear in main marine vendors and ASRS supplies have
been decreased by 40% to help counteract added supplies the marines will
get in latejoining. Hopefully this also keeps reqs active to dispatch
new supplies.
fix: Altered a few items vendor stock scalings to be linear for use with
the new system, such as RTO pack, Drop Pouch and Machete Pouch.
/:cl:

---------

Co-authored-by: forest2001 <[email protected]>
  • Loading branch information
fira and realforest2001 authored Dec 7, 2023
1 parent 2f41e50 commit ba6e6aa
Show file tree
Hide file tree
Showing 13 changed files with 191 additions and 112 deletions.
4 changes: 2 additions & 2 deletions code/__DEFINES/mode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@
//=================================================


//Number of marine players against which the Marine's gear scales
#define MARINE_GEAR_SCALING_NORMAL 30
/// Number of weighted marine players for 1 gear_scale. gear_scale is clamped to 1 minimum
#define MARINE_GEAR_SCALING_NORMAL 50

#define RESOURCE_NODE_SCALE 95 //How many players minimum per extra set of resource nodes
#define RESOURCE_NODE_QUANTITY_PER_POP 11 //How many resources total per pop
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/vendors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
//Whether or not to load ammo boxes depending on ammo loaded into the vendor
//Only relevant in big vendors, like Requisitions or Squad Prep
#define VEND_LOAD_AMMO_BOXES (1<<9)
/// Vendors with this flag will fill retroactively based on latejoining players,
/// and expect a scale multiplier instead of amount of items
#define VEND_STOCK_DYNAMIC (1<<10)

// Redemption Tokens
#define VEND_TOKEN_ENGINEER "Engineer"
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/bitfields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ DEFINE_BITFIELD(vend_flags, list(
"VEND_INSTANCED_CATEGORY" = VEND_INSTANCED_CATEGORY,
"VEND_FACTION_THEMES" = VEND_FACTION_THEMES,
"VEND_USE_VENDOR_FLAGS" = VEND_USE_VENDOR_FLAGS,
"VEND_LOAD_AMMO_BOXES" = VEND_LOAD_AMMO_BOXES,
"VEND_STOCK_DYNAMIC" = VEND_STOCK_DYNAMIC
))

DEFINE_BITFIELD(vehicle_flags, list(
Expand Down
46 changes: 39 additions & 7 deletions code/game/gamemodes/cm_initialize.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ Additional game mode variables.
var/list/monkey_types = list() //What type of monkeys do we spawn
var/latejoin_tally = 0 //How many people latejoined Marines
var/latejoin_larva_drop = LATEJOIN_MARINES_PER_LATEJOIN_LARVA //A larva will spawn in once the tally reaches this level. If set to 0, no latejoin larva drop
/// Amount of latejoin_tally already awarded as larvas
var/latejoin_larva_used = 0
/// Multiplier to the amount of marine gear, current value as calculated with modifiers
var/gear_scale = 1
/// Multiplier to the amount of marine gear, maximum reached value for
var/gear_scale_max = 1

//Role Authority set up.
/// List of role titles to override to different roles when starting game
Expand Down Expand Up @@ -914,23 +920,49 @@ Additional game mode variables.
//We do NOT want to initilialize the gear before everyone is properly spawned in
/datum/game_mode/proc/initialize_post_marine_gear_list()
var/scale = get_scaling_value()
init_gear_scale()

//Set up attachment vendor contents related to Marine count
for(var/i in GLOB.cm_vending_vendors)
var/obj/structure/machinery/cm_vending/sorted/CVS = i
CVS.populate_product_list_and_boxes(scale)
CVS.populate_product_list_and_boxes(gear_scale)

//Scale the amount of cargo points through a direct multiplier
GLOB.supply_controller.points = round(GLOB.supply_controller.points * scale)
GLOB.supply_controller.points += round(GLOB.supply_controller.points_scale * gear_scale)

/datum/game_mode/proc/get_scaling_value()
///Returns a multiplier to the amount of gear that is to be distributed roundstart, stored in [/datum/game_mode/var/gear_scale]
/datum/game_mode/proc/init_gear_scale()
//We take the number of marine players, deduced from other lists, and then get a scale multiplier from it, to be used in arbitrary manners to distribute equipment
//This might count players who ready up but get kicked back to the lobby
var/marine_pop_size = length(GLOB.alive_human_list)
var/marine_pop_size = 0
var/uscm_personnel_count = 0
for(var/mob/living/carbon/human/human as anything in GLOB.alive_human_list)
if(human.faction == FACTION_USCM)
uscm_personnel_count++
var/datum/job/job = GET_MAPPED_ROLE(human.job)
marine_pop_size += GLOB.RoleAuthority.calculate_role_weight(job)

//This gives a decimal value representing a scaling multiplier. Cannot go below 1
return max(marine_pop_size / MARINE_GEAR_SCALING_NORMAL, 1)
gear_scale = max(marine_pop_size / MARINE_GEAR_SCALING_NORMAL, 1)
gear_scale_max = gear_scale
log_debug("SUPPLY: Game start detected [marine_pop_size] weighted marines (out of [uscm_personnel_count]/[length(GLOB.alive_human_list)] USCM humans), resulting in gear_scale = [gear_scale]")
return gear_scale

///Updates the [/datum/game_mode/var/gear_scale] multiplier based on joining and cryoing marines
/datum/game_mode/proc/update_gear_scale(delta)
// Magic inverse function that guarantees marines still get good supplies for latejoins within first ~30 minutes but stalls starting 2 hours or so
gear_scale += delta * (0.25 + 0.75 / (1 + ROUND_TIME / 20000)) / MARINE_GEAR_SCALING_NORMAL
var/gear_delta = gear_scale - gear_scale_max
if(gear_delta > 0)
gear_scale_max = gear_scale
for(var/obj/structure/machinery/cm_vending/sorted/vendor as anything in GLOB.cm_vending_vendors)
vendor.update_dynamic_stock(gear_scale_max)
GLOB.supply_controller.points += round(gear_delta * GLOB.supply_controller.points_scale)

/// Updates [var/latejoin_tally] and [var/gear_scale] based on role weights of latejoiners/cryoers. Delta is the amount of role positions added/removed
/datum/game_mode/proc/latejoin_update(role, delta = 1)
var/weight = GLOB.RoleAuthority.calculate_role_weight(role)
latejoin_tally += weight * delta
update_gear_scale(weight * delta)

// for the toolbox
/datum/game_mode/proc/end_round_message()
Expand Down
2 changes: 2 additions & 0 deletions code/game/jobs/role_authority.dm
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou
* survivors and the number of roundstart Squad Rifleman slots.
*/
/datum/authority/branch/role/proc/calculate_role_weight(datum/job/J)
if(!J)
return 0
if(GLOB.ROLES_MARINES.Find(J.title))
return 1
if(GLOB.ROLES_XENO.Find(J.title))
Expand Down
7 changes: 4 additions & 3 deletions code/game/machinery/cryopod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,13 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
dept_console += A
A.moveToNullspace()

var/datum/job/job = GET_MAPPED_ROLE(occupant.job)
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
if(H.assigned_squad)
var/datum/squad/S = H.assigned_squad
S.forget_marine_in_squad(H)
var/datum/job/J = GET_MAPPED_ROLE(H.job)
if(istype(J, /datum/job/marine/specialist))
if(istype(job, /datum/job/marine/specialist))
//we make the set this specialist took if any available again
if(H.skills)
var/set_name
Expand All @@ -346,7 +346,8 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li
if(set_name && !GLOB.available_specialist_sets.Find(set_name))
GLOB.available_specialist_sets += set_name

SSticker.mode.latejoin_tally-- //Cryoing someone out removes someone from the Marines, blocking further larva spawns until accounted for
//Cryoing someone out removes someone from the Marines, blocking further larva spawns until accounted for
SSticker.mode.latejoin_update(job, -1)

//Handle job slot/tater cleanup.
GLOB.RoleAuthority.free_role(GET_MAPPED_ROLE(occupant.job), TRUE)
Expand Down
41 changes: 37 additions & 4 deletions code/game/machinery/vending/cm_vending.dm
Original file line number Diff line number Diff line change
Expand Up @@ -875,8 +875,11 @@ GLOBAL_LIST_EMPTY(vending_products)
vend_flags = VEND_CLUTTER_PROTECTION | VEND_LIMITED_INVENTORY | VEND_TO_HAND
show_points = FALSE

//this here is made to provide ability to restock vendors with different subtypes of same object, like handmade and manually filled ammo boxes.
///this here is made to provide ability to restock vendors with different subtypes of same object, like handmade and manually filled ammo boxes.
var/list/corresponding_types_list
///If using [VEND_STOCK_DYNAMIC], assoc list of product entry to list of (product multiplier, awarded objects) - as seen in [/obj/structure/machinery/cm_vending/sorted/proc/populate_product_list]
///This allows us to backtrack and refill the stocks when new players latejoin
var/list/list/dynamic_stock_multipliers

/obj/structure/machinery/cm_vending/sorted/Initialize()
. = ..()
Expand All @@ -889,14 +892,44 @@ GLOBAL_LIST_EMPTY(vending_products)
GLOB.cm_vending_vendors -= src
return ..()

//this proc, well, populates product list based on roundstart amount of players
///this proc, well, populates product list based on roundstart amount of players
/obj/structure/machinery/cm_vending/sorted/proc/populate_product_list_and_boxes(scale)
populate_product_list(scale)
if(vend_flags & VEND_STOCK_DYNAMIC)
populate_product_list(1.0)
dynamic_stock_multipliers = list()
for(var/list/vendspec in listed_products)
var/multiplier = vendspec[2]
if(multiplier > 0)
var/awarded = round(vendspec[2] * scale) // Starting amount
//Record the multiplier and how many have actually been given out
dynamic_stock_multipliers[vendspec] = list(vendspec[2], awarded)
vendspec[2] = awarded // Override starting amount
else
populate_product_list(scale)

if(vend_flags & VEND_LOAD_AMMO_BOXES)
populate_ammo_boxes()
return

//this proc, well, populates product list based on roundstart amount of players
///Updates the vendor stock when the [/datum/game_mode/var/marine_tally] has changed and we're using [VEND_STOCK_DYNAMIC]
///Assumes the scale can only increase!!! Don't take their items away!
/obj/structure/machinery/cm_vending/sorted/proc/update_dynamic_stock(new_scale)
if(!(vend_flags & VEND_STOCK_DYNAMIC))
return
for(var/list/vendspec in dynamic_stock_multipliers)
var/list/metadata = dynamic_stock_multipliers[vendspec]
var/multiplier = metadata[1] // How much do we multiply scales by
var/previous_max_amount = metadata[2] // How many we already handed out at old scale
var/projected_max_amount = round(new_scale * multiplier) // How much we would have had total now in total
var/amount_to_add = round(projected_max_amount - previous_max_amount) // Rounding just in case
if(amount_to_add > 0)
metadata[2] += amount_to_add
vendspec[2] += amount_to_add
update_derived_ammo_and_boxes_on_add(vendspec)

///this proc, well, populates product list based on roundstart amount of players
///do not rely on scale here if you use VEND_STOCK_DYNAMIC because it's already taken into account
///this is here for historical reasons and should ONLY be called by populate_product_list_and_boxes if you want dynamic stocks and ammoboxes to work
/obj/structure/machinery/cm_vending/sorted/proc/populate_product_list(scale)
return

Expand Down
Loading

0 comments on commit ba6e6aa

Please sign in to comment.