mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
Basic mobs now use z-level turnoff instead of simple (#82469)
## About The Pull Request On one compile of MetaStation, I saw that there's 45 basic mobs on the station, 256 on lavaland (the number growing from tendrils), and 59 in all other z levels combined. While we do expect Lavaland to be visited every round, at least it won't be running during the times when no one is there, but even more importantly, space exploration is something not done every round, so we don't have any reason to waste our resources on AIs that will never be interacted with. Simple animals had an easy solution to this: If no one is on the Z level, their AI turns off If someone is on the Z level, they are idle unless needed. The last simple animals that exists right now are bots, megafauna, geese, gondolas, and some minor ones like mimic, zombie, dark wizard, soulscythe, etc. Point is, we're very much nearly done going through all simple animals, so this code is being wasted just to ensure things like cleanbots won't work if no one is on the z level, something I doubt happens often, so I took their code and made it work for basic mobs instead. I could've done both but I thought it would look very bad, and maybe this is a good incentivize to get more basic mob conversions. There's one major change here and it's that we're missing the "Idle" mode, some basic mobs like the Lavaland village seems to be made with intent that they'll be running even if players aren't around, so this sets up a future PR that makes idle AI easier to add, and I want to make sure those cases are taken into account. ## Why It's Good For The Game We don't need to always be processing these basic mobs, and sets us in the future to hopefully also implement idle AIs. ## Changelog 🆑 balance: Basic mob AIs with no mobs on the Z level now stop. /🆑 --------- Co-authored-by: san7890 <the@san7890.com>
This commit is contained in:
@@ -3,27 +3,32 @@ SUBSYSTEM_DEF(ai_controllers)
|
||||
name = "AI Controller Ticker"
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_NPC
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_AI_CONTROLLERS
|
||||
wait = 0.5 SECONDS //Plan every half second if required, not great not terrible.
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
///List of all ai_subtree singletons, key is the typepath while assigned value is a newly created instance of the typepath. See setup_subtrees()
|
||||
var/list/ai_subtrees = list()
|
||||
///List of all ai controllers currently running
|
||||
var/list/active_ai_controllers = list()
|
||||
var/list/datum/ai_planning_subtree/ai_subtrees = list()
|
||||
///Assoc List of all AI statuses and all AI controllers with that status.
|
||||
var/list/ai_controllers_by_status = list(
|
||||
AI_STATUS_ON = list(),
|
||||
AI_STATUS_OFF = list(),
|
||||
)
|
||||
///Assoc List of all AI controllers and the Z level they are on, which we check when someone enters/leaves a Z level to turn them on/off.
|
||||
var/list/ai_controllers_by_zlevel = list()
|
||||
|
||||
/datum/controller/subsystem/ai_controllers/Initialize()
|
||||
setup_subtrees()
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/ai_controllers/proc/setup_subtrees()
|
||||
ai_subtrees = list()
|
||||
for(var/subtree_type in subtypesof(/datum/ai_planning_subtree))
|
||||
var/datum/ai_planning_subtree/subtree = new subtree_type
|
||||
ai_subtrees[subtree_type] = subtree
|
||||
/datum/controller/subsystem/ai_controllers/stat_entry(msg)
|
||||
var/list/active_list = ai_controllers_by_status[AI_STATUS_ON]
|
||||
var/list/inactive_list = ai_controllers_by_status[AI_STATUS_OFF]
|
||||
msg = "Active AIs:[length(active_list)]|Inactive:[length(inactive_list)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ai_controllers/fire(resumed)
|
||||
for(var/datum/ai_controller/ai_controller as anything in active_ai_controllers)
|
||||
for(var/datum/ai_controller/ai_controller as anything in ai_controllers_by_status[AI_STATUS_ON])
|
||||
if(!COOLDOWN_FINISHED(ai_controller, failed_planning_cooldown))
|
||||
continue
|
||||
|
||||
@@ -32,3 +37,17 @@ SUBSYSTEM_DEF(ai_controllers)
|
||||
ai_controller.SelectBehaviors(wait * 0.1)
|
||||
if(!LAZYLEN(ai_controller.current_behaviors)) //Still no plan
|
||||
COOLDOWN_START(ai_controller, failed_planning_cooldown, AI_FAILED_PLANNING_COOLDOWN)
|
||||
|
||||
///Creates all instances of ai_subtrees and assigns them to the ai_subtrees list.
|
||||
/datum/controller/subsystem/ai_controllers/proc/setup_subtrees()
|
||||
for(var/subtree_type in subtypesof(/datum/ai_planning_subtree))
|
||||
var/datum/ai_planning_subtree/subtree = new subtree_type
|
||||
ai_subtrees[subtree_type] = subtree
|
||||
|
||||
///Called when the max Z level was changed, updating our coverage.
|
||||
/datum/controller/subsystem/ai_controllers/proc/on_max_z_changed()
|
||||
if (!islist(ai_controllers_by_zlevel))
|
||||
ai_controllers_by_zlevel = new /list(world.maxz,0)
|
||||
while (SSai_controllers.ai_controllers_by_zlevel.len < world.maxz)
|
||||
SSai_controllers.ai_controllers_by_zlevel.len++
|
||||
SSai_controllers.ai_controllers_by_zlevel[ai_controllers_by_zlevel.len] = list()
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
SUBSYSTEM_DEF(idlenpcpool)
|
||||
name = "Idling NPC Pool"
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
priority = FIRE_PRIORITY_IDLE_NPC
|
||||
wait = 60
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/static/list/idle_mobs_by_zlevel[][]
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/stat_entry(msg)
|
||||
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
|
||||
var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
|
||||
msg = "IdleNPCS:[length(idlelist)]|Z:[length(zlist)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/proc/MaxZChanged()
|
||||
if (!islist(idle_mobs_by_zlevel))
|
||||
idle_mobs_by_zlevel = new /list(world.maxz,0)
|
||||
while (SSidlenpcpool.idle_mobs_by_zlevel.len < world.maxz)
|
||||
SSidlenpcpool.idle_mobs_by_zlevel.len++
|
||||
SSidlenpcpool.idle_mobs_by_zlevel[idle_mobs_by_zlevel.len] = list()
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
|
||||
|
||||
if (!resumed)
|
||||
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
|
||||
src.currentrun = idlelist.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
if (QDELETED(SA))
|
||||
GLOB.simple_animals[AI_IDLE] -= SA
|
||||
stack_trace("Found a null in simple_animals deactive list [SA.type]!")
|
||||
continue
|
||||
|
||||
if(!SA.ckey)
|
||||
if(SA.stat != DEAD)
|
||||
SA.handle_automated_movement()
|
||||
if(SA.stat != DEAD)
|
||||
SA.consider_wakeup()
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
Reference in New Issue
Block a user