mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 04:51:32 +01:00
Life changes (#19560)
Refactored Life() to receive seconds per tick and times fired as parameters. Life() now cannot be slept in, turned various sleepings into async calls procs. Optimized mob AI subsystems, gave them new priorities levels and flags. Grab upgrades are now elaborated asynchronously, tweaked them to avoid stacking multiple upgrades. Fixed plains tyrants keeping sending messages about stomping even if dead.
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
SUBSYSTEM_DEF(mobs)
|
||||
name = "Mobs - Life"
|
||||
init_order = INIT_ORDER_MISC // doesn't really matter when we init
|
||||
priority = SS_PRIORITY_MOB
|
||||
runlevels = RUNLEVELS_PLAYING
|
||||
|
||||
var/list/slept = list()
|
||||
priority = FIRE_PRIORITY_MOBS
|
||||
flags = SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 2 SECONDS
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
@@ -70,7 +69,7 @@ SUBSYSTEM_DEF(mobs)
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry(msg)
|
||||
msg = "P:[GLOB.mob_list.len]"
|
||||
msg = "P:[length(GLOB.mob_list)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
||||
@@ -82,10 +81,12 @@ SUBSYSTEM_DEF(mobs)
|
||||
//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/list/currentrun = resumed ? (src.currentrun &= (GLOB.mob_list + processing)) : src.currentrun
|
||||
|
||||
while (currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
var/seconds_per_tick = wait / (1 SECONDS)
|
||||
|
||||
while(length(currentrun))
|
||||
var/datum/thing = currentrun[length(currentrun)]
|
||||
currentrun.len--
|
||||
if(!ismob(thing))
|
||||
if(!QDELETED(thing))
|
||||
@@ -93,13 +94,13 @@ SUBSYSTEM_DEF(mobs)
|
||||
stop_processing(thing)
|
||||
else
|
||||
processing -= thing
|
||||
if (MC_TICK_CHECK)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
var/mob/M = thing
|
||||
|
||||
if (QDELETED(M))
|
||||
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
|
||||
@@ -110,15 +111,8 @@ SUBSYSTEM_DEF(mobs)
|
||||
return
|
||||
continue
|
||||
|
||||
var/time = world.time
|
||||
|
||||
if (!M.frozen)
|
||||
M.Life()
|
||||
|
||||
if (time != world.time && !slept[M.type])
|
||||
slept[M.type] = TRUE
|
||||
var/diff = world.time - time
|
||||
LOG_DEBUG("SSmobs: Type '[M.type]' slept for [diff] ds in Life()! Suppressing further warnings.")
|
||||
M.Life(seconds_per_tick, times_fired)
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
SUBSYSTEM_DEF(mob_ai)
|
||||
name = "Mobs - AI"
|
||||
flags = SS_NO_INIT
|
||||
priority = SS_PRIORITY_MOB
|
||||
runlevels = RUNLEVELS_PLAYING
|
||||
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/list/datum/weakref/mutexes = list() //Yes i know they're opinionably not mutexes as there's only one process shut up
|
||||
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:[processing.len]"
|
||||
msg = "P:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/mob_ai/fire(resumed = FALSE)
|
||||
@@ -21,7 +22,7 @@ SUBSYSTEM_DEF(mob_ai)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
//Remove the mobs that have a mutex from being reprocessed again, this run
|
||||
for(var/datum/weakref/locked_mob in mutexes)
|
||||
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
|
||||
@@ -31,24 +32,24 @@ SUBSYSTEM_DEF(mob_ai)
|
||||
|
||||
currentrun -= possible_locked_mob
|
||||
|
||||
while (currentrun.len)
|
||||
var/mob/M = currentrun[currentrun.len]
|
||||
while(length(currentrun))
|
||||
var/mob/M = currentrun[length(currentrun)]
|
||||
currentrun.len--
|
||||
|
||||
if (QDELETED(M))
|
||||
if(QDELETED(M))
|
||||
processing -= M
|
||||
continue
|
||||
|
||||
if (M.ckey)
|
||||
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)
|
||||
if(!M.frozen && !M.stat)
|
||||
INVOKE_ASYNC(src, PROC_REF(async_think), M)
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* This is the fast AI subsystem, used for mobs that are doing something visible and thus have priority over other mobs processing
|
||||
*
|
||||
* You should promote mobs to fast thinking if eg. they are fighting players or similar, and de-promote them once they resume their normal routine
|
||||
*/
|
||||
MOB_AI_SUBSYSTEM_DEF(mob_fast_ai)
|
||||
name = "Mobs - Fast AI"
|
||||
flags = SS_KEEP_TIMING | SS_BACKGROUND | SS_NO_INIT
|
||||
priority = FIRE_PRIORITY_NPC_ACTIONS
|
||||
wait = 5
|
||||
|
||||
Reference in New Issue
Block a user