mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-22 05:17:38 +01:00
1423fcd04e
Organs were being given ~3 seconds of DT per ~2 seconds of real time, because they were being hit by Process() TWICE, once during processing for the "Set of all objects", and again during processing for the "Set of all mobs". No species was hit harder than this but IPCs, who suffered from having wildly inconsistent temperature mechanics that seemingly never matched the expected numbers. I have actually tested this PR to verify that it works. I even went the extra mile to more extensively test IPC temperature mechanics to find a separate bug unrelated to DTs that was causing suit coolers to just straight up not work at all (space suit or otherwise) on a majority of all IPC subspecies. I then tested the numbers in the PR for IPC cooling to verify that things work as intended. <img width="969" height="623" alt="image" src="https://github.com/user-attachments/assets/01c3aca7-b436-4e52-86f7-aed847dcba5e" /> I also tweaked all the subsystems to have a small performance improvement. --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com>
158 lines
4.8 KiB
Plaintext
158 lines
4.8 KiB
Plaintext
SUBSYSTEM_DEF(mobs)
|
|
name = "Mobs - Life"
|
|
priority = FIRE_PRIORITY_MOBS
|
|
flags = SS_KEEP_TIMING
|
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
|
wait = 2 SECONDS
|
|
|
|
var/list/currentrun = list()
|
|
var/list/processing = list()
|
|
|
|
var/list/all_rats = list() // Contains all *living* rats.
|
|
|
|
///Contains all mannequins used by character preview
|
|
var/list/mob/living/carbon/human/dummy/mannequin/mannequins = list()
|
|
|
|
var/list/greatworms = list()
|
|
var/list/greatasses = list()
|
|
|
|
// Devour types (these are typecaches). Only simple_animals check these, other types are handled specially.
|
|
var/list/mtl_synthetic = list(
|
|
/mob/living/simple_animal/hostile/hivebot
|
|
)
|
|
|
|
var/list/mtl_weird = list(
|
|
/mob/living/simple_animal/construct,
|
|
/mob/living/simple_animal/shade,
|
|
/mob/living/simple_animal/slime,
|
|
/mob/living/simple_animal/hostile/faithless
|
|
)
|
|
|
|
// Actual human mobs are delibrately not in this list as they are handled elsewhere.
|
|
var/list/mtl_humanoid = list(
|
|
/mob/living/simple_animal/hostile/pirate,
|
|
/mob/living/simple_animal/hostile/russian,
|
|
/mob/living/simple_animal/hostile/syndicate
|
|
)
|
|
|
|
var/list/mtl_incorporeal = list(
|
|
/mob/living/simple_animal/hostile/carp/holodeck,
|
|
/mob/living/simple_animal/penguin/holodeck,
|
|
/mob/living/simple_animal/corgi/puppy/holodeck,
|
|
/mob/living/simple_animal/cat/kitten/holodeck
|
|
)
|
|
|
|
/**
|
|
* An associative list containing timer IDs associated with a mannequin that they're supposed to delete
|
|
*/
|
|
var/list/mannequins_del_timers = list()
|
|
|
|
/datum/controller/subsystem/mobs/Initialize()
|
|
// Some setup work for the eat-types lists.
|
|
mtl_synthetic = typecacheof(mtl_synthetic) + list(
|
|
/mob/living/simple_animal/hostile/icarus_drone = TRUE,
|
|
/mob/living/simple_animal/hostile/viscerator = TRUE,
|
|
/mob/living/simple_animal/spiderbot = TRUE
|
|
)
|
|
|
|
mtl_weird = typecacheof(mtl_weird) + list(
|
|
/mob/living/simple_animal/adultslime = TRUE
|
|
)
|
|
|
|
mtl_humanoid = typecacheof(mtl_humanoid)
|
|
|
|
mtl_incorporeal = typecacheof(mtl_incorporeal)
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/mobs/stat_entry(msg)
|
|
msg = "P:[length(GLOB.mob_list)]"
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
|
if (!resumed)
|
|
src.currentrun = GLOB.mob_list.Copy()
|
|
src.currentrun += processing.Copy()
|
|
|
|
//Mobs might have been removed between the previous and a resumed fire, yet we want to maintain the priority to process
|
|
//the mobs that we didn't in the previous run, hence we have to pay the price of a list subtraction
|
|
//with &= we say to remove any item in the first list that is not in the second one
|
|
//of course, if we haven't resumed, this comparison would be useless, hence we skip it
|
|
var/list/currentrun = resumed ? (src.currentrun &= (GLOB.mob_list + processing)) : src.currentrun
|
|
|
|
var/seconds_per_tick = wait * 0.1
|
|
|
|
while(length(currentrun))
|
|
var/datum/thing = currentrun[length(currentrun)]
|
|
currentrun.len--
|
|
if(!ismob(thing))
|
|
if(!QDELETED(thing))
|
|
if(thing.process(seconds_per_tick, times_fired) == PROCESS_KILL)
|
|
stop_processing(thing)
|
|
else
|
|
processing -= thing
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
continue
|
|
|
|
var/mob/M = thing
|
|
|
|
if(QDELETED(M))
|
|
LOG_DEBUG("SSmobs: QDELETED mob [DEBUG_REF(M)] left in processing list!")
|
|
// We can just go ahead and remove them from all the mob lists.
|
|
GLOB.mob_list -= M
|
|
GLOB.dead_mob_list -= M
|
|
GLOB.living_mob_list -= M
|
|
|
|
if (MC_TICK_CHECK)
|
|
return
|
|
continue
|
|
|
|
if (!M.frozen)
|
|
M.Life(seconds_per_tick, times_fired)
|
|
|
|
if (MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/mobs/proc/get_mannequin(ckey)
|
|
. = mannequins[ckey]
|
|
if (!.)
|
|
. = new /mob/living/carbon/human/dummy/mannequin
|
|
mannequins[ckey] = .
|
|
|
|
mannequins_del_timers[ckey] = addtimer(CALLBACK(src, PROC_REF(del_mannequin), ckey), 5 MINUTES, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE)
|
|
|
|
/datum/controller/subsystem/mobs/proc/del_mannequin(ckey)
|
|
var/mannequin = mannequins[ckey]
|
|
mannequins[ckey] = null
|
|
mannequins -= ckey
|
|
|
|
//Remove the deletion timer, if it exists
|
|
if(mannequins_del_timers[ckey])
|
|
deltimer(mannequins_del_timers[ckey])
|
|
mannequins_del_timers[ckey] = null
|
|
mannequins_del_timers -= ckey
|
|
|
|
qdel(mannequin)
|
|
|
|
/**
|
|
* Used to dereference a mannequin, does not delete it per-se
|
|
*
|
|
* * the_mannequin - A `/mob/living/carbon/human/dummy/mannequin` to search for, and dereference if found
|
|
*/
|
|
/datum/controller/subsystem/mobs/proc/free_mannequin(mob/living/carbon/human/dummy/mannequin/the_mannequin)
|
|
for(var/ckey in mannequins)
|
|
if(mannequins[ckey] == the_mannequin)
|
|
mannequins[ckey] = null
|
|
mannequins -= ckey
|
|
|
|
//Remove the deletion timer, if it exists
|
|
if(mannequins_del_timers[ckey])
|
|
deltimer(mannequins_del_timers[ckey])
|
|
mannequins_del_timers[ckey] = null
|
|
mannequins_del_timers -= ckey
|
|
|
|
// Helper so PROCESS_KILL works.
|
|
/datum/controller/subsystem/mobs/proc/stop_processing(datum/D)
|
|
STOP_PROCESSING(src, D)
|