Merge pull request #4430 from Citadel-Station-13/upstream-merge-33574

[MIRROR] Advanced mob laziness
This commit is contained in:
LetterJay
2018-01-02 04:52:38 -06:00
committed by GitHub
6 changed files with 65 additions and 9 deletions
+1
View File
@@ -108,6 +108,7 @@
#define AI_ON 1
#define AI_IDLE 2
#define AI_OFF 3
#define AI_Z_OFF 4
//determines if a mob can smash through it
#define ENVIRONMENT_SMASH_NONE 0
+1 -1
View File
@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subt
GLOBAL_LIST_EMPTY(ai_list)
GLOBAL_LIST_EMPTY(pai_list)
GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
+12 -2
View File
@@ -1,15 +1,21 @@
SUBSYSTEM_DEF(idlenpcpool)
name = "Idling NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
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()
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
..("IdleNPCS:[idlelist.len]")
var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
/datum/controller/subsystem/idlenpcpool/Initialize(start_timeofday)
idle_mobs_by_zlevel = new /list(world.maxz,0)
return ..()
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
@@ -24,6 +30,9 @@ SUBSYSTEM_DEF(idlenpcpool)
while(currentrun.len)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
if (!SA)
GLOB.simple_animals[AI_IDLE] -= SA
continue
if(!SA.ckey)
if(SA.stat != DEAD)
@@ -32,3 +41,4 @@ SUBSYSTEM_DEF(idlenpcpool)
SA.consider_wakeup()
if (MC_TICK_CHECK)
return
+7
View File
@@ -1058,6 +1058,13 @@
if (client)
if (new_z)
SSmobs.clients_by_zlevel[new_z] += src
for (var/I in length(SSidlenpcpool.idle_mobs_by_zlevel[new_z]) to 1 step -1) //Backwards loop because we're removing (guarantees optimal rather than worst-case performance), it's fine to use .len here but doesn't compile on 511
var/mob/living/simple_animal/SA = SSidlenpcpool.idle_mobs_by_zlevel[new_z][I]
if (SA)
SA.toggle_ai(AI_ON) // Guarantees responsiveness for when appearing right next to mobs
else
SSidlenpcpool.idle_mobs_by_zlevel[new_z] -= SA
registered_z = new_z
else
registered_z = null
@@ -289,7 +289,7 @@
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
target = null
LoseSearchObjects()
if(AIStatus == AI_IDLE)
if(AIStatus != AI_ON && AIStatus != AI_OFF)
toggle_ai(AI_ON)
FindTarget()
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
@@ -480,6 +480,31 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
/mob/living/simple_animal/hostile/consider_wakeup()
..()
if(AIStatus == AI_IDLE && FindTarget(ListTargets(), 1))
var/list/tlist
var/turf/T = get_turf(src)
if (!T)
return
if (!length(SSmobs.clients_by_zlevel[T.z])) // It's fine to use .len here but doesn't compile on 511
toggle_ai(AI_Z_OFF)
return
if (isturf(T) && !(T.z in GLOB.station_z_levels))
tlist = ListTargetsLazy(T.z)
else
tlist = ListTargets()
if(AIStatus == AI_IDLE && FindTarget(tlist, 1))
toggle_ai(AI_ON)
/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
. = list()
for (var/I in SSmobs.clients_by_zlevel[_Z])
var/mob/M = I
if (get_dist(M, src) < vision_range)
if (isturf(M.loc))
. += M
else if (M.loc.type in hostile_machines)
. += M.loc
@@ -82,14 +82,14 @@
var/dextrous_hud_type = /datum/hud/dextrous
var/datum/personal_crafting/handcrafting
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
//domestication
var/tame = 0
no_vore = TRUE
var/my_z // I don't want to confuse this with client registered_z
/mob/living/simple_animal/Initialize()
. = ..()
@@ -544,7 +544,13 @@
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 4)
if (togglestatus > 0 && togglestatus < 5)
if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
var/turf/T = get_turf(src)
if (AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
else
SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src
GLOB.simple_animals[AIStatus] -= src
GLOB.simple_animals[togglestatus] += src
AIStatus = togglestatus
@@ -559,4 +565,11 @@
. = ..()
if(!ckey && !stat)//Not unconscious
if(AIStatus == AI_IDLE)
toggle_ai(AI_ON)
toggle_ai(AI_ON)
/mob/living/simple_animal/onTransitZ(old_z, new_z)
..()
if (AIStatus == AI_Z_OFF)
SSidlenpcpool[old_z] -= src
toggle_ai(initial(AIStatus))