Process procs now properly utilize deltatime when implementing rates, timers and probabilities (#52981)

* Process procs now properly use deltatime when implementing rates, timers and probabilities

* Review fixes

* Geiger counters cleanup

Made hardsuit geiger code more similar to geiger counter code
Geiger counters are more responsive now

* Moved SS*_DT defines to subsystems.dm

* Rebase fix

* Redefined the SS*_DT defines to use the subsystem wait vars

* Implemented suggested changes by @AnturK

* Commented /datum/proc/process about the deltatime stuff

* Send delta_time as a process parameter instead of the defines

Also DTfied acid_processing

* Dtfied new acid component
This commit is contained in:
Donkie
2020-09-08 10:24:05 +02:00
committed by GitHub
parent 671c4666ed
commit 53b212ddf2
159 changed files with 808 additions and 719 deletions

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(air)
name = "Atmospherics"
init_order = INIT_ORDER_AIR
priority = FIRE_PRIORITY_AIR
wait = 5
wait = 0.5 SECONDS
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
@@ -39,6 +39,8 @@ SUBSYSTEM_DEF(air)
var/list/queued_for_activation
var/display_all_groups = FALSE
var/lasttick = 0
/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
msg += "AT:[round(cost_turfs,1)]|"
@@ -72,6 +74,7 @@ SUBSYSTEM_DEF(air)
/datum/controller/subsystem/air/fire(resumed = FALSE)
var/timer = TICK_USAGE_REAL
var/delta_time = wait * 0.1
if(currentpart == SSAIR_REBUILD_PIPENETS)
var/list/pipenet_rebuilds = pipenets_needing_rebuilt
@@ -86,7 +89,7 @@ SUBSYSTEM_DEF(air)
currentpart = SSAIR_PIPENETS
if(currentpart == SSAIR_PIPENETS || !resumed)
process_pipenets(resumed)
process_pipenets(delta_time, resumed)
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
@@ -95,7 +98,7 @@ SUBSYSTEM_DEF(air)
if(currentpart == SSAIR_ATMOSMACHINERY)
timer = TICK_USAGE_REAL
process_atmos_machinery(resumed)
process_atmos_machinery(delta_time, resumed)
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
@@ -131,7 +134,7 @@ SUBSYSTEM_DEF(air)
if(currentpart == SSAIR_HOTSPOTS)
timer = TICK_USAGE_REAL
process_hotspots(resumed)
process_hotspots(delta_time, resumed)
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
@@ -150,7 +153,7 @@ SUBSYSTEM_DEF(air)
SStgui.update_uis(SSair) //Lightning fast debugging motherfucker
/datum/controller/subsystem/air/proc/process_pipenets(resumed = FALSE)
/datum/controller/subsystem/air/proc/process_pipenets(delta_time, resumed = FALSE)
if (!resumed)
src.currentrun = networks.Copy()
//cache for sanic speed (lists are references anyways)
@@ -159,7 +162,7 @@ SUBSYSTEM_DEF(air)
var/datum/thing = currentrun[currentrun.len]
currentrun.len--
if(thing)
thing.process()
thing.process(delta_time)
else
networks.Remove(thing)
if(MC_TICK_CHECK)
@@ -169,8 +172,7 @@ SUBSYSTEM_DEF(air)
if(istype(atmos_machine, /obj/machinery/atmospherics))
pipenets_needing_rebuilt += atmos_machine
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = FALSE)
var/seconds = wait * 0.1
/datum/controller/subsystem/air/proc/process_atmos_machinery(delta_time, resumed = FALSE)
if (!resumed)
src.currentrun = atmos_machinery.Copy()
//cache for sanic speed (lists are references anyways)
@@ -178,7 +180,7 @@ SUBSYSTEM_DEF(air)
while(currentrun.len)
var/obj/machinery/M = currentrun[currentrun.len]
currentrun.len--
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
if(!M || (M.process_atmos(delta_time) == PROCESS_KILL))
atmos_machinery.Remove(M)
if(MC_TICK_CHECK)
return
@@ -196,7 +198,7 @@ SUBSYSTEM_DEF(air)
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_hotspots(resumed = FALSE)
/datum/controller/subsystem/air/proc/process_hotspots(delta_time, resumed = FALSE)
if (!resumed)
src.currentrun = hotspots.Copy()
//cache for sanic speed (lists are references anyways)
@@ -205,7 +207,7 @@ SUBSYSTEM_DEF(air)
var/obj/effect/hotspot/H = currentrun[currentrun.len]
currentrun.len--
if (H)
H.process()
H.process(delta_time)
else
hotspots -= H
if(MC_TICK_CHECK)

View File

@@ -1,6 +1,7 @@
PROCESSING_SUBSYSTEM_DEF(dcs)
name = "Datum Component System"
flags = SS_NO_INIT
wait = 1 SECONDS
var/list/elements_by_type = list()

View File

@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(events)
var/datum/thing = currentrun[currentrun.len]
currentrun.len--
if(thing)
thing.process()
thing.process(wait * 0.1)
else
running.Remove(thing)
if (MC_TICK_CHECK)

View File

@@ -18,6 +18,7 @@ SUBSYSTEM_DEF(fire_burning)
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/delta_time = wait * 0.1
while(currentrun.len)
var/obj/O = currentrun[currentrun.len]
@@ -31,7 +32,7 @@ SUBSYSTEM_DEF(fire_burning)
if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun
if(!(O.resistance_flags & FIRE_PROOF))
O.take_damage(20, BURN, FIRE, 0)
O.take_damage(10 * delta_time, BURN, FIRE, 0)
else
O.extinguish()

View File

@@ -2,6 +2,7 @@ SUBSYSTEM_DEF(machines)
name = "Machines"
init_order = INIT_ORDER_MACHINES
flags = SS_KEEP_TIMING
wait = 2 SECONDS
var/list/processing = list()
var/list/currentrun = list()
var/list/powernets = list()
@@ -36,11 +37,10 @@ SUBSYSTEM_DEF(machines)
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/seconds = wait * 0.1
while(currentrun.len)
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL)
if(!QDELETED(thing) && thing.process(wait * 0.1) != PROCESS_KILL)
if(thing.use_power)
thing.auto_use_power() //add back the power state
else

View File

@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(mobs)
priority = FIRE_PRIORITY_MOBS
flags = SS_KEEP_TIMING | SS_NO_INIT
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
wait = 2 SECONDS
var/list/currentrun = list()
var/static/list/clients_by_zlevel[][]
@@ -25,7 +26,6 @@ SUBSYSTEM_DEF(mobs)
dead_players_by_zlevel[dead_players_by_zlevel.len] = list()
/datum/controller/subsystem/mobs/fire(resumed = FALSE)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = GLOB.mob_living_list.Copy()
@@ -36,7 +36,7 @@ SUBSYSTEM_DEF(mobs)
var/mob/living/L = currentrun[currentrun.len]
currentrun.len--
if(L)
L.Life(seconds, times_fired)
L.Life(times_fired)
else
GLOB.mob_living_list.Remove(L)
if (MC_TICK_CHECK)

View File

@@ -2,3 +2,4 @@ PROCESSING_SUBSYSTEM_DEF(mood)
name = "Mood"
flags = SS_NO_INIT | SS_BACKGROUND
priority = 20
wait = 1 SECONDS

View File

@@ -1,6 +1,4 @@
//Fires five times every second.
PROCESSING_SUBSYSTEM_DEF(fastprocess)
name = "Fast Processing"
wait = 2
wait = 0.2 SECONDS
stat_tag = "FP"

View File

@@ -1,7 +1,7 @@
PROCESSING_SUBSYSTEM_DEF(nanites)
name = "Nanites"
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 10
wait = 1 SECONDS
var/list/datum/nanite_cloud_backup/cloud_backups = list()
var/list/mob/living/nanite_monitored_mobs = list()

View File

@@ -2,4 +2,4 @@ PROCESSING_SUBSYSTEM_DEF(obj)
name = "Objects"
priority = FIRE_PRIORITY_OBJ
flags = SS_NO_INIT
wait = 20
wait = 2 SECONDS

View File

@@ -1,10 +1,10 @@
//Used to process objects. Fires once every second.
//Used to process objects.
SUBSYSTEM_DEF(processing)
name = "Processing"
priority = FIRE_PRIORITY_PROCESS
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 10
wait = 1 SECONDS
var/stat_tag = "P" //Used for logging
var/list/processing = list()
@@ -25,14 +25,26 @@ SUBSYSTEM_DEF(processing)
current_run.len--
if(QDELETED(thing))
processing -= thing
else if(thing.process(wait) == PROCESS_KILL)
else if(thing.process(wait * 0.1) == PROCESS_KILL)
// fully stop so that a future START_PROCESSING will work
STOP_PROCESSING(src, thing)
if (MC_TICK_CHECK)
return
///This proc is called on a datum if it is being processed in a subsystem. If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
/datum/proc/process()
/**
* This proc is called on a datum on every "cycle" if it is being processed by a subsystem. The time between each cycle is determined by the subsystem's "wait" setting.
* You can start and stop processing a datum using the START_PROCESSING and STOP_PROCESSING defines.
*
* Since the wait setting of a subsystem can be changed at any time, it is important that any rate-of-change that you implement in this proc is multiplied by the delta_time that is sent as a parameter,
* Additionally, any "prob" you use in this proc should instead use the DT_PROB define to make sure that the final probability per second stays the same even if the subsystem's wait is altered.
* Examples where this must be considered:
* - Implementing a cooldown timer, use `mytimer -= delta_time`, not `mytimer -= 1`. This way, `mytimer` will always have the unit of seconds
* - Damaging a mob, do `L.adjustFireLoss(20 * delta_time)`, not `L.adjustFireLoss(20)`. This way, the damage per second stays constant even if the wait of the subsystem is changed
* - Probability of something happening, do `if(DT_PROB(25, delta_time))`, not `if(prob(25))`. This way, if the subsystem wait is e.g. lowered, there won't be a higher chance of this event happening per second
*
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(delta_time)
set waitfor = FALSE
return PROCESS_KILL

View File

@@ -6,15 +6,15 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
name = "Quirks"
init_order = INIT_ORDER_QUIRKS
flags = SS_BACKGROUND
wait = 10
runlevels = RUNLEVEL_GAME
wait = 1 SECONDS
var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/
var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad
var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process
var/list/quirk_blacklist = list() //A list of quirks that can not be used with each other. Format: list(quirk1,quirk2),list(quirk3,quirk4)
///An assoc list of quirks that can be obtained as a hardcore character, and their hardcore value.
var/list/hardcore_quirks = list()
var/list/hardcore_quirks = list()
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)

View File

@@ -1,6 +1,7 @@
PROCESSING_SUBSYSTEM_DEF(radiation)
name = "Radiation"
flags = SS_NO_INIT | SS_BACKGROUND
wait = 1 SECONDS
var/list/warned_atoms = list()

View File

@@ -43,7 +43,7 @@ SUBSYSTEM_DEF(tgui)
current_run.len--
// TODO: Move user/src_object check to process()
if(ui && ui.user && ui.src_object)
ui.process()
ui.process(wait * 0.1)
else
open_uis.Remove(ui)
if(MC_TICK_CHECK)
@@ -192,7 +192,7 @@ SUBSYSTEM_DEF(tgui)
for(var/datum/tgui/ui in open_uis_by_src[key])
// Check if UI is valid.
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user))
ui.process(force = 1)
ui.process(wait * 0.1, force = 1)
count++
return count
@@ -251,7 +251,7 @@ SUBSYSTEM_DEF(tgui)
return count
for(var/datum/tgui/ui in user.tgui_open_uis)
if(isnull(src_object) || ui.src_object == src_object)
ui.process(force = 1)
ui.process(wait * 0.1, force = 1)
count++
return count