mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-27 06:54:18 +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:
@@ -33,7 +33,6 @@
|
||||
// Normal
|
||||
#define SS_PRIORITY_TICKER 100 // Gameticker.
|
||||
//#define FIRE_PRIORITY_DEFAULT 50 // This is defined somewhere else.
|
||||
#define SS_PRIORITY_MOB 40 // Mob Life().
|
||||
#define SS_PRIORITY_AIR 40 // ZAS processing.
|
||||
#define SS_PRIORITY_STATPANELS 25 // Statpanels.
|
||||
#define SS_PRIORITY_LIGHTING 25 // Queued lighting engine updates.
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
#define INIT_ORDER_SOUNDS 83
|
||||
#define INIT_ORDER_DISCORD 78
|
||||
#define INIT_ORDER_JOBS 65 // Must init before atoms, to set up properly the dynamic job lists.
|
||||
#define INIT_ORDER_AI_CONTROLLERS 55 //So the controller can get the ref
|
||||
#define INIT_ORDER_TICKER 55
|
||||
#define INIT_ORDER_SEEDS 52 // More aurora snowflake, needs to load before the atoms init as it generates images for seeds that are used
|
||||
#define INIT_ORDER_MISC_FIRST 51 //Another aurora snowflake system? Who would have guessed... Anyways, need to load before mapping or global HUDs are not ready when atoms request them
|
||||
@@ -252,11 +253,14 @@
|
||||
#define FIRE_PRIORITY_PING 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_ASSETS 20
|
||||
#define FIRE_PRIORITY_NPC_MOVEMENT 21
|
||||
#define FIRE_PRIORITY_NPC_ACTIONS 22
|
||||
#define FIRE_PRIORITY_PATHFINDING 23
|
||||
#define FIRE_PRIORITY_PROCESS 25
|
||||
#define FIRE_PRIORITY_THROWING 25
|
||||
#define FIRE_PRIORITY_SPACEDRIFT 30
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_STATPANEL 390
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_RUNECHAT 410
|
||||
@@ -273,6 +277,10 @@
|
||||
*/
|
||||
#define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__)
|
||||
|
||||
// Subsystem delta times or tickrates, in seconds. I.e, how many seconds in between each process() call for objects being processed by that subsystem.
|
||||
// Only use these defines if you want to access some other objects processing seconds_per_tick, otherwise use the seconds_per_tick that is sent as a parameter to process()
|
||||
#define SSMOBS_DT (SSmobs.wait/10)
|
||||
|
||||
/* AURORA SHIT */
|
||||
|
||||
// Don't display in processes panel.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -110,7 +110,9 @@ the HUD updates properly! */
|
||||
// if(get_dist(H, T) <= client?.view)
|
||||
// viewed += H
|
||||
// return viewed
|
||||
return get_hearers_in_range(client?.view, T)
|
||||
|
||||
//Some virtual eyes eg. the AI eye doesn't have a client but an owner, select it as preferred if so, otherwise use the mob's client itself
|
||||
return get_hearers_in_range((src.owner ? src.owner.client?.view : src.client?.view), T)
|
||||
|
||||
/proc/get_sec_hud_icon(var/mob/living/carbon/human/H)//This function is called from human/life,dm, ~line 1663
|
||||
var/state
|
||||
|
||||
@@ -542,7 +542,7 @@
|
||||
damtype = DAMAGE_BURN
|
||||
w_class = ITEMSIZE_LARGE
|
||||
welding = TRUE
|
||||
hitsound = SOUNDS_LASER_MEAT
|
||||
hitsound = pick(SOUNDS_LASER_MEAT)
|
||||
attack_verb = list("scorched", "burned", "blasted", "blazed")
|
||||
update_icon()
|
||||
set_processing(TRUE)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/mob/living/heavy_vehicle/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/heavy_vehicle/Life()
|
||||
/mob/living/heavy_vehicle/Life(seconds_per_tick, times_fired)
|
||||
|
||||
// Size offsets for large mechs.
|
||||
if(offset_x && pixel_x != offset_x)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/abstract/eye/Life()
|
||||
/mob/abstract/eye/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
// If we lost our client, reset the list of visible chunks so they update properly on return
|
||||
if(owner == src && !client)
|
||||
|
||||
@@ -145,7 +145,7 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
|
||||
Works together with spawning an observer, noted above.
|
||||
*/
|
||||
|
||||
/mob/abstract/observer/Life()
|
||||
/mob/abstract/observer/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(!loc) return
|
||||
if(!client) return 0
|
||||
|
||||
@@ -59,7 +59,8 @@
|
||||
src.voice_name = initial(voice_name)
|
||||
src.accent = initial(accent)
|
||||
|
||||
/mob/living/announcer/Life()
|
||||
/mob/living/announcer/Life(seconds_per_tick, times_fired)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
return
|
||||
|
||||
/mob/living/announcer/Move()
|
||||
|
||||
@@ -55,15 +55,18 @@
|
||||
if(pAI)
|
||||
. += FONT_SMALL(SPAN_NOTICE("It has a pAI piloting it."))
|
||||
|
||||
/mob/living/bot/Life()
|
||||
/mob/living/bot/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(health <= 0)
|
||||
death()
|
||||
return
|
||||
return FALSE
|
||||
|
||||
weakened = 0
|
||||
stunned = 0
|
||||
paralysis = 0
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/movement_delay()
|
||||
return 3
|
||||
|
||||
|
||||
@@ -144,8 +144,10 @@ GLOBAL_LIST_INIT_TYPED(cleanbot_types, /obj/effect/decal/cleanable, typesof(/obj
|
||||
/mob/living/bot/cleanbot/proc/remove_from_ignore(datum/weakref/thing_to_unignore)
|
||||
ignorelist -= thing_to_unignore
|
||||
|
||||
/mob/living/bot/cleanbot/Life()
|
||||
..()
|
||||
/mob/living/bot/cleanbot/Life(seconds_per_tick, times_fired)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
if(!on)
|
||||
ignorelist = list()
|
||||
return
|
||||
@@ -173,6 +175,8 @@ GLOBAL_LIST_INIT_TYPED(cleanbot_types, /obj/effect/decal/cleanable, typesof(/obj
|
||||
ignorelist += gib
|
||||
addtimer(CALLBACK(src, PROC_REF(remove_from_ignore), gib), 600)
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/cleanbot/think()
|
||||
if(pAI) // no AI if we have a pAI installed
|
||||
return
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
else
|
||||
icon_state = "farmbot[on]"
|
||||
|
||||
/mob/living/bot/farmbot/Life()
|
||||
/mob/living/bot/farmbot/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(emagged && prob(1))
|
||||
flick("farmbot_broke", src)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
diona_handle_radiation(DS)
|
||||
|
||||
|
||||
/mob/living/carbon/alien/diona/Life()
|
||||
/mob/living/carbon/alien/diona/Life(seconds_per_tick, times_fired)
|
||||
if(!detached && gestalt && (gestalt.life_tick % 5 == 0)) // Minimal processing while in stasis
|
||||
updatehealth()
|
||||
check_status_as_organ()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Alien larva are quite simple.
|
||||
/mob/living/carbon/alien/Life()
|
||||
/mob/living/carbon/alien/Life(seconds_per_tick, times_fired)
|
||||
if (transforming) return
|
||||
if(!loc) return
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
if(species && species.indefinite_sleep)
|
||||
add_verb(src, /verb/toggle_indefinite_sleep)
|
||||
|
||||
/mob/living/carbon/Life()
|
||||
/mob/living/carbon/Life(seconds_per_tick, times_fired)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
var/pressure_alert = 0
|
||||
var/temperature_alert = 0
|
||||
|
||||
/mob/living/carbon/human/Life()
|
||||
/mob/living/carbon/human/Life(seconds_per_tick, times_fired)
|
||||
if (transforming)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/slime/Life()
|
||||
/mob/living/carbon/slime/Life(seconds_per_tick, times_fired)
|
||||
if(src.transforming)
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/mob/living/Life()
|
||||
/mob/living/Life(seconds_per_tick, times_fired)
|
||||
if (QDELETED(src)) // If they're being deleted, why bother?
|
||||
return
|
||||
return FALSE
|
||||
|
||||
..()
|
||||
|
||||
if (transforming)
|
||||
return
|
||||
if(transforming)
|
||||
return FALSE
|
||||
|
||||
if(!loc)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
var/datum/gas_mixture/gas_environment = loc.return_air()
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
@@ -32,7 +32,7 @@
|
||||
update_pulling()
|
||||
|
||||
for(var/obj/item/grab/G in src)
|
||||
G.process()
|
||||
INVOKE_ASYNC(G, TYPE_PROC_REF(/datum, process))
|
||||
|
||||
handle_actions()
|
||||
|
||||
|
||||
@@ -1,129 +1,69 @@
|
||||
/mob/living/silicon/ai/Life()
|
||||
/mob/living/silicon/ai/Life(seconds_per_tick, times_fired)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
if (src.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
if (src.stat!=CONSCIOUS)
|
||||
src.cameraFollow = null
|
||||
src.reset_view(null)
|
||||
|
||||
src.updatehealth()
|
||||
|
||||
if (hardware_integrity() <= 0 || backup_capacitor() <= 0)
|
||||
death()
|
||||
return
|
||||
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
//Being dead doesn't mean your temperature never changes
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if (src.stat!=CONSCIOUS)
|
||||
src.cameraFollow = null
|
||||
src.reset_view(null)
|
||||
// If our powersupply object was destroyed somehow, create new one.
|
||||
if(!psupply)
|
||||
create_powersupply()
|
||||
|
||||
src.updatehealth()
|
||||
|
||||
if (hardware_integrity() <= 0 || backup_capacitor() <= 0)
|
||||
death()
|
||||
// Handle power damage (oxy)
|
||||
if(ai_restore_power_routine != 0 && !APU_power)
|
||||
// Lose power
|
||||
adjustOxyLoss(1)
|
||||
else
|
||||
// Gain Power
|
||||
ai_restore_power_routine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
|
||||
adjustOxyLoss(-1)
|
||||
|
||||
handle_stunned() // Handle EMP-stun
|
||||
lying = 0 // Handle lying down
|
||||
|
||||
malf_process()
|
||||
|
||||
if(APU_power && (hardware_integrity() < 50))
|
||||
to_chat(src, SPAN_NOTICE("<b>APU GENERATOR FAILURE! (System Damaged)</b>"))
|
||||
stop_apu(1)
|
||||
|
||||
if (!is_blind())
|
||||
if (ai_restore_power_routine==2)
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else if (ai_restore_power_routine==3)
|
||||
to_chat(src, "Alert cancelled. Power has been restored.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else if (APU_power)
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
var/area/current_area = get_area(src)
|
||||
|
||||
// If our powersupply object was destroyed somehow, create new one.
|
||||
if(!psupply)
|
||||
create_powersupply()
|
||||
if(lacks_power())
|
||||
if(ai_restore_power_routine==0)
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_power_loss), current_area)
|
||||
|
||||
|
||||
// Handle power damage (oxy)
|
||||
if(ai_restore_power_routine != 0 && !APU_power)
|
||||
// Lose power
|
||||
adjustOxyLoss(1)
|
||||
else
|
||||
// Gain Power
|
||||
ai_restore_power_routine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
|
||||
adjustOxyLoss(-1)
|
||||
|
||||
handle_stunned() // Handle EMP-stun
|
||||
lying = 0 // Handle lying down
|
||||
|
||||
malf_process()
|
||||
|
||||
if(APU_power && (hardware_integrity() < 50))
|
||||
to_chat(src, SPAN_NOTICE("<b>APU GENERATOR FAILURE! (System Damaged)</b>"))
|
||||
stop_apu(1)
|
||||
|
||||
if (!is_blind())
|
||||
if (ai_restore_power_routine==2)
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else if (ai_restore_power_routine==3)
|
||||
to_chat(src, "Alert cancelled. Power has been restored.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else if (APU_power)
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
var/area/current_area = get_area(src)
|
||||
|
||||
if (lacks_power())
|
||||
if (ai_restore_power_routine==0)
|
||||
ai_restore_power_routine = 1
|
||||
|
||||
//Now to tell the AI why they're blind and dying slowly.
|
||||
to_chat(src, "You've lost power!")
|
||||
|
||||
spawn(20)
|
||||
to_chat(src, "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection.")
|
||||
sleep(50)
|
||||
if (current_area.power_equip)
|
||||
if (!istype(T, /turf/space))
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
return
|
||||
to_chat(src, "Fault confirmed: missing external power. Shutting down main control system to save power.")
|
||||
sleep(20)
|
||||
to_chat(src, "Emergency control system online. Verifying connection to power network.")
|
||||
sleep(50)
|
||||
if (istype(T, /turf/space))
|
||||
to_chat(src, "Unable to verify! No power connection detected!")
|
||||
ai_restore_power_routine = 2
|
||||
return
|
||||
to_chat(src, "Connection verified. Searching for APC in power network.")
|
||||
sleep(50)
|
||||
var/obj/machinery/power/apc/theAPC = null
|
||||
|
||||
var/PRP
|
||||
for (PRP=1, PRP<=4, PRP++)
|
||||
for (var/obj/machinery/power/apc/APC in current_area)
|
||||
if (!(APC.stat & BROKEN))
|
||||
theAPC = APC
|
||||
break
|
||||
if (!theAPC)
|
||||
switch(PRP)
|
||||
if (1) to_chat(src, "Unable to locate APC!")
|
||||
else to_chat(src, "Lost connection with the APC!")
|
||||
src:ai_restore_power_routine = 2
|
||||
return
|
||||
if (current_area.power_equip)
|
||||
if (!istype(T, /turf/space))
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
return
|
||||
switch(PRP)
|
||||
if (1) to_chat(src, "APC located. Optimizing route to APC to avoid needless power waste.")
|
||||
if (2) to_chat(src, "Best route identified. Hacking offline APC power port.")
|
||||
if (3) to_chat(src, "Power port upload access confirmed. Loading control program into APC power port software.")
|
||||
if (4)
|
||||
to_chat(src, "Transfer complete. Forcing APC to execute program.")
|
||||
sleep(50)
|
||||
to_chat(src, "Receiving control information from APC.")
|
||||
sleep(2)
|
||||
theAPC.operating = 1
|
||||
theAPC.equipment = 3
|
||||
theAPC.update()
|
||||
ai_restore_power_routine = 3
|
||||
to_chat(src, "Here are your current laws:")
|
||||
show_laws()
|
||||
update_icon()
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
handle_regular_hud_updates()
|
||||
switch(src.sensor_mode)
|
||||
@@ -132,6 +72,80 @@
|
||||
if (MED_HUD)
|
||||
process_med_hud(src,0,src.eyeobj)
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Handles the power loss for the AI
|
||||
*
|
||||
* Broken up from the Life() proc so it can be done async, I claim no part in the creation of this abhorrent mess
|
||||
* apart from copying the code from the aforementioned proc
|
||||
*/
|
||||
/mob/living/silicon/ai/proc/handle_power_loss(area/current_area)
|
||||
ai_restore_power_routine = 1
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
//Now to tell the AI why they're blind and dying slowly.
|
||||
to_chat(src, "You've lost power!")
|
||||
|
||||
spawn(20)
|
||||
to_chat(src, "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection.")
|
||||
sleep(50)
|
||||
if (current_area.power_equip)
|
||||
if (!istype(T, /turf/space))
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
return
|
||||
to_chat(src, "Fault confirmed: missing external power. Shutting down main control system to save power.")
|
||||
sleep(20)
|
||||
to_chat(src, "Emergency control system online. Verifying connection to power network.")
|
||||
sleep(50)
|
||||
if (istype(T, /turf/space))
|
||||
to_chat(src, "Unable to verify! No power connection detected!")
|
||||
ai_restore_power_routine = 2
|
||||
return
|
||||
to_chat(src, "Connection verified. Searching for APC in power network.")
|
||||
sleep(50)
|
||||
var/obj/machinery/power/apc/theAPC = null
|
||||
|
||||
var/PRP
|
||||
for (PRP=1, PRP<=4, PRP++)
|
||||
for (var/obj/machinery/power/apc/APC in current_area)
|
||||
if (!(APC.stat & BROKEN))
|
||||
theAPC = APC
|
||||
break
|
||||
if (!theAPC)
|
||||
switch(PRP)
|
||||
if (1) to_chat(src, "Unable to locate APC!")
|
||||
else to_chat(src, "Lost connection with the APC!")
|
||||
src:ai_restore_power_routine = 2
|
||||
return
|
||||
if (current_area.power_equip)
|
||||
if (!istype(T, /turf/space))
|
||||
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
|
||||
ai_restore_power_routine = 0
|
||||
clear_fullscreen("blind")
|
||||
return
|
||||
switch(PRP)
|
||||
if (1) to_chat(src, "APC located. Optimizing route to APC to avoid needless power waste.")
|
||||
if (2) to_chat(src, "Best route identified. Hacking offline APC power port.")
|
||||
if (3) to_chat(src, "Power port upload access confirmed. Loading control program into APC power port software.")
|
||||
if (4)
|
||||
to_chat(src, "Transfer complete. Forcing APC to execute program.")
|
||||
sleep(50)
|
||||
to_chat(src, "Receiving control information from APC.")
|
||||
sleep(2)
|
||||
theAPC.operating = 1
|
||||
theAPC.equipment = 3
|
||||
theAPC.update()
|
||||
ai_restore_power_routine = 3
|
||||
to_chat(src, "Here are your current laws:")
|
||||
show_laws()
|
||||
update_icon()
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
/mob/living/silicon/ai/proc/lacks_power()
|
||||
if(APU_power)
|
||||
return 0
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
/mob/living/silicon/decoy/Life()
|
||||
if (src.stat == 2)
|
||||
return
|
||||
/mob/living/silicon/decoy/Life(seconds_per_tick, times_fired)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
if (src.stat == DEAD)
|
||||
return FALSE
|
||||
else
|
||||
if (src.health <= GLOB.config.health_threshold_dead && src.stat != 2)
|
||||
if (src.health <= GLOB.config.health_threshold_dead && src.stat != DEAD)
|
||||
death()
|
||||
return
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/silicon/decoy/updatehealth()
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/mob/living/silicon/pai/Life()
|
||||
/mob/living/silicon/pai/Life(seconds_per_tick, times_fired)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
if (src.stat == 2)
|
||||
return
|
||||
if(src.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
if(src.cable)
|
||||
if(get_dist(src, src.cable) > 1)
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message(SPAN_WARNING("The data cable rapidly retracts back into its spool."), 3, SPAN_WARNING("You hear a click and the sound of wire spooling rapidly."), 2)
|
||||
qdel(src.cable)
|
||||
src.cable = null
|
||||
QDEL_NULL(src.cable)
|
||||
|
||||
handle_regular_hud_updates()
|
||||
|
||||
if(src.secHUD == 1)
|
||||
process_sec_hud(src, 1)
|
||||
if(src.secHUD)
|
||||
process_sec_hud(src, TRUE)
|
||||
|
||||
if(src.medHUD == 1)
|
||||
process_med_hud(src, 1)
|
||||
if(src.medHUD)
|
||||
process_med_hud(src, TRUE)
|
||||
|
||||
if(silence_time)
|
||||
if(world.timeofday >= silence_time)
|
||||
@@ -29,6 +29,8 @@
|
||||
if(health <= 0)
|
||||
death(null,"gives one shrill beep before falling lifeless.")
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/pai/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
health = maxHealth
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/mob/living/silicon/robot/Life()
|
||||
/mob/living/silicon/robot/Life(seconds_per_tick, times_fired)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
if(transforming)
|
||||
return
|
||||
|
||||
@@ -27,6 +29,8 @@
|
||||
process_level_restrictions()
|
||||
update_canmove()
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/robot/proc/clamp_values()
|
||||
SetParalysis(min(paralysis, 30))
|
||||
sleeping = FALSE
|
||||
@@ -318,7 +322,7 @@
|
||||
if(istype(get_area(src), /area/centcom) || istype(get_area(src), /area/shuttle/escape) || istype(get_area(src), /area/shuttle/arrival))
|
||||
return FALSE
|
||||
if(!self_destructing)
|
||||
start_self_destruct(TRUE)
|
||||
INVOKE_ASYNC(src, PROC_REF(start_self_destruct), TRUE)
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/robot/update_fire()
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
icon_state = "[icon_state]"
|
||||
return ..()//Proceed as normal.
|
||||
|
||||
/mob/living/simple_animal/aquatic/Life()
|
||||
/mob/living/simple_animal/aquatic/Life(seconds_per_tick, times_fired)
|
||||
var/turf/T = get_turf(src)
|
||||
if (!(is_type_in_list(T,suitable_turf_types)))
|
||||
alpha = 255//Becomes a solid color because it is revealed
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bee/Life()
|
||||
/mob/living/simple_animal/bee/Life(seconds_per_tick, times_fired)
|
||||
if(!loner && strength && !parent && prob(7-strength))
|
||||
strength -= 1
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
/mob/living/simple_animal/borer/can_name(var/mob/living/M)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/borer/Life()
|
||||
/mob/living/simple_animal/borer/Life(seconds_per_tick, times_fired)
|
||||
if(host)
|
||||
if(!stat && host.stat != DEAD)
|
||||
if(chemicals < 250)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
QDEL_NULL(resist_bar)
|
||||
return ..()
|
||||
|
||||
/mob/living/captive_brain/Life()
|
||||
/mob/living/captive_brain/Life(seconds_per_tick, times_fired)
|
||||
if(resist_bar)
|
||||
resist_bar.update(world.time - resist_start_time)
|
||||
return ..()
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
AddOverlays(glow)
|
||||
set_light(2, -2, l_color = COLOR_WHITE)
|
||||
|
||||
/mob/living/simple_animal/construct/Life()
|
||||
/mob/living/simple_animal/construct/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/newstate
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/ice_tunneler/Life()
|
||||
/mob/living/simple_animal/ice_tunneler/Life(seconds_per_tick, times_fired)
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
.=..()
|
||||
set_stat(DEAD)
|
||||
|
||||
/mob/living/simple_animal/cat/Life()
|
||||
/mob/living/simple_animal/cat/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
handle_radiation_light()
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
butchering_products = list(/obj/item/stack/material/animalhide = 3)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Life()
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(locate(/obj/effect/plant) in loc)
|
||||
@@ -182,7 +182,7 @@
|
||||
pixel_x = rand(-6, 6)
|
||||
pixel_y = rand(0, 10)
|
||||
|
||||
/mob/living/simple_animal/chick/Life()
|
||||
/mob/living/simple_animal/chick/Life(seconds_per_tick, times_fired)
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -271,7 +271,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/chicken/Life()
|
||||
/mob/living/simple_animal/chicken/Life(seconds_per_tick, times_fired)
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
. = ..()
|
||||
nutrition = rand(max_nutrition*0.25, max_nutrition*0.75)
|
||||
|
||||
/mob/living/simple_animal/lizard/Life()
|
||||
/mob/living/simple_animal/lizard/Life(seconds_per_tick, times_fired)
|
||||
if (!..())
|
||||
if ((world.time - timeofdeath) > decompose_time)
|
||||
dust()
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
kitchen_tag = "rodent"
|
||||
|
||||
/mob/living/simple_animal/rat/Life()
|
||||
/mob/living/simple_animal/rat/Life(seconds_per_tick, times_fired)
|
||||
if(..())
|
||||
|
||||
if(client)
|
||||
|
||||
@@ -80,6 +80,6 @@
|
||||
/mob/living/simple_animal/hostile/scarybat/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/cult/Life()
|
||||
/mob/living/simple_animal/hostile/scarybat/cult/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
check_horde()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
..()
|
||||
anchored = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/cavern_geist/Life()
|
||||
/mob/living/simple_animal/hostile/cavern_geist/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
adjustBruteLoss(-5)
|
||||
|
||||
|
||||
@@ -64,11 +64,14 @@
|
||||
mind.assigned_role = "Changeling"
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/true_changeling/Life()
|
||||
/mob/living/simple_animal/hostile/true_changeling/Life(seconds_per_tick, times_fired)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
if(prob(10))
|
||||
custom_emote(VISIBLE_MESSAGE, pick( list("shrieks!","roars!", "screeches!", "snarls!", "bellows!", "screams!") ) )
|
||||
var/sound = pick(loud_sounds)
|
||||
playsound(src, sound, 90, 1, 15, pressure_affected = 0)
|
||||
playsound(src, sound, 90, TRUE, 15, pressure_affected = FALSE)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/true_changeling/death(gibbed)
|
||||
|
||||
@@ -37,6 +37,6 @@
|
||||
/mob/living/simple_animal/hostile/creature/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/creature/cult/Life()
|
||||
/mob/living/simple_animal/hostile/creature/cult/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
check_horde()
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/mob/living/simple_animal/hostile/faithless/cult/cultify()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/cult/Life()
|
||||
/mob/living/simple_animal/hostile/faithless/cult/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
check_horde()
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
var/playable = TRUE
|
||||
sample_data = list("Genetic markers identified as being linked with stem cell differentiaton", "Cellular structures indicative of high offspring production", "Tissue sample contains high neural cell content")
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/servant/Life()
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/servant/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
adjustBruteLoss(-2)
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebotbeacon/Life()
|
||||
/mob/living/simple_animal/hostile/hivebotbeacon/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(wander)
|
||||
wander = 0
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
return TRUE
|
||||
|
||||
//self repair systems have a chance to bring the drone back to life
|
||||
/mob/living/simple_animal/hostile/icarus_drone/Life()
|
||||
/mob/living/simple_animal/hostile/icarus_drone/Life(seconds_per_tick, times_fired)
|
||||
//emps and lots of damage can temporarily shut us down
|
||||
if(disabled > 0)
|
||||
set_stat(UNCONSCIOUS)
|
||||
|
||||
@@ -51,8 +51,9 @@
|
||||
..()
|
||||
anchored = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/biglizard/Life()
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/biglizard/Life(seconds_per_tick, times_fired)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
//It's a predator, supposedly it shouldn't always alert his victims to be nearby
|
||||
//(also saves some processing)
|
||||
@@ -80,7 +81,9 @@
|
||||
poor_soul_approaching.notify_message(message, 10 SECONDS, key = "biglizard-[REF(src)]")
|
||||
|
||||
|
||||
adjustBruteLoss(-1)
|
||||
adjustBruteLoss(-0.5 * seconds_per_tick)
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/biglizard/verb/devour(mob/living/target as mob in oview())
|
||||
set category = "Plains Tyrant"
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
for(var/spell in morph_spells)
|
||||
add_spell(new spell, "const_spell_ready")
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/Life()
|
||||
/mob/living/simple_animal/hostile/morph/Life(seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
if(stat == DEAD && healths)
|
||||
healths.icon_state = "health6"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
icon_state = "[icon_state]"
|
||||
return ..()//Proceed as normal.
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/aquatic/Life()
|
||||
/mob/living/simple_animal/hostile/retaliate/aquatic/Life(seconds_per_tick, times_fired)
|
||||
var/turf/T = get_turf(src)
|
||||
if (!(is_type_in_list(T,suitable_turf_types)))
|
||||
alpha = 255//Becomes a solid color because it is revealed
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
O.forceMove(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/minedrone/Life()
|
||||
/mob/living/simple_animal/hostile/retaliate/minedrone/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(ore_count<20)
|
||||
FindOre()
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
sarlacc = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/greatworm/Life()
|
||||
/mob/living/simple_animal/hostile/greatworm/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
if(!sarlacc)
|
||||
var/obj/item/trap/sarlacc/L = new /obj/item/trap/sarlacc(src.loc)
|
||||
|
||||
@@ -125,6 +125,6 @@
|
||||
M.apply_effect(6, STUN)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/spider_queen/Life()
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/spider_queen/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
adjustBruteLoss(-3)
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
to_chat(src, SPAN_DANGER("You feel yourself begin to fade away!"))
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/shade/bluespace/Life()
|
||||
/mob/living/simple_animal/shade/bluespace/Life(seconds_per_tick, times_fired)
|
||||
if(possessive && possessed_body)
|
||||
update_possession()
|
||||
..()
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
/mob/living/simple_animal/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
life_tick++
|
||||
if (stat == DEAD)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
var/atom/currentlyEating //what the worm is currently eating
|
||||
var/eatingDuration = 0 //how long he's been eating it for
|
||||
|
||||
/mob/living/simple_animal/space_worm/Life()
|
||||
/mob/living/simple_animal/space_worm/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
|
||||
if(next && !(next in view(src,1)))
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/space_worm/Destroy() //if a chunk a destroyed, make a new worm out of the split halves
|
||||
if(previous)
|
||||
|
||||
+15
-1
@@ -279,11 +279,25 @@
|
||||
if(P.buckled || locate(/mob) in P.contents)
|
||||
. += P.slowdown
|
||||
|
||||
/mob/proc/Life()
|
||||
/**
|
||||
* Handles the biological and general over-time processes of the mob.
|
||||
*
|
||||
*
|
||||
* Arguments:
|
||||
* - seconds_per_tick: The amount of time that has elapsed since this last fired
|
||||
* - times_fired: The number of times SSmobs has fired
|
||||
*/
|
||||
/mob/proc/Life(seconds_per_tick = SSMOBS_DT, times_fired)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
if(LAZYLEN(spell_masters))
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
spell_master.update_spells(0, src)
|
||||
|
||||
if(stat != DEAD)
|
||||
return TRUE
|
||||
|
||||
/mob/proc/buckled_to()
|
||||
// Preliminary work for a future buckle rewrite,
|
||||
// where one might be fully restrained (like an elecrical chair), or merely secured (shuttle chair, keeping you safe but not otherwise restrained from acting)
|
||||
|
||||
@@ -157,9 +157,12 @@
|
||||
A.losebreath = max(A.losebreath + 3, 5)
|
||||
A.adjustOxyLoss(3)
|
||||
if(affecting.stat == CONSCIOUS)
|
||||
state = GRAB_UPGRADING
|
||||
if(do_mob(assailant, affecting, 150))
|
||||
A.visible_message(SPAN_WARNING("[A] falls unconscious..."), FONT_LARGE(SPAN_DANGER("The world goes dark as you fall unconscious...")))
|
||||
A.Paralyse(20)
|
||||
if(state == GRAB_UPGRADING)
|
||||
state = GRAB_KILL
|
||||
else if(istype(affecting, /mob/living/simple_animal))
|
||||
if(affecting.stat != DEAD)
|
||||
affecting.health -= 1
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
else
|
||||
to_chat(src, SPAN_WARNING("You've already released concentration. Wait to wake up naturally."))
|
||||
|
||||
/mob/living/brain_ghost/Life()
|
||||
/mob/living/brain_ghost/Life(seconds_per_tick, times_fired)
|
||||
..()
|
||||
// Out body was probs gibbed or somefin
|
||||
if(!istype(body))
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# - (fixes bugs)
|
||||
# wip
|
||||
# - (work in progress)
|
||||
# qol
|
||||
# - (quality of life)
|
||||
# soundadd
|
||||
# - (adds a sound)
|
||||
# sounddel
|
||||
# - (removes a sound)
|
||||
# rscadd
|
||||
# - (adds a feature)
|
||||
# rscdel
|
||||
# - (removes a feature)
|
||||
# imageadd
|
||||
# - (adds an image or sprite)
|
||||
# imagedel
|
||||
# - (removes an image or sprite)
|
||||
# spellcheck
|
||||
# - (fixes spelling or grammar)
|
||||
# experiment
|
||||
# - (experimental change)
|
||||
# balance
|
||||
# - (balance changes)
|
||||
# code_imp
|
||||
# - (misc internal code change)
|
||||
# refactor
|
||||
# - (refactors code)
|
||||
# config
|
||||
# - (makes a change to the config files)
|
||||
# admin
|
||||
# - (makes changes to administrator tools)
|
||||
# server
|
||||
# - (miscellaneous changes to server)
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: FluffyGhost
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
|
||||
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- refactor: "Refactored Life() to receive seconds per tick and times fired as parameters."
|
||||
- refactor: "Life() now cannot be slept in, turned various sleepings into async calls procs."
|
||||
- code_imp: "Optimized mob AI subsystems, gave them new priorities levels and flags."
|
||||
- code_imp: "Grab upgrades are now elaborated asynchronously, tweaked them to avoid stacking multiple upgrades."
|
||||
- bugfix: "Fixed plains tyrants keeping sending messages about stomping even if dead."
|
||||
Reference in New Issue
Block a user