mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 08:27:13 +01:00
201592f6bd
Refactoring the entire destroy proc path from Mob Human all the way down to Atom while trying to find the causes for the damn mob human hard deletes. This PR comprehensively reorganizes every single stray snowflake var used by /atom/ all the way to /mob/living/carbon/human, and makes sure that every var that COULD store a reference, is now cleared during the entirety of the Mob Destroy() parent hierarchy. This may very well be the end of the lag war. In total, I've hunted down and cleared 39 hanging references between /atom and /mob/living/carbon/human --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com>
90 lines
2.5 KiB
Plaintext
90 lines
2.5 KiB
Plaintext
SUBSYSTEM_DEF(mob_ai)
|
|
name = "Mobs - AI"
|
|
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
|
|
priority = FIRE_PRIORITY_NPC_MOVEMENT
|
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
|
init_order = INIT_ORDER_AI_CONTROLLERS
|
|
|
|
var/list/processing = list()
|
|
var/list/currentrun = list()
|
|
|
|
///A list of mutex locks, to avoid reentry and starting new processings on mobs that were already processing from the previous run
|
|
VAR_PRIVATE/list/datum/weakref/mutexes = list() //Yes i know they're opinionably not mutexes as there's only one process shut up
|
|
|
|
/datum/controller/subsystem/mob_ai/stat_entry(msg)
|
|
msg = "P:[length(processing)]"
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/mob_ai/fire(resumed = FALSE)
|
|
if (!resumed)
|
|
src.currentrun = processing.Copy()
|
|
|
|
var/list/currentrun = src.currentrun
|
|
|
|
//Remove the mobs that have a mutex from being reprocessed again, this run
|
|
for(var/datum/weakref/locked_mob as anything in mutexes)
|
|
var/mob/possible_locked_mob = locked_mob.resolve()
|
|
|
|
//The mob got QDEL'd, or otherwise somehow disappeared
|
|
if(!possible_locked_mob)
|
|
mutexes -= locked_mob
|
|
continue
|
|
|
|
currentrun -= possible_locked_mob
|
|
|
|
while(length(currentrun))
|
|
var/mob/M = currentrun[length(currentrun)]
|
|
currentrun.len--
|
|
|
|
if(QDELETED(M))
|
|
processing -= M
|
|
continue
|
|
|
|
if(M.ckey)
|
|
// cliented mobs are not allowed to think
|
|
LOG_DEBUG("SSmob_ai: Type '[M.type]' was still thinking despite having a client!")
|
|
MOB_STOP_THINKING(M)
|
|
continue
|
|
|
|
if(!M.frozen && !M.stat)
|
|
INVOKE_ASYNC(src, PROC_REF(async_think), M)
|
|
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/**
|
|
* Invoke .think() on a mob in an asyncronous manner, ensuring to properly set the mutex for it, so it's not reprocessed until it's finished
|
|
*
|
|
* It's up to the caller to check that the mob does not have a mutex set, before calling this proc
|
|
*/
|
|
/datum/controller/subsystem/mob_ai/proc/async_think(mob/mob_to_process)
|
|
var/datum/weakref/mob_weakref = WEAKREF(mob_to_process)
|
|
|
|
mutexes += mob_weakref
|
|
|
|
mob_to_process.think()
|
|
|
|
mutexes -= mob_weakref
|
|
|
|
/**
|
|
* Perform AI logic for a mob, called by the AI subsystem
|
|
*
|
|
* For the love of god, *DO NOT* set a waitfor false or similar things here, this proc is under a mutex and if it returns before having done its work,
|
|
* it will mess things up!
|
|
*/
|
|
/mob/proc/think()
|
|
return
|
|
|
|
/mob/proc/on_think_disabled()
|
|
walk_to(src, 0)
|
|
QDEL_NULL(move_packet)
|
|
|
|
/mob/proc/on_think_enabled()
|
|
return
|
|
|
|
/datum/controller/subsystem/mob_ai/ExplosionStart()
|
|
can_fire = FALSE
|
|
|
|
/datum/controller/subsystem/mob_ai/ExplosionEnd()
|
|
can_fire = TRUE
|