Skip to content

Commit

Permalink
Adds lag compensation for the supermatter zaps and some antagonists. (t…
Browse files Browse the repository at this point in the history
…gstation#78174)

## About The Pull Request
Adds delta time scaling for changeling chemical generation, xenomorph
plasma generation, xenomorph resin healing (up to 8 seconds per tick to
prevent weird instant heal phenomena in extreme cases), and revenant
essence generation. This delta time scaling is based on the world's time
and the respective subsystem's last fire. This will help keep these
generation smooth even when their respective subsystem lags, preventing
lag from ruining the antagonists rounds. This can still slow down if the
actual world is slowing down, but that's fine because the rest of the
world will typically be slowing down proportionately so it's fair.

Fixes supermatter zap rate not scaling with its internal energy
properly. Ghilker forgot to scale the time reduction by seconds. It
should be much faster at higher energy levels, making the transition
between 0 and 5 GeV more smooth.

Supermatter zap power generation will scale by the world's delta time
between the supermatter's last zap, making power generation more
consistent even when atmos lags. Also prevents the supermatter zap rate
scaling from also scaling the power generation by extreme amounts,
keeping it linear and consistent for the first 5 GeV (>5GeV has cringe
power multipliers, but I'm going to ignore that for this PR, because I
want this to mainly be a consistency thing rather than a balance thing).
A 1.5GeV supermatter will be able to generate around 800kW* of power. I
forgot exactly what goal of power we want the roundstart SM to produce,
so I might change the scale if I find the target power generation.

* - By generate 800kW of power I mean the energy the actual zaps
contain. Tesla coils don't collect 100% of it. I'll test later to see
how much an actual roundstart SM will output to grid (ignoring SMES),
and I'll try to keep it as close as possible to what it was before this
PR assuming no lag.
## Why It's Good For The Game
Subsystems can disproportionately lag a lot more compared to the rest of
the subsystems and game. This can ruin antagonist rounds as it can slow
their chemicals, plasma or whatever generation grinding to a halt. The
delta time scaling will significantly reduce the impact of lag for these
antagonists, allowing them to play more normally even while the
subsystems their generators run on are lagging.

Supermatter zap rate was supposed to fire every 2.5 or something seconds
at 1.5GeV according to comments on older commits. I just assume they
accidentally forgot to scale their time reduction by seconds, as doing
that made it work accordingly.

For supermatter zap power generation delta time scaling, kinda same
reasoning as for the antagonists. We don't want power generation to stop
because atmos ss is being slow. Scaling between the zaps also prevents a
nonlinear boost to power generation making it even more absurd at higher
energy levels.
## Changelog
:cl:
balance: Supermatter zap power generation scales with the delta time
between its last zaps, preventing faster zapping from scaling power
generation to extreme levels.
fix: Fixes supermatter zap rate not scaling properly. It should zap much
faster at higher energy levels as intended.
qol: Changeling chemical generation scales with the world's delta time,
making its rate independent of subsystem lag.
qol: Revenant essence generation scales with the world's delta time,
making its rate independent of subsystem lag.
qol: Xenomorph plasma generation and resin healing scales with the
world's delta time, making their rates independent of subsystem lag.
/:cl:
  • Loading branch information
Pickle-Coding authored Sep 11, 2023
1 parent 13318e8 commit ea11068
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 13 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@
#define SSMOBS_DT (SSmobs.wait/10)
#define SSOBJ_DT (SSobj.wait/10)

// The change in the world's time from the subsystem's last fire in seconds.
#define DELTA_WORLD_TIME(ss) ((world.time - ss.last_fire) * 0.1)

/// The timer key used to know how long subsystem initialization takes
#define SS_INIT_TIMER_KEY "ss_init"

Expand Down
6 changes: 4 additions & 2 deletions code/modules/antagonists/changeling/changeling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,15 @@
/datum/antagonist/changeling/proc/on_life(datum/source, seconds_per_tick, times_fired)
SIGNAL_HANDLER

var/delta_time = DELTA_WORLD_TIME(SSmobs)

// If dead, we only regenerate up to half chem storage.
if(owner.current.stat == DEAD)
adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * seconds_per_tick, total_chem_storage * 0.5)
adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * delta_time, total_chem_storage * 0.5)

// If we're not dead - we go up to the full chem cap.
else
adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * seconds_per_tick)
adjust_chemicals((chem_recharge_rate - chem_recharge_slowdown) * delta_time)

/**
* Signal proc for [COMSIG_LIVING_POST_FULLY_HEAL], getting admin-healed restores our chemicals.
Expand Down
17 changes: 10 additions & 7 deletions code/modules/mob/living/carbon/alien/organs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,24 @@
actions_types = list(/datum/action/cooldown/alien/transfer)

/obj/item/organ/internal/alien/plasmavessel/on_life(seconds_per_tick, times_fired)
var/delta_time = DELTA_WORLD_TIME(SSmobs)
//Instantly healing to max health in a single tick would be silly. If it takes 8 seconds to fire, then something's fucked.
var/delta_time_capped = min(delta_time, 8)
//If there are alien weeds on the ground then heal if needed or give some plasma
if(locate(/obj/structure/alien/weeds) in owner.loc)
if(owner.health >= owner.maxHealth)
owner.adjustPlasma(plasma_rate * seconds_per_tick)
owner.adjustPlasma(plasma_rate * delta_time)
else
var/heal_amt = heal_rate
if(!isalien(owner))
heal_amt *= 0.2
owner.adjustPlasma(0.5 * plasma_rate * seconds_per_tick)
owner.adjustBruteLoss(-heal_amt * seconds_per_tick)
owner.adjustFireLoss(-heal_amt * seconds_per_tick)
owner.adjustOxyLoss(-heal_amt * seconds_per_tick)
owner.adjustCloneLoss(-heal_amt * seconds_per_tick)
owner.adjustPlasma(0.5 * plasma_rate * delta_time_capped)
owner.adjustBruteLoss(-heal_amt * delta_time_capped)
owner.adjustFireLoss(-heal_amt * delta_time_capped)
owner.adjustOxyLoss(-heal_amt * delta_time_capped)
owner.adjustCloneLoss(-heal_amt * delta_time_capped)
else
owner.adjustPlasma(0.1 * plasma_rate * seconds_per_tick)
owner.adjustPlasma(0.1 * plasma_rate * delta_time)

/obj/item/organ/internal/alien/plasmavessel/on_insert(mob/living/carbon/organ_owner)
. = ..()
Expand Down
3 changes: 2 additions & 1 deletion code/modules/mob/living/simple_animal/revenant.dm
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
/mob/living/simple_animal/revenant/Life(seconds_per_tick = SSMOBS_DT, times_fired)
if(stasis)
return
var/delta_time = DELTA_WORLD_TIME(SSmobs)
if(revealed && essence <= 0)
death()
if(unreveal_time && world.time >= unreveal_time)
Expand All @@ -145,7 +146,7 @@
REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT)
to_chat(src, span_revenboldnotice("You can move again!"))
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
essence = min(essence + (essence_regen_amount * seconds_per_tick), essence_regen_cap)
essence = min(essence + (essence_regen_amount * delta_time), essence_regen_cap)
update_mob_action_buttons() //because we update something required by our spells in life, we need to update our buttons
update_spooky_icon()
update_health_hud()
Expand Down
9 changes: 6 additions & 3 deletions code/modules/power/supermatter/supermatter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,19 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
// PART 3: POWER PROCESSING
internal_energy_factors = calculate_internal_energy()
zap_factors = calculate_zap_multiplier()
if(internal_energy && (last_power_zap + 4 SECONDS - (internal_energy * 0.001)) < world.time)
if(internal_energy && (last_power_zap + (4 - internal_energy * 0.001) SECONDS) < world.time)
playsound(src, 'sound/weapons/emitter2.ogg', 70, TRUE)
hue_angle_shift = clamp(903 * log(10, (internal_energy + 8000)) - 3590, -50, 240)
var/zap_color = color_matrix_rotate_hue(hue_angle_shift)
//Scale the strength of the zap with the world's time elapsed between zaps in seconds.
//Capped at 16 seconds to prevent a crazy burst of energy if atmos was halted for a long time.
var/delta_time = min((world.time - last_power_zap) * 0.1, 16)
supermatter_zap(
zapstart = src,
range = 3,
zap_str = 5 * internal_energy * zap_multiplier,
zap_str = 1.25 * internal_energy * zap_multiplier * delta_time,
zap_flags = ZAP_SUPERMATTER_FLAGS,
zap_cutoff = 300,
zap_cutoff = 300 * delta_time,
power_level = internal_energy,
color = zap_color,
)
Expand Down

0 comments on commit ea11068

Please sign in to comment.