mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 11:37:40 +01:00
wire up ai idling to spatial grid (#30711)
* wire up ai idling to spatial grid * lint * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: warriorstar-orion <orion@snowfrost.garden> * stupid loadbearing src * some spatial grid cleanup * make sure to remove controllers in the GLOB * immediately set targets and state for hiveloord brood * properly fail behaviors when movement targets are lost * Apply suggestions from code review Comment formatting Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/ai/ai_controller.dm Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/ai/ai_controller.dm Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> * Apply suggestions from code review Comment formatting Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/datums/ai/ai_controller.dm Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> --------- Signed-off-by: warriorstar-orion <orion@snowfrost.garden> Signed-off-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
This commit is contained in:
co-authored by
DGamerL
PollardTheDragon
Burzah
parent
9e87289bd8
commit
be48d7598f
@@ -7,59 +7,54 @@ SUBSYSTEM_DEF(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/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(),
|
||||
AI_STATUS_IDLE = 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()
|
||||
/// Type of status we are interested in running
|
||||
var/planning_status = AI_STATUS_ON
|
||||
/// The tick cost of all active AI, calculated on fire.
|
||||
var/cost_on
|
||||
/// The tick cost of all idle AI, calculated on fire.
|
||||
var/cost_idle
|
||||
|
||||
var/our_cost
|
||||
/// The tick cost of all currently processed AI, being summed together
|
||||
var/summing_cost
|
||||
|
||||
/datum/controller/subsystem/ai_controllers/Initialize()
|
||||
setup_subtrees()
|
||||
|
||||
/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]
|
||||
var/list/idle_list = ai_controllers_by_status[AI_STATUS_IDLE]
|
||||
msg = "Active AIs:[length(active_list)]/[round(cost_on,1)]%|Inactive:[length(inactive_list)]|Idle:[length(idle_list)]/[round(cost_idle,1)]%"
|
||||
var/list/planning_list = GLOB.ai_controllers_by_status[planning_status]
|
||||
msg = "Planning AIs:[length(planning_list)]/[round(our_cost,1)]%"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ai_controllers/fire(resumed)
|
||||
if(!resumed)
|
||||
summing_cost = 0
|
||||
var/timer = TICK_USAGE_REAL
|
||||
cost_idle = MC_AVERAGE(cost_idle, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
|
||||
timer = TICK_USAGE_REAL
|
||||
for(var/datum/ai_controller/ai_controller as anything in ai_controllers_by_status[AI_STATUS_ON])
|
||||
if(!ai_controller.able_to_plan())
|
||||
for(var/datum/ai_controller/ai_controller as anything in GLOB.ai_controllers_by_status[planning_status])
|
||||
if(!ai_controller.able_to_plan)
|
||||
continue
|
||||
ai_controller.select_behaviors(wait / (1 SECONDS))
|
||||
if(!LAZYLEN(ai_controller.current_behaviors)) //Still no plan
|
||||
ai_controller.select_behaviors(wait * 0.1)
|
||||
|
||||
if(!length(ai_controller.current_behaviors)) // Still no plan
|
||||
ai_controller.planning_failed()
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
cost_on = MC_AVERAGE(cost_on, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
summing_cost += TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
///Creates all instances of ai_subtrees and assigns them to the ai_subtrees list.
|
||||
our_cost = MC_AVERAGE(our_cost, summing_cost)
|
||||
|
||||
/// Creates all instances of ai_subtrees and assigns them to the ai_subtrees list.
|
||||
/datum/controller/subsystem/ai_controllers/proc/setup_subtrees()
|
||||
if(length(GLOB.ai_subtrees))
|
||||
return
|
||||
for(var/subtree_type in subtypesof(/datum/ai_planning_subtree))
|
||||
var/datum/ai_planning_subtree/subtree = new subtree_type
|
||||
ai_subtrees[subtree_type] = subtree
|
||||
GLOB.ai_subtrees[subtree_type] = subtree
|
||||
|
||||
///Called when the max Z level was changed, updating our coverage.
|
||||
/// 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()
|
||||
if(!length(GLOB.ai_controllers_by_zlevel))
|
||||
GLOB.ai_controllers_by_zlevel = new /list(world.maxz,0)
|
||||
while(GLOB.ai_controllers_by_zlevel.len < world.maxz)
|
||||
GLOB.ai_controllers_by_zlevel.len++
|
||||
GLOB.ai_controllers_by_zlevel[GLOB.ai_controllers_by_zlevel.len] = list()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
UNPLANNED_CONTROLLER_SUBSYSTEM_DEF(idle_unplanned_controllers)
|
||||
name = "Unplanned AI Idle Controllers"
|
||||
wait = 2.5 SECONDS
|
||||
target_status = AI_STATUS_IDLE
|
||||
@@ -0,0 +1,34 @@
|
||||
GLOBAL_LIST_EMPTY(unplanned_controller_subsystems)
|
||||
/// Handles making mobs perform lightweight "idle" behaviors such as wandering around when they have nothing planned
|
||||
SUBSYSTEM_DEF(unplanned_controllers)
|
||||
name = "AI Unplanned Controllers"
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_UNPLANNED_NPC
|
||||
wait = 0.25 SECONDS
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
/// What ai status are we interested in
|
||||
var/target_status = AI_STATUS_ON
|
||||
var/list/current_run = list()
|
||||
|
||||
/datum/controller/subsystem/unplanned_controllers/Initialize()
|
||||
GLOB.unplanned_controller_subsystems += src
|
||||
|
||||
/datum/controller/subsystem/unplanned_controllers/Destroy()
|
||||
GLOB.unplanned_controller_subsystems -= src
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/unplanned_controllers/stat_entry(msg)
|
||||
msg = "Planning AIs:[length(GLOB.unplanned_controllers[target_status])]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/unplanned_controllers/fire(resumed)
|
||||
if(!resumed)
|
||||
src.current_run = GLOB.unplanned_controllers[target_status].Copy()
|
||||
var/list/current_run = src.current_run // cache for sonic speed
|
||||
while(length(current_run))
|
||||
var/datum/ai_controller/unplanned = current_run[current_run.len]
|
||||
current_run.len--
|
||||
if(!QDELETED(unplanned))
|
||||
unplanned.idle_behavior.perform_idle_behavior(wait * 0.1, unplanned)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
@@ -0,0 +1,8 @@
|
||||
AI_CONTROLLER_SUBSYSTEM_DEF(ai_idle_controllers)
|
||||
name = "AI Idle Controllers"
|
||||
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND
|
||||
priority = FIRE_PRIORITY_IDLE_NPC
|
||||
init_order = INIT_ORDER_AI_IDLE_CONTROLLERS
|
||||
wait = 5 SECONDS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
planning_status = AI_STATUS_IDLE
|
||||
@@ -0,0 +1,6 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(idle_ai_behaviors)
|
||||
name = "AI Idle Behaviors"
|
||||
flags = SS_NO_INIT | SS_BACKGROUND
|
||||
wait = 1.5 SECONDS
|
||||
priority = FIRE_PRIORITY_IDLE_NPC
|
||||
init_order = INIT_ORDER_AI_IDLE_CONTROLLERS // must execute only after ai behaviors are initialized
|
||||
Reference in New Issue
Block a user