Files
VMSolidus 2e61d8fd15 Kill Hardsuit Processing (#22809)
Life() was wasting a bunch of processing time on "Every hardsuit
forever" regardless of if it was equipped or not. Additionally Life()
was responsible for double-processing hardsuits, which is extremely
improper. Since hardsuits are being moved to SSprocessing instead of
SSmobs, which has a different tickrate, I went ahead and tick
differentiated them to make sure that nothing will break.
2026-07-10 17:05:20 +00:00

142 lines
4.3 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/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()
//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) : src.currentrun
var/seconds_per_tick = wait * 0.1
while(length(currentrun))
var/datum/thing = currentrun[length(currentrun)]
currentrun.len--
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