mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Replaces GoonPS scheduled_tasks and obj processing with SMC processing subsystems and timer
This commit is contained in:
@@ -20,7 +20,7 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS
|
||||
gases.Cut() // Do not qdel the gases, we don't own them
|
||||
return ..()
|
||||
|
||||
proc/process()
|
||||
process()
|
||||
//Equalize gases amongst pipe if called for
|
||||
if(update)
|
||||
update = 0
|
||||
@@ -75,7 +75,7 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS
|
||||
|
||||
for(var/datum/pipeline/line_member in line_members)
|
||||
gases += line_member.air
|
||||
|
||||
|
||||
for(var/datum/gas_mixture/air in gases)
|
||||
volume += air.volume
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ datum/pipeline
|
||||
edges = null
|
||||
. = ..()
|
||||
|
||||
proc/process()//This use to be called called from the pipe networks
|
||||
process()//This use to be called called from the pipe networks
|
||||
|
||||
//Check to see if pressure is within acceptable limits
|
||||
var/pressure = air.return_pressure()
|
||||
|
||||
@@ -1,15 +1,81 @@
|
||||
#define MC_TICK_CHECK ( ( TICK_USAGE > GLOB.CURRENT_TICKLIMIT || src.state != SS_RUNNING ) ? pause() : 0 )
|
||||
|
||||
// Used for splitting up your remaining time into phases, if you want to evenly divide it.
|
||||
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = GLOB.CURRENT_TICKLIMIT; var/split_tick_phases = ##phase_count
|
||||
#define MC_TICK_CHECK ( ( TICK_USAGE > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
|
||||
|
||||
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
|
||||
#define MC_SPLIT_TICK \
|
||||
if(split_tick_phases > 1){\
|
||||
GLOB.CURRENT_TICKLIMIT = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\
|
||||
--split_tick_phases;\
|
||||
} else {\
|
||||
GLOB.CURRENT_TICKLIMIT = original_tick_limit;\
|
||||
}
|
||||
if(split_tick_phases > 1){\
|
||||
Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\
|
||||
--split_tick_phases;\
|
||||
} else {\
|
||||
Master.current_ticklimit = original_tick_limit;\
|
||||
}
|
||||
|
||||
// Used to smooth out costs to try and avoid oscillation.
|
||||
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
|
||||
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
|
||||
#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current))
|
||||
|
||||
#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.is_processing) {Datum.is_processing = TRUE;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.is_processing = FALSE;Processor.processing -= Datum
|
||||
|
||||
//! SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
/// subsystem does not initialize.
|
||||
#define SS_NO_INIT 1
|
||||
|
||||
/** subsystem does not fire. */
|
||||
/// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
||||
/// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE 2
|
||||
|
||||
/** subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) */
|
||||
/// SS_BACKGROUND has its own priority bracket
|
||||
#define SS_BACKGROUND 4
|
||||
|
||||
/// subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK 8
|
||||
|
||||
/** Treat wait as a tick count, not DS, run every wait ticks. */
|
||||
/// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
||||
/// (implies all runlevels because of how it works)
|
||||
/// (overrides SS_BACKGROUND)
|
||||
/// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER 16
|
||||
|
||||
/** keep the subsystem's timing on point by firing early if it fired late last fire because of lag */
|
||||
/// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
||||
#define SS_KEEP_TIMING 32
|
||||
|
||||
/** Calculate its next fire after its fired. */
|
||||
/// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
||||
/// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING 64
|
||||
|
||||
//! SUBSYSTEM STATES
|
||||
#define SS_IDLE 0 /// aint doing shit.
|
||||
#define SS_QUEUED 1 /// queued to run
|
||||
#define SS_RUNNING 2 /// actively running
|
||||
#define SS_PAUSED 3 /// paused by mc_tick_check
|
||||
#define SS_SLEEPING 4 /// fire() slept.
|
||||
#define SS_PAUSING 5 /// in the middle of pausing
|
||||
|
||||
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
}\
|
||||
/datum/controller/subsystem/##X
|
||||
|
||||
#define PROCESSING_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/processing/##X);\
|
||||
/datum/controller/subsystem/processing/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
}\
|
||||
/datum/controller/subsystem/processing/##X
|
||||
|
||||
// Boilerplate code for multi-step processors. See machines.dm for example use.
|
||||
#define INTERNAL_PROCESS_STEP(this_step, initial_step, proc_to_call, cost_var, next_step)\
|
||||
@@ -23,71 +89,3 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st
|
||||
resumed = 0;\
|
||||
current_step = next_step;\
|
||||
}
|
||||
|
||||
// Used to smooth out costs to try and avoid oscillation.
|
||||
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
|
||||
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
|
||||
#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current))
|
||||
|
||||
#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = 0;Processor.processing -= Datum
|
||||
|
||||
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
//subsystem does not initialize.
|
||||
#define SS_NO_INIT 1
|
||||
|
||||
//subsystem does not fire.
|
||||
// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
||||
// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE 2
|
||||
|
||||
//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick)
|
||||
// SS_BACKGROUND has its own priority bracket
|
||||
#define SS_BACKGROUND 4
|
||||
|
||||
//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK 8
|
||||
|
||||
//Treat wait as a tick count, not DS, run every wait ticks.
|
||||
// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
||||
// (implies all runlevels because of how it works)
|
||||
// (overrides SS_BACKGROUND)
|
||||
// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER 16
|
||||
|
||||
//keep the subsystem's timing on point by firing early if it fired late last fire because of lag
|
||||
// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
||||
#define SS_KEEP_TIMING 32
|
||||
|
||||
//Calculate its next fire after its fired.
|
||||
// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
||||
// This flag overrides SS_KEEP_TIMING
|
||||
#define SS_POST_FIRE_TIMING 64
|
||||
|
||||
//SUBSYSTEM STATES
|
||||
#define SS_IDLE 0 //aint doing shit.
|
||||
#define SS_QUEUED 1 //queued to run
|
||||
#define SS_RUNNING 2 //actively running
|
||||
#define SS_PAUSED 3 //paused by mc_tick_check
|
||||
#define SS_SLEEPING 4 //fire() slept.
|
||||
#define SS_PAUSING 5 //in the middle of pausing
|
||||
|
||||
// Standard way to define a global subsystem, keep boilerplate organized here!
|
||||
#define SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/##X);\
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
}\
|
||||
/datum/controller/subsystem/##X
|
||||
#define PROCESSING_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/processing/##X);\
|
||||
/datum/controller/subsystem/processing/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
}\
|
||||
/datum/controller/subsystem/processing/##X
|
||||
54
code/__defines/_lists.dm
Normal file
54
code/__defines/_lists.dm
Normal file
@@ -0,0 +1,54 @@
|
||||
// Helper macros to aid in optimizing lazy instantiation of lists.
|
||||
// All of these are null-safe, you can use them without knowing if the list var is initialized yet
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
// Ensures L is initailized after this point
|
||||
#define LAZYINITLIST(L) if (!L) L = list()
|
||||
// Sets a L back to null iff it is empty
|
||||
#define UNSETEMPTY(L) if (L && !length(L)) L = null
|
||||
// Removes I from list L, and sets I to null if it is now empty
|
||||
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } }
|
||||
// Adds I to L, initalizing I if necessary
|
||||
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
|
||||
#define LAZYOR(L, I) if(!L) { L = list(); } L |= I;
|
||||
#define LAZYFIND(L, V) L ? L.Find(V) : 0
|
||||
// Reads I from L safely - Works with both associative and traditional lists.
|
||||
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null)
|
||||
// Turns LAZYINITLIST(L) L[K] = V into ... for associated lists
|
||||
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
|
||||
// Reads the length of L, returning 0 if null
|
||||
#define LAZYLEN(L) length(L)
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression.
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
#define reverseList(L) reverseRange(L.Copy())
|
||||
|
||||
// binary search sorted insert
|
||||
// IN: Object to be inserted
|
||||
// LIST: List to insert object into
|
||||
// TYPECONT: The typepath of the contents of the list
|
||||
// COMPARE: The variable on the objects to compare
|
||||
#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \
|
||||
var/__BIN_CTTL = length(LIST);\
|
||||
if(!__BIN_CTTL) {\
|
||||
LIST += IN;\
|
||||
} else {\
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var/##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\
|
||||
__BIN_LEFT = __BIN_MID + 1;\
|
||||
} else {\
|
||||
__BIN_RIGHT = __BIN_MID;\
|
||||
};\
|
||||
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
};\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
__BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\
|
||||
LIST.Insert(__BIN_MID, IN);\
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
#define TICK_LIMIT_MC 70
|
||||
#define TICK_LIMIT_MC_INIT_DEFAULT 98
|
||||
|
||||
#define TICK_CHECK ( TICK_USAGE > GLOB.CURRENT_TICKLIMIT )
|
||||
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
|
||||
#define CHECK_TICK if TICK_CHECK stoplag()
|
||||
|
||||
#define TICK_USAGE world.tick_usage
|
||||
|
||||
6
code/__defines/flags.dm
Normal file
6
code/__defines/flags.dm
Normal file
@@ -0,0 +1,6 @@
|
||||
#define ALL (~0)
|
||||
#define NONE 0
|
||||
|
||||
// datum_flags
|
||||
#define DF_VAR_EDITED (1<<0)
|
||||
#define DF_ISPROCESSING (1<<1)
|
||||
@@ -22,7 +22,13 @@
|
||||
#define QDELETED(X) (!X || X.gc_destroyed)
|
||||
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
|
||||
//Qdel helper macros.
|
||||
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
|
||||
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
|
||||
#define QDEL_NULL(item) qdel(item); item = null
|
||||
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
|
||||
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
|
||||
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
|
||||
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
|
||||
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }
|
||||
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
//Timing subsystem
|
||||
//Don't run if there is an identical unique timer active
|
||||
#define TIMER_UNIQUE 0x1
|
||||
//if the arguments to addtimer are the same as an existing timer, it doesn't create a new timer, and returns the id of the existing timer
|
||||
#define TIMER_UNIQUE (1<<0)
|
||||
//For unique timers: Replace the old timer rather then not start this one
|
||||
#define TIMER_OVERRIDE 0x2
|
||||
#define TIMER_OVERRIDE (1<<1)
|
||||
//Timing should be based on how timing progresses on clients, not the sever.
|
||||
// tracking this is more expensive,
|
||||
// should only be used in conjuction with things that have to progress client side, such as animate() or sound()
|
||||
#define TIMER_CLIENT_TIME 0x4
|
||||
#define TIMER_CLIENT_TIME (1<<2)
|
||||
//Timer can be stopped using deltimer()
|
||||
#define TIMER_STOPPABLE 0x8
|
||||
#define TIMER_STOPPABLE (1<<3)
|
||||
//To be used with TIMER_UNIQUE
|
||||
//prevents distinguishing identical timers with the wait variable
|
||||
#define TIMER_NO_HASH_WAIT 0x10
|
||||
#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something
|
||||
#define TIMER_NO_HASH_WAIT (1<<4)
|
||||
//Loops the timer repeatedly until qdeleted
|
||||
//In most cases you want a subsystem instead
|
||||
#define TIMER_LOOP (1<<5)
|
||||
|
||||
#define TIMER_ID_NULL -1
|
||||
|
||||
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
|
||||
@@ -47,6 +52,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
<<<<<<< HEAD
|
||||
#define INIT_ORDER_MAPPING 20 // VOREStation Edit
|
||||
#define INIT_ORDER_DECALS 16
|
||||
#define INIT_ORDER_ATOMS 15
|
||||
@@ -72,6 +78,8 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_AIRFLOW 30
|
||||
#define FIRE_PRIORITY_AIR 35
|
||||
#define FIRE_PRIORITY_OBJ 40
|
||||
#define FIRE_PRIORITY_PROCESS 45
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
#define FIRE_PRIORITY_PLANETS 75
|
||||
#define FIRE_PRIORITY_MACHINES 100
|
||||
|
||||
@@ -250,7 +250,7 @@ proc/listclearnulls(list/list)
|
||||
else
|
||||
L[key] = temp[key]
|
||||
|
||||
|
||||
|
||||
//Mergesort: divides up the list into halves to begin the sort
|
||||
/proc/sortKey(var/list/client/L, var/order = 1)
|
||||
if(isnull(L) || L.len < 2)
|
||||
|
||||
@@ -42,3 +42,6 @@
|
||||
. = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME]
|
||||
if (!.)
|
||||
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
|
||||
|
||||
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
|
||||
return a.timeToRun - b.timeToRun
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#define TICK *world.tick_lag
|
||||
#define TICKS *world.tick_lag
|
||||
|
||||
#define DS2TICKS(DS) (DS/world.tick_lag) // Convert deciseconds to ticks
|
||||
#define TICKS2DS(T) (T TICKS) // Convert ticks to deciseconds
|
||||
#define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks
|
||||
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
@@ -140,7 +140,7 @@ var/round_start_time = 0
|
||||
. += CEILING(i*DELTA_CALC, 1)
|
||||
sleep(i*world.tick_lag*DELTA_CALC)
|
||||
i *= 2
|
||||
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, GLOB.CURRENT_TICKLIMIT))
|
||||
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
|
||||
|
||||
#undef DELTA_CALC
|
||||
|
||||
|
||||
@@ -65,32 +65,4 @@
|
||||
|
||||
#define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE)
|
||||
|
||||
#define QDEL_NULL_LIST(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
|
||||
|
||||
#define QDEL_NULL(x) if(x) { qdel(x) ; x = null }
|
||||
|
||||
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
|
||||
|
||||
// Helper macros to aid in optimizing lazy instantiation of lists.
|
||||
// All of these are null-safe, you can use them without knowing if the list var is initialized yet
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
// Ensures L is initailized after this point
|
||||
#define LAZYINITLIST(L) if (!L) L = list()
|
||||
// Sets a L back to null iff it is empty
|
||||
#define UNSETEMPTY(L) if (L && !L.len) L = null
|
||||
// Removes I from list L, and sets I to null if it is now empty
|
||||
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
|
||||
// Adds I to L, initalizing I if necessary
|
||||
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
|
||||
// Reads I from L safely - Works with both associative and traditional lists.
|
||||
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
|
||||
// Reads the length of L, returning 0 if null
|
||||
#define LAZYLEN(L) length(L)
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression.
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
// Turns LAZYINITLIST(L) L[K] = V into ... for associated lists
|
||||
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
/datum/controller/process/proc/setup()
|
||||
|
||||
/datum/controller/process/proc/process()
|
||||
/datum/controller/process/process()
|
||||
started()
|
||||
doWork()
|
||||
finished()
|
||||
|
||||
@@ -70,7 +70,7 @@ var/global/datum/controller/processScheduler/processScheduler
|
||||
spawn(0)
|
||||
process()
|
||||
|
||||
/datum/controller/processScheduler/proc/process()
|
||||
/datum/controller/processScheduler/process()
|
||||
while(isRunning)
|
||||
checkRunningProcesses()
|
||||
queueProcesses()
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/datum/controller/process/obj/setup()
|
||||
name = "obj"
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
start_delay = 8
|
||||
|
||||
/datum/controller/process/obj/started()
|
||||
..()
|
||||
if(!processing_objects)
|
||||
processing_objects = list()
|
||||
|
||||
/datum/controller/process/obj/doWork()
|
||||
for(last_object in processing_objects)
|
||||
var/datum/O = last_object
|
||||
if(!QDELETED(O))
|
||||
try
|
||||
O:process()
|
||||
catch(var/exception/e)
|
||||
catchException(e, O)
|
||||
SCHECK
|
||||
else
|
||||
catchBadType(O)
|
||||
processing_objects -= O
|
||||
|
||||
/datum/controller/process/obj/statProcess()
|
||||
..()
|
||||
stat(null, "[processing_objects.len] objects")
|
||||
@@ -65,7 +65,7 @@ var/datum/controller/supply/supply_controller = new()
|
||||
|
||||
// Supply shuttle ticker - handles supply point regeneration
|
||||
// This is called by the process scheduler every thirty seconds
|
||||
/datum/controller/supply/proc/process()
|
||||
/datum/controller/supply/process()
|
||||
points += points_per_process
|
||||
|
||||
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
|
||||
|
||||
@@ -7,14 +7,18 @@ datum/controller/transfer_controller
|
||||
var/shift_last_vote = 0 //VOREStation Edit
|
||||
datum/controller/transfer_controller/New()
|
||||
timerbuffer = config.vote_autotransfer_initial
|
||||
<<<<<<< HEAD
|
||||
shift_hard_end = config.vote_autotransfer_initial + (config.vote_autotransfer_interval * 1) //VOREStation Edit //Change this "1" to how many extend votes you want there to be.
|
||||
shift_last_vote = shift_hard_end - config.vote_autotransfer_interval //VOREStation Edit
|
||||
processing_objects += src
|
||||
=======
|
||||
START_PROCESSING(SSobj, src)
|
||||
>>>>>>> 2c4b5af... Merge pull request #5677 from kevinz000/PS_PORT_SCHEDULER
|
||||
|
||||
datum/controller/transfer_controller/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
datum/controller/transfer_controller/proc/process()
|
||||
datum/controller/transfer_controller/process()
|
||||
currenttick = currenttick + 1
|
||||
//VOREStation Edit START
|
||||
if (round_duration_in_ticks >= shift_last_vote - 2 MINUTES)
|
||||
|
||||
@@ -26,7 +26,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
escape_pods = list()
|
||||
..()
|
||||
|
||||
/datum/emergency_shuttle_controller/proc/process()
|
||||
/datum/emergency_shuttle_controller/process()
|
||||
if (wait_for_launch)
|
||||
if (evac && auto_recall && world.time >= auto_recall_time)
|
||||
recall()
|
||||
|
||||
@@ -13,14 +13,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
//THIS IS THE INIT ORDER
|
||||
//Master -> SSPreInit -> GLOB -> world -> config -> SSInit -> Failsafe
|
||||
//GOT IT MEMORIZED?
|
||||
GLOBAL_VAR_INIT(MC_restart_clear, 0)
|
||||
GLOBAL_VAR_INIT(MC_restart_timeout, 0)
|
||||
GLOBAL_VAR_INIT(MC_restart_count, 0)
|
||||
|
||||
//current tick limit, assigned by the queue controller before running a subsystem.
|
||||
//used by check_tick as well so that the procs subsystems call can obey that SS's tick limits
|
||||
GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
|
||||
/datum/controller/master
|
||||
name = "Master"
|
||||
@@ -62,6 +54,10 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
var/static/restart_timeout = 0
|
||||
var/static/restart_count = 0
|
||||
|
||||
//current tick limit, assigned by the queue controller before running a subsystem.
|
||||
//used by check_tick as well so that the procs subsystems call can obey that SS's tick limits
|
||||
var/static/current_ticklimit
|
||||
|
||||
/datum/controller/master/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
var/list/_subsystems = list()
|
||||
@@ -98,14 +94,14 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// -1 if we encountered a runtime trying to recreate it
|
||||
/proc/Recreate_MC()
|
||||
. = -1 //so if we runtime, things know we failed
|
||||
if (world.time < GLOB.MC_restart_timeout)
|
||||
if (world.time < Master.restart_timeout)
|
||||
return 0
|
||||
if (world.time < GLOB.MC_restart_clear)
|
||||
GLOB.MC_restart_count *= 0.5
|
||||
if (world.time < Master.restart_clear)
|
||||
Master.restart_count *= 0.5
|
||||
|
||||
var/delay = 50 * ++GLOB.MC_restart_count
|
||||
GLOB.MC_restart_timeout = world.time + delay
|
||||
GLOB.MC_restart_clear = world.time + (delay * 2)
|
||||
var/delay = 50 * ++Master.restart_count
|
||||
Master.restart_timeout = world.time + delay
|
||||
Master.restart_clear = world.time + (delay * 2)
|
||||
Master.processing = FALSE //stop ticking this one
|
||||
try
|
||||
new/datum/controller/master()
|
||||
@@ -176,13 +172,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
var/start_timeofday = REALTIMEOFDAY
|
||||
// Initialize subsystems.
|
||||
GLOB.CURRENT_TICKLIMIT = config.tick_limit_mc_init
|
||||
current_ticklimit = config.tick_limit_mc_init
|
||||
for (var/datum/controller/subsystem/SS in subsystems)
|
||||
if (SS.flags & SS_NO_INIT)
|
||||
continue
|
||||
SS.Initialize(REALTIMEOFDAY)
|
||||
CHECK_TICK
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
|
||||
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
@@ -291,7 +287,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
|
||||
var/starting_tick_usage = TICK_USAGE
|
||||
if (processing <= 0)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
@@ -300,7 +296,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// (because sleeps are processed in the order received, longer sleeps are more likely to run first)
|
||||
if (starting_tick_usage > TICK_LIMIT_MC) //if there isn't enough time to bother doing anything this tick, sleep a bit.
|
||||
sleep_delta *= 2
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5
|
||||
current_ticklimit = TICK_LIMIT_RUNNING * 0.5
|
||||
sleep(world.tick_lag * (processing * sleep_delta))
|
||||
continue
|
||||
|
||||
@@ -346,7 +342,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
if (!error_level)
|
||||
iteration++
|
||||
error_level++
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
@@ -358,7 +354,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
if (!error_level)
|
||||
iteration++
|
||||
error_level++
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
error_level--
|
||||
@@ -369,9 +365,9 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
iteration++
|
||||
last_run = world.time
|
||||
src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
if (processing * sleep_delta <= world.tick_lag)
|
||||
GLOB.CURRENT_TICKLIMIT -= (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc if we plan on running next tick
|
||||
current_ticklimit -= (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc if we plan on running next tick
|
||||
sleep(world.tick_lag * (processing * sleep_delta))
|
||||
|
||||
|
||||
@@ -463,7 +459,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// Reduce tick allocation for subsystems that overran on their last tick.
|
||||
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun)
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = round(TICK_USAGE + tick_precentage)
|
||||
current_ticklimit = round(TICK_USAGE + tick_precentage)
|
||||
|
||||
if (!(queue_node_flags & SS_TICKER))
|
||||
ran_non_ticker = TRUE
|
||||
|
||||
6
code/controllers/subsystems/processing/fastprocess.dm
Normal file
6
code/controllers/subsystems/processing/fastprocess.dm
Normal file
@@ -0,0 +1,6 @@
|
||||
//Fires five times every second.
|
||||
|
||||
PROCESSING_SUBSYSTEM_DEF(fastprocess)
|
||||
name = "Fast Processing"
|
||||
wait = 2
|
||||
stat_tag = "FP"
|
||||
5
code/controllers/subsystems/processing/obj.dm
Normal file
5
code/controllers/subsystems/processing/obj.dm
Normal file
@@ -0,0 +1,5 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(obj)
|
||||
name = "Objects"
|
||||
priority = FIRE_PRIORITY_OBJ
|
||||
flags = SS_NO_INIT
|
||||
wait = 20
|
||||
35
code/controllers/subsystems/processing/processing.dm
Normal file
35
code/controllers/subsystems/processing/processing.dm
Normal file
@@ -0,0 +1,35 @@
|
||||
//Used to process objects. Fires once every second.
|
||||
|
||||
SUBSYSTEM_DEF(processing)
|
||||
name = "Processing"
|
||||
priority = FIRE_PRIORITY_PROCESS
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
|
||||
wait = 10
|
||||
|
||||
var/stat_tag = "P" //Used for logging
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/processing/stat_entry()
|
||||
..("[stat_tag]:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/processing/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/current_run = currentrun
|
||||
|
||||
while(current_run.len)
|
||||
var/datum/thing = current_run[current_run.len]
|
||||
current_run.len--
|
||||
if(QDELETED(thing))
|
||||
processing -= thing
|
||||
else if(thing.process(wait) == PROCESS_KILL)
|
||||
// fully stop so that a future START_PROCESSING will work
|
||||
STOP_PROCESSING(src, thing)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/proc/process()
|
||||
set waitfor = 0
|
||||
return PROCESS_KILL
|
||||
37
code/controllers/subsystems/time_track.dm
Normal file
37
code/controllers/subsystems/time_track.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
SUBSYSTEM_DEF(time_track)
|
||||
name = "Time Tracking"
|
||||
wait = 600
|
||||
flags = SS_NO_INIT|SS_NO_TICK_CHECK
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/time_dilation_current = 0
|
||||
|
||||
var/time_dilation_avg_fast = 0
|
||||
var/time_dilation_avg = 0
|
||||
var/time_dilation_avg_slow = 0
|
||||
|
||||
var/first_run = TRUE
|
||||
|
||||
var/last_tick_realtime = 0
|
||||
var/last_tick_byond_time = 0
|
||||
var/last_tick_tickcount = 0
|
||||
|
||||
/datum/controller/subsystem/time_track/fire()
|
||||
|
||||
var/current_realtime = REALTIMEOFDAY
|
||||
var/current_byondtime = world.time
|
||||
var/current_tickcount = world.time/world.tick_lag
|
||||
|
||||
if (!first_run)
|
||||
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
|
||||
|
||||
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
|
||||
|
||||
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
|
||||
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
|
||||
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
|
||||
else
|
||||
first_run = FALSE
|
||||
last_tick_realtime = current_realtime
|
||||
last_tick_byond_time = current_byondtime
|
||||
last_tick_tickcount = current_tickcount
|
||||
522
code/controllers/subsystems/timer.dm
Normal file
522
code/controllers/subsystems/timer.dm
Normal file
@@ -0,0 +1,522 @@
|
||||
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
|
||||
#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN)||BUCKET_LEN)
|
||||
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
|
||||
#define TIMER_ID_MAX (2**24) //max float with integer precision
|
||||
|
||||
SUBSYSTEM_DEF(timer)
|
||||
name = "Timer"
|
||||
wait = 1 //SS_TICKER subsystem, so wait is in ticks
|
||||
init_order = INIT_ORDER_TIMER
|
||||
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue?
|
||||
var/list/hashes = list()
|
||||
|
||||
var/head_offset = 0 //world.time of the first entry in the the bucket.
|
||||
var/practical_offset = 1 //index of the first non-empty item in the bucket.
|
||||
var/bucket_resolution = 0 //world.tick_lag the bucket was designed for
|
||||
var/bucket_count = 0 //how many timers are in the buckets
|
||||
|
||||
var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick.
|
||||
|
||||
var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup)
|
||||
|
||||
var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time"
|
||||
|
||||
var/last_invoke_tick = 0
|
||||
var/static/last_invoke_warning = 0
|
||||
var/static/bucket_auto_reset = TRUE
|
||||
|
||||
/datum/controller/subsystem/timer/PreInit()
|
||||
bucket_list.len = BUCKET_LEN
|
||||
head_offset = world.time
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
/datum/controller/subsystem/timer/stat_entry(msg)
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
var/lit = last_invoke_tick
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5)
|
||||
var/list/bucket_list = src.bucket_list
|
||||
|
||||
if(!bucket_count)
|
||||
last_invoke_tick = world.time
|
||||
|
||||
if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check)
|
||||
last_invoke_warning = world.time
|
||||
var/msg = "No regular timers processed in the last [BUCKET_LEN*1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
|
||||
message_admins(msg)
|
||||
WARNING(msg)
|
||||
if(bucket_auto_reset)
|
||||
bucket_resolution = 0
|
||||
|
||||
log_world("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
for (var/i in 1 to length(bucket_list))
|
||||
var/datum/timedevent/bucket_head = bucket_list[i]
|
||||
if (!bucket_head)
|
||||
continue
|
||||
|
||||
log_world("Active timers at index [i]:")
|
||||
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
var/anti_loop_check = 1000
|
||||
do
|
||||
log_world(get_timer_debug_string(bucket_node))
|
||||
bucket_node = bucket_node.next
|
||||
anti_loop_check--
|
||||
while(bucket_node && bucket_node != bucket_head && anti_loop_check)
|
||||
log_world("Active timers in the second_queue queue:")
|
||||
for(var/I in second_queue)
|
||||
log_world(get_timer_debug_string(I))
|
||||
|
||||
var/cut_start_index = 1
|
||||
var/next_clienttime_timer_index = 0
|
||||
var/len = length(clienttime_timers)
|
||||
|
||||
for (next_clienttime_timer_index in 1 to len)
|
||||
if (MC_TICK_CHECK)
|
||||
next_clienttime_timer_index--
|
||||
break
|
||||
var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index]
|
||||
if (ctime_timer.timeToRun > REALTIMEOFDAY)
|
||||
next_clienttime_timer_index--
|
||||
break
|
||||
|
||||
var/datum/callback/callBack = ctime_timer.callBack
|
||||
if (!callBack)
|
||||
clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1)
|
||||
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
|
||||
|
||||
ctime_timer.spent = REALTIMEOFDAY
|
||||
callBack.InvokeAsync()
|
||||
|
||||
if(ctime_timer.flags & TIMER_LOOP)
|
||||
ctime_timer.spent = 0
|
||||
clienttime_timers.Insert(ctime_timer, 1)
|
||||
cut_start_index++
|
||||
else
|
||||
qdel(ctime_timer)
|
||||
|
||||
|
||||
if (next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1)
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
var/static/list/spent = list()
|
||||
var/static/datum/timedevent/timer
|
||||
if (practical_offset > BUCKET_LEN)
|
||||
head_offset += TICKS2DS(BUCKET_LEN)
|
||||
practical_offset = 1
|
||||
resumed = FALSE
|
||||
|
||||
if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution))
|
||||
reset_buckets()
|
||||
bucket_list = src.bucket_list
|
||||
resumed = FALSE
|
||||
|
||||
|
||||
if (!resumed)
|
||||
timer = null
|
||||
|
||||
while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time)
|
||||
var/datum/timedevent/head = bucket_list[practical_offset]
|
||||
if (!timer || !head || timer == head)
|
||||
head = bucket_list[practical_offset]
|
||||
timer = head
|
||||
while (timer)
|
||||
var/datum/callback/callBack = timer.callBack
|
||||
if (!callBack)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
if (!timer.spent)
|
||||
spent += timer
|
||||
timer.spent = world.time
|
||||
callBack.InvokeAsync()
|
||||
last_invoke_tick = world.time
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
timer = timer.next
|
||||
if (timer == head)
|
||||
break
|
||||
|
||||
|
||||
bucket_list[practical_offset++] = null
|
||||
|
||||
//we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket.
|
||||
var/i = 0
|
||||
var/L = length(second_queue)
|
||||
for (i in 1 to L)
|
||||
timer = second_queue[i]
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
if (timer.timeToRun < head_offset)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
bucket_count++
|
||||
var/bucket_pos = max(1, BUCKET_POS(timer))
|
||||
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
timer.next = null
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
if (i)
|
||||
second_queue.Cut(1, i+1)
|
||||
|
||||
timer = null
|
||||
|
||||
bucket_count -= length(spent)
|
||||
|
||||
for (var/i in spent)
|
||||
var/datum/timedevent/qtimer = i
|
||||
if(QDELETED(qtimer))
|
||||
bucket_count++
|
||||
continue
|
||||
if(!(qtimer.flags & TIMER_LOOP))
|
||||
qdel(qtimer)
|
||||
else
|
||||
bucket_count++
|
||||
qtimer.spent = 0
|
||||
qtimer.bucketEject()
|
||||
if(qtimer.flags & TIMER_CLIENT_TIME)
|
||||
qtimer.timeToRun = REALTIMEOFDAY + qtimer.wait
|
||||
else
|
||||
qtimer.timeToRun = world.time + qtimer.wait
|
||||
qtimer.bucketJoin()
|
||||
|
||||
spent.len = 0
|
||||
|
||||
//formated this way to be runtime resistant
|
||||
/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE)
|
||||
. = "Timer: [TE]"
|
||||
. += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]"
|
||||
if(TE.spent)
|
||||
. += ", SPENT([TE.spent])"
|
||||
if(QDELETED(TE))
|
||||
. += ", QDELETED"
|
||||
if(!TE.callBack)
|
||||
. += ", NO CALLBACK"
|
||||
|
||||
/datum/controller/subsystem/timer/proc/reset_buckets()
|
||||
var/list/bucket_list = src.bucket_list
|
||||
var/list/alltimers = list()
|
||||
//collect the timers currently in the bucket
|
||||
for (var/bucket_head in bucket_list)
|
||||
if (!bucket_head)
|
||||
continue
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
do
|
||||
alltimers += bucket_node
|
||||
bucket_node = bucket_node.next
|
||||
while(bucket_node && bucket_node != bucket_head)
|
||||
|
||||
bucket_list.len = 0
|
||||
bucket_list.len = BUCKET_LEN
|
||||
|
||||
practical_offset = 1
|
||||
bucket_count = 0
|
||||
head_offset = world.time
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
alltimers += second_queue
|
||||
if (!length(alltimers))
|
||||
return
|
||||
|
||||
sortTim(alltimers, .proc/cmp_timer)
|
||||
|
||||
var/datum/timedevent/head = alltimers[1]
|
||||
|
||||
if (head.timeToRun < head_offset)
|
||||
head_offset = head.timeToRun
|
||||
|
||||
var/new_bucket_count
|
||||
var/i = 1
|
||||
for (i in 1 to length(alltimers))
|
||||
var/datum/timedevent/timer = alltimers[1]
|
||||
if (!timer)
|
||||
continue
|
||||
|
||||
var/bucket_pos = BUCKET_POS(timer)
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
|
||||
if (!timer.callBack || timer.spent)
|
||||
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack)
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
new_bucket_count++
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
timer.next = null
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
if (i)
|
||||
alltimers.Cut(1, i+1)
|
||||
second_queue = alltimers
|
||||
bucket_count = new_bucket_count
|
||||
|
||||
|
||||
/datum/controller/subsystem/timer/Recover()
|
||||
second_queue |= SStimer.second_queue
|
||||
hashes |= SStimer.hashes
|
||||
timer_id_dict |= SStimer.timer_id_dict
|
||||
bucket_list |= SStimer.bucket_list
|
||||
|
||||
/datum/timedevent
|
||||
var/id
|
||||
var/datum/callback/callBack
|
||||
var/timeToRun
|
||||
var/wait
|
||||
var/hash
|
||||
var/list/flags
|
||||
var/spent = 0 //time we ran the timer.
|
||||
var/name //for easy debugging.
|
||||
//cicular doublely linked list
|
||||
var/datum/timedevent/next
|
||||
var/datum/timedevent/prev
|
||||
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash)
|
||||
var/static/nextid = 1
|
||||
id = TIMER_ID_NULL
|
||||
src.callBack = callBack
|
||||
src.wait = wait
|
||||
src.flags = flags
|
||||
src.hash = hash
|
||||
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
timeToRun = REALTIMEOFDAY + wait
|
||||
else
|
||||
timeToRun = world.time + wait
|
||||
|
||||
if (flags & TIMER_UNIQUE)
|
||||
SStimer.hashes[hash] = src
|
||||
|
||||
if (flags & TIMER_STOPPABLE)
|
||||
id = num2text(nextid, 100)
|
||||
if (nextid >= SHORT_REAL_LIMIT)
|
||||
nextid += min(1, 2**round(nextid/SHORT_REAL_LIMIT))
|
||||
else
|
||||
nextid++
|
||||
SStimer.timer_id_dict[id] = src
|
||||
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
|
||||
|
||||
if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
|
||||
CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
|
||||
|
||||
if (callBack.object != GLOBAL_PROC && !QDESTROYING(callBack.object))
|
||||
LAZYADD(callBack.object.active_timers, src)
|
||||
|
||||
bucketJoin()
|
||||
|
||||
/datum/timedevent/Destroy()
|
||||
..()
|
||||
if (flags & TIMER_UNIQUE && hash)
|
||||
SStimer.hashes -= hash
|
||||
|
||||
if (callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers)
|
||||
callBack.object.active_timers -= src
|
||||
UNSETEMPTY(callBack.object.active_timers)
|
||||
|
||||
callBack = null
|
||||
|
||||
if (flags & TIMER_STOPPABLE)
|
||||
SStimer.timer_id_dict -= id
|
||||
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
if (!spent)
|
||||
spent = world.time
|
||||
SStimer.clienttime_timers -= src
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
if (!spent)
|
||||
spent = world.time
|
||||
bucketEject()
|
||||
else
|
||||
if (prev && prev.next == src)
|
||||
prev.next = next
|
||||
if (next && next.prev == src)
|
||||
next.prev = prev
|
||||
next = null
|
||||
prev = null
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/datum/timedevent/proc/bucketEject()
|
||||
var/bucketpos = BUCKET_POS(src)
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
var/list/second_queue = SStimer.second_queue
|
||||
var/datum/timedevent/buckethead
|
||||
if(bucketpos > 0)
|
||||
buckethead = bucket_list[bucketpos]
|
||||
if(buckethead == src)
|
||||
bucket_list[bucketpos] = next
|
||||
SStimer.bucket_count--
|
||||
else if(timeToRun < TIMER_MAX || next || prev)
|
||||
SStimer.bucket_count--
|
||||
else
|
||||
var/l = length(second_queue)
|
||||
second_queue -= src
|
||||
if(l == length(second_queue))
|
||||
SStimer.bucket_count--
|
||||
if(prev != next)
|
||||
prev.next = next
|
||||
next.prev = prev
|
||||
else
|
||||
prev?.next = null
|
||||
next?.prev = null
|
||||
prev = next = null
|
||||
|
||||
/datum/timedevent/proc/bucketJoin()
|
||||
var/list/L
|
||||
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
L = SStimer.clienttime_timers
|
||||
else if (timeToRun >= TIMER_MAX)
|
||||
L = SStimer.second_queue
|
||||
|
||||
if(L)
|
||||
BINARY_INSERT(src, L, datum/timedevent, timeToRun)
|
||||
return
|
||||
|
||||
//get the list of buckets
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
|
||||
//calculate our place in the bucket list
|
||||
var/bucket_pos = BUCKET_POS(src)
|
||||
|
||||
//get the bucket for our tick
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
SStimer.bucket_count++
|
||||
//empty bucket, we will just add ourselves
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = src
|
||||
return
|
||||
//other wise, lets do a simplified linked list add.
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
next = bucket_head
|
||||
prev = bucket_head.prev
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
|
||||
/datum/timedevent/proc/getcallingtype()
|
||||
. = "ERROR"
|
||||
if (callBack.object == GLOBAL_PROC)
|
||||
. = "GLOBAL_PROC"
|
||||
else
|
||||
. = "[callBack.object.type]"
|
||||
|
||||
/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
|
||||
if (!callback)
|
||||
CRASH("addtimer called without a callback")
|
||||
|
||||
if (wait < 0)
|
||||
crash_with("addtimer called with a negative wait. Converting to [world.tick_lag]")
|
||||
|
||||
if (callback.object != GLOBAL_PROC && QDELETED(callback.object) && !QDESTROYING(callback.object))
|
||||
crash_with("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not be supported and may refuse to run or run with a 0 wait")
|
||||
|
||||
wait = max(CEILING(wait, world.tick_lag), world.tick_lag)
|
||||
|
||||
if(wait >= INFINITY)
|
||||
CRASH("Attempted to create timer with INFINITY delay")
|
||||
|
||||
var/hash
|
||||
|
||||
if (flags & TIMER_UNIQUE)
|
||||
var/list/hashlist
|
||||
if(flags & TIMER_NO_HASH_WAIT)
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
else
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
hashlist += callback.arguments
|
||||
hash = hashlist.Join("|||||||")
|
||||
|
||||
var/datum/timedevent/hash_timer = SStimer.hashes[hash]
|
||||
if(hash_timer)
|
||||
if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist.
|
||||
hash_timer.hash = null //but keep it from accidentally deleting us
|
||||
else
|
||||
if (flags & TIMER_OVERRIDE)
|
||||
hash_timer.hash = null //no need having it delete it's hash if we are going to replace it
|
||||
qdel(hash_timer)
|
||||
else
|
||||
if (hash_timer.flags & TIMER_STOPPABLE)
|
||||
. = hash_timer.id
|
||||
return
|
||||
else if(flags & TIMER_OVERRIDE)
|
||||
crash_with("TIMER_OVERRIDE used without TIMER_UNIQUE")
|
||||
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash)
|
||||
return timer.id
|
||||
|
||||
/proc/deltimer(id)
|
||||
if (!id)
|
||||
return FALSE
|
||||
if (id == TIMER_ID_NULL)
|
||||
CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag")
|
||||
if (!istext(id))
|
||||
if (istype(id, /datum/timedevent))
|
||||
qdel(id)
|
||||
return TRUE
|
||||
//id is string
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
|
||||
if (timer && !timer.spent)
|
||||
qdel(timer)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
#undef BUCKET_LEN
|
||||
#undef BUCKET_POS
|
||||
#undef TIMER_MAX
|
||||
#undef TIMER_ID_MAX
|
||||
@@ -145,11 +145,11 @@
|
||||
/obj/effect/ebeam/reactive
|
||||
|
||||
/obj/effect/ebeam/reactive/Initialize()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/ebeam/reactive/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/ebeam/reactive/on_drawn()
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
|
||||
/datum
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/list/active_timers //for SStimer
|
||||
var/weakref/weakref // Holder of weakref instance pointing to this datum
|
||||
var/is_processing = FALSE // If this datum is in an MC processing list, this will be set to its name.
|
||||
var/is_processing //If is processing, may or may not have the name of the list it's in.
|
||||
|
||||
#ifdef TESTING
|
||||
var/tmp/running_find_references
|
||||
@@ -17,6 +18,16 @@
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
|
||||
//clear timers
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
|
||||
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
|
||||
tag = null
|
||||
GLOB.nanomanager.close_uis(src)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/*
|
||||
DO NOT USE THIS. THIS IS BEING DEPRECATED BY PROCESSING SUBSYSTEMS (controllers/subsystems/processing) AND TIMERS.
|
||||
*/
|
||||
|
||||
/*
|
||||
README:
|
||||
|
||||
@@ -109,9 +113,6 @@ Data storage vars:
|
||||
CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.")
|
||||
return 1
|
||||
|
||||
proc/process()
|
||||
return
|
||||
|
||||
proc/active()
|
||||
return control_switch
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// Observer Pattern Implementation: Scheduled task triggered
|
||||
// Registration type: /datum/scheduled_task
|
||||
//
|
||||
// Raised when: When a scheduled task reaches its trigger time.
|
||||
//
|
||||
// Arguments that the called proc should expect:
|
||||
// /datum/scheduled_task/task: The task that reached its trigger time.
|
||||
var/decl/observ/task_triggered/task_triggered_event = new()
|
||||
|
||||
/decl/observ/task_triggered
|
||||
name = "Task Triggered"
|
||||
expected_type = /datum/scheduled_task
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/obj/item/weapon/melee/changeling/New(location)
|
||||
..()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(ismob(loc))
|
||||
visible_message("<span class='warning'>A grotesque weapon forms around [loc.name]\'s arm!</span>",
|
||||
"<span class='warning'>Our arm twists and mutates, transforming it into a deadly weapon.</span>",
|
||||
@@ -81,7 +81,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/melee/changeling/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
creator = null
|
||||
..()
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
// No more available directions? Shut down process().
|
||||
if(avail_dirs.len==0)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
// We're checking, reset the timer.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/obj/singularity/narsie/large/exit/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/singularity/narsie/large/exit/update_icon()
|
||||
overlays = 0
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
///process()
|
||||
///Called by the gameticker
|
||||
/datum/game_mode/proc/process()
|
||||
/datum/game_mode/process()
|
||||
// Slow this down a bit so latejoiners have a chance of being antags.
|
||||
process_count++
|
||||
if(process_count >= 10)
|
||||
|
||||
@@ -307,7 +307,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
to_chat(M, "Colony Directorship not forced on anyone.")
|
||||
|
||||
|
||||
proc/process()
|
||||
process()
|
||||
if(current_state != GAME_STATE_PLAYING)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
// Proc: process()
|
||||
// Parameters: None
|
||||
// Description: Processes CPU gain and research progress based on "realtime" calculation.
|
||||
/datum/malf_research/proc/process(var/idle = 0)
|
||||
/datum/malf_research/process(var/idle = 0)
|
||||
if(idle) // No power or running on APU. Do nothing.
|
||||
last_tick = world.time
|
||||
return
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/datum/malf_research_ability/next = null // Next research (if applicable).
|
||||
|
||||
|
||||
/datum/malf_research_ability/proc/process(var/time = 0)
|
||||
/datum/malf_research_ability/process(var/time = 0)
|
||||
invested += time
|
||||
if(invested >= price)
|
||||
unlocked = 1
|
||||
@@ -38,11 +38,11 @@
|
||||
|
||||
/obj/item/weapon/technomancer_core/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/technomancer_core/Destroy()
|
||||
dismiss_all_summons()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
// Add the spell buttons to the HUD.
|
||||
|
||||
@@ -37,12 +37,12 @@
|
||||
wearer = null
|
||||
|
||||
/obj/item/clothing/gloves/regen/New()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/gloves/regen/Destroy()
|
||||
wearer = null
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/regen/process()
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
/obj/item/weapon/spell/aura/New()
|
||||
..()
|
||||
set_light(7, 4, l_color = glow_color)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/spell/aura/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/spell/aura/process()
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
/obj/item/weapon/spell/aura/New()
|
||||
..()
|
||||
set_light(calculate_spell_power(7), calculate_spell_power(4), l_color = glow_color)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
log_and_message_admins("has started casting [src].")
|
||||
|
||||
/obj/item/weapon/spell/aura/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
log_and_message_admins("has stopped maintaining [src].")
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
/obj/item/weapon/spell/energy_siphon/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/spell/energy_siphon/Destroy()
|
||||
stop_siphoning()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/spell/energy_siphon/process()
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
/obj/effect/phase_shift/New()
|
||||
..()
|
||||
set_light(3, 5, l_color = "#FA58F4")
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/phase_shift/Destroy()
|
||||
for(var/atom/movable/AM in contents) //Eject everything out.
|
||||
AM.forceMove(get_turf(src))
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/phase_shift/process()
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
/obj/item/weapon/spell/radiance/New()
|
||||
..()
|
||||
set_light(7, 4, l_color = "#D9D900")
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
log_and_message_admins("has casted [src].")
|
||||
|
||||
/obj/item/weapon/spell/radiance/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
log_and_message_admins("has stopped maintaining [src].")
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -896,7 +896,7 @@ FIRE ALARM
|
||||
alarm()
|
||||
time = 0
|
||||
timing = 0
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
updateDialog()
|
||||
last_process = world.timeofday
|
||||
|
||||
@@ -965,7 +965,7 @@ FIRE ALARM
|
||||
else if(href_list["time"])
|
||||
timing = text2num(href_list["time"])
|
||||
last_process = world.timeofday
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else if(href_list["tp"])
|
||||
var/tp = text2num(href_list["tp"])
|
||||
time += tp
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
kick_viewers()
|
||||
update_icon()
|
||||
update_coverage()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/machinery/camera/bullet_act(var/obj/item/projectile/P)
|
||||
take_damage(P.get_structure_damage())
|
||||
|
||||
@@ -56,11 +56,11 @@
|
||||
|
||||
/obj/item/weapon/card/id/guest/Initialize()
|
||||
. = ..()
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/card/id/guest/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/card/id/guest/process()
|
||||
|
||||
@@ -117,7 +117,7 @@ Programs are a file that can be executed
|
||||
/*
|
||||
The computer object will transfer process() calls to the program.
|
||||
*/
|
||||
/datum/file/program/proc/process()
|
||||
/datum/file/program/process()
|
||||
if(refresh && computer && !computer.stat)
|
||||
computer.updateDialog()
|
||||
update_icon()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return
|
||||
|
||||
/datum/computer/file/embedded_program/proc/process()
|
||||
/datum/computer/file/embedded_program/process()
|
||||
return
|
||||
|
||||
/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line)
|
||||
|
||||
@@ -117,6 +117,8 @@ Class Procs:
|
||||
var/interact_offline = 0 // Can the machine be interacted with while de-powered.
|
||||
var/obj/item/weapon/circuitboard/circuit = null
|
||||
|
||||
var/speed_process = FALSE //If false, SSmachines. If true, SSfastprocess.
|
||||
|
||||
/obj/machinery/New(l, d=0)
|
||||
..(l)
|
||||
if(d)
|
||||
@@ -127,10 +129,16 @@ Class Procs:
|
||||
/obj/machinery/Initialize()
|
||||
. = ..()
|
||||
global.machines += src
|
||||
START_MACHINE_PROCESSING(src)
|
||||
if(!speed_process)
|
||||
START_MACHINE_PROCESSING(src)
|
||||
else
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/machinery/Destroy()
|
||||
STOP_MACHINE_PROCESSING(src)
|
||||
if(!speed_process)
|
||||
STOP_MACHINE_PROCESSING(src)
|
||||
else
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
global.machines -= src
|
||||
if(component_parts)
|
||||
for(var/atom/A in component_parts)
|
||||
@@ -153,8 +161,6 @@ Class Procs:
|
||||
if(!(use_power || idle_power_usage || active_power_usage))
|
||||
return PROCESS_KILL
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/emp_act(severity)
|
||||
if(use_power && stat == 0)
|
||||
use_power(7500/severity)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
process()
|
||||
checkReagents()
|
||||
spawn(120)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
sleep(30)
|
||||
if(metal)
|
||||
var/obj/structure/foamedmetal/M = new(src.loc)
|
||||
|
||||
@@ -33,11 +33,11 @@ var/global/list/image/splatter_cache=list()
|
||||
if(invisibility != 100)
|
||||
invisibility = 100
|
||||
amount = 0
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..(ignore=1)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/New()
|
||||
@@ -53,7 +53,7 @@ var/global/list/image/splatter_cache=list()
|
||||
blood_DNA |= B.blood_DNA.Copy()
|
||||
qdel(B)
|
||||
drytime = world.time + DRYING_TIME * (amount+1)
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/process()
|
||||
if(world.time > drytime)
|
||||
@@ -115,7 +115,7 @@ var/global/list/image/splatter_cache=list()
|
||||
desc = drydesc
|
||||
color = adjust_brightness(color, -50)
|
||||
amount = 0
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/attack_hand(mob/living/carbon/human/user)
|
||||
..()
|
||||
|
||||
@@ -105,7 +105,7 @@ steam.start() -- spawns the effect
|
||||
|
||||
/obj/effect/effect/sparks/Initialize()
|
||||
. = ..()
|
||||
schedule_task_in(5 SECONDS, /proc/qdel, list(src))
|
||||
QDEL_IN(src, 5 SECONDS)
|
||||
|
||||
/obj/effect/effect/sparks/Destroy()
|
||||
var/turf/T = src.loc
|
||||
@@ -263,11 +263,11 @@ steam.start() -- spawns the effect
|
||||
var/strength = 5 // How much damage to do inside each affect()
|
||||
|
||||
/obj/effect/effect/smoke/elemental/Initialize()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/effect/smoke/elemental/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/effect/smoke/elemental/Move()
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// Constantly emites radiation from the tile it's placed on.
|
||||
/obj/effect/map_effect/radiation_emitter
|
||||
name = "radiation emitter"
|
||||
icon_state = "radiation_emitter"
|
||||
var/radiation_power = 30 // Bigger numbers means more radiation.
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/Initialize()
|
||||
processing_objects += src
|
||||
return ..()
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/Destroy()
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/process()
|
||||
radiation_repository.radiate(src, radiation_power)
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/strong
|
||||
// Constantly emites radiation from the tile it's placed on.
|
||||
/obj/effect/map_effect/radiation_emitter
|
||||
name = "radiation emitter"
|
||||
icon_state = "radiation_emitter"
|
||||
var/radiation_power = 30 // Bigger numbers means more radiation.
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/Initialize()
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/process()
|
||||
radiation_repository.radiate(src, radiation_power)
|
||||
|
||||
/obj/effect/map_effect/radiation_emitter/strong
|
||||
radiation_power = 100
|
||||
@@ -86,7 +86,7 @@
|
||||
/obj/effect/spider/eggcluster/Initialize()
|
||||
pixel_x = rand(3,-3)
|
||||
pixel_y = rand(3,-3)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/spider/eggcluster/New(var/location, var/atom/parent)
|
||||
@@ -94,7 +94,7 @@
|
||||
..()
|
||||
|
||||
/obj/effect/spider/eggcluster/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(istype(loc, /obj/item/organ/external))
|
||||
var/obj/item/organ/external/O = loc
|
||||
O.implants -= src
|
||||
@@ -141,7 +141,7 @@
|
||||
/obj/effect/spider/spiderling/New(var/location, var/atom/parent)
|
||||
pixel_x = rand(6,-6)
|
||||
pixel_y = rand(6,-6)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
//50% chance to grow up
|
||||
if(prob(50))
|
||||
amount_grown = 1
|
||||
@@ -149,7 +149,7 @@
|
||||
..()
|
||||
|
||||
/obj/effect/spider/spiderling/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever.
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
// It's really really unlikely for the view range to change. But why not be futureproof anyways?
|
||||
range_alert = world.view
|
||||
range_warning = world.view * 2
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/device/multitool/ai_detector/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/multitool/ai_detector/process()
|
||||
|
||||
@@ -82,7 +82,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
all_communicators += src
|
||||
all_communicators = sortAtom(all_communicators)
|
||||
node = get_exonet_node()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
camera = new(src)
|
||||
camera.name = "[src] #[rand(100,999)]"
|
||||
camera.c_tag = camera.name
|
||||
@@ -324,7 +324,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
|
||||
//Clean up references that might point at us
|
||||
all_communicators -= src
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
listening_objects.Remove(src)
|
||||
QDEL_NULL(camera)
|
||||
QDEL_NULL(exonet)
|
||||
|
||||
@@ -604,7 +604,7 @@
|
||||
/obj/item/weapon/shockpaddles/standalone/Destroy()
|
||||
. = ..()
|
||||
if(fail_counter)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/shockpaddles/standalone/check_charge(var/charge_amt)
|
||||
return 1
|
||||
@@ -617,7 +617,7 @@
|
||||
if(fail_counter > 0)
|
||||
radiation_repository.radiate(src, fail_counter--)
|
||||
else
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/shockpaddles/standalone/emp_act(severity)
|
||||
..()
|
||||
@@ -632,7 +632,7 @@
|
||||
to_chat(loc, "<span class='warning'>\The [src] feel pleasantly warm.</span>")
|
||||
|
||||
if(new_fail && !fail_counter)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
fail_counter = new_fail
|
||||
|
||||
/* From the Bay port, this doesn't seem to have a sprite.
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/item/device/flashlight/New()
|
||||
if(power_use)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
if(cell_type)
|
||||
cell = new cell_type(src)
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/obj/item/device/flashlight/Destroy()
|
||||
if(power_use)
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/flashlight/get_cell()
|
||||
@@ -352,7 +352,7 @@
|
||||
turn_off()
|
||||
if(!fuel)
|
||||
src.icon_state = "[initial(icon_state)]-empty"
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/flashlight/flare/proc/turn_off()
|
||||
on = 0
|
||||
@@ -375,14 +375,14 @@
|
||||
user.visible_message("<span class='notice'>[user] activates the flare.</span>", "<span class='notice'>You pull the cord on the flare, activating it!</span>")
|
||||
src.force = on_damage
|
||||
src.damtype = "fire"
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/flashlight/flare/proc/ignite() //Used for flare launchers.
|
||||
on = !on
|
||||
update_icon()
|
||||
force = on_damage
|
||||
damtype = "fire"
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
//Glowsticks
|
||||
@@ -409,7 +409,7 @@
|
||||
turn_off()
|
||||
if(!fuel)
|
||||
src.icon_state = "[initial(icon_state)]-empty"
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/flashlight/glowstick/proc/turn_off()
|
||||
on = 0
|
||||
@@ -426,7 +426,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
user.visible_message("<span class='notice'>[user] cracks and shakes the glowstick.</span>", "<span class='notice'>You crack and shake the glowstick, turning it on!</span>")
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/flashlight/glowstick/red
|
||||
name = "red glowstick"
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
var/radiation_count = 0
|
||||
|
||||
/obj/item/device/geiger/New()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/geiger/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/geiger/process()
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
if(energy <= max_energy)
|
||||
if(!recharging)
|
||||
recharging = 1
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(energy <= 0)
|
||||
to_chat(user, "<span class='warning'>You've overused the battery of [src], now it needs time to recharge!</span>")
|
||||
recharge_locked = 1
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
var/obj/structure/cable/attached // the attached cable
|
||||
|
||||
/obj/item/device/powersink/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
STOP_PROCESSING_POWER_OBJECT(src)
|
||||
..()
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
return
|
||||
else
|
||||
if (mode == 2)
|
||||
processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
|
||||
STOP_PROCESSING(SSobj, src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
|
||||
STOP_PROCESSING_POWER_OBJECT(src)
|
||||
anchored = 0
|
||||
mode = 0
|
||||
@@ -73,14 +73,14 @@
|
||||
src.visible_message("<span class='notice'>[user] activates [src]!</span>")
|
||||
mode = 2
|
||||
icon_state = "powersink1"
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
START_PROCESSING_POWER_OBJECT(src)
|
||||
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
|
||||
src.visible_message("<span class='notice'>[user] deactivates [src]!</span>")
|
||||
mode = 1
|
||||
set_light(0)
|
||||
icon_state = "powersink0"
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
STOP_PROCESSING_POWER_OBJECT(src)
|
||||
|
||||
/obj/item/device/powersink/pwr_drain()
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/obj/item/device/radio/intercom/New()
|
||||
..()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
circuit = new circuit(src)
|
||||
|
||||
/obj/item/device/radio/intercom/department/medbay/New()
|
||||
@@ -104,7 +104,7 @@
|
||||
internal_channels[num2text(RAID_FREQ)] = list(access_syndicate)
|
||||
|
||||
/obj/item/device/radio/intercom/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/radio/intercom/attack_ai(mob/user as mob)
|
||||
|
||||
@@ -44,7 +44,7 @@ var/global/list/active_radio_jammers = list()
|
||||
/obj/item/device/radio_jammer/proc/turn_off(mob/user)
|
||||
if(user)
|
||||
to_chat(user,"<span class='warning'>\The [src] deactivates.</span>")
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
active_radio_jammers -= src
|
||||
on = FALSE
|
||||
update_icon()
|
||||
@@ -52,7 +52,7 @@ var/global/list/active_radio_jammers = list()
|
||||
/obj/item/device/radio_jammer/proc/turn_on(mob/user)
|
||||
if(user)
|
||||
to_chat(user,"<span class='notice'>\The [src] is now active.</span>")
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
active_radio_jammers += src
|
||||
on = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
toggle(usr)
|
||||
|
||||
/obj/item/device/suit_cooling_unit/New()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
cell = new/obj/item/weapon/cell/high() //comes not with the crappy default power cell - because this is dedicated EVA equipment
|
||||
cell.loc = src
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
/obj/item/device/t_scanner/proc/set_active(var/active)
|
||||
on = active
|
||||
if(on)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
flicker = 0
|
||||
else
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_user_client(null)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
uses = owner.tcrystals
|
||||
else
|
||||
uses = telecrystals
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/uplink/Destroy()
|
||||
world_uplinks -= src
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/uplink/get_item_cost(var/item_type, var/item_cost)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var/obj/effect/spider/spiderling/S = A
|
||||
user.visible_message("<span class='notice'>[user] scoops [S] into \the [src].</span>", "<span class='notice'>You scoop [S] into \the [src].</span>")
|
||||
S.loc = src
|
||||
processing_objects.Remove(S) // No growing inside jars
|
||||
STOP_PROCESSING(SSobj, S) // No growing inside jars
|
||||
contains = 3
|
||||
update_icon()
|
||||
return
|
||||
@@ -59,7 +59,7 @@
|
||||
for(var/obj/effect/spider/spiderling/S in src)
|
||||
S.loc = user.loc
|
||||
user.visible_message("<span class='notice'>[user] releases [S] from \the [src].</span>", "<span class='notice'>You release [S] from \the [src].</span>")
|
||||
processing_objects.Add(S) // They can grow after being let out though
|
||||
START_PROCESSING(SSobj, S) // They can grow after being let out though
|
||||
contains = 0
|
||||
update_icon()
|
||||
return
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
desc = "The top of this twisted chunk of metal is faintly stamped with a five pointed star. 'Property of US Army, Pascal B - 1957'."
|
||||
|
||||
/obj/item/poi/pascalb/New()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/poi/pascalb/process()
|
||||
radiation_repository.radiate(src, 5)
|
||||
|
||||
/obj/item/poi/pascalb/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/oldreactor
|
||||
@@ -37,13 +37,13 @@
|
||||
desc = "This broken hunk of machinery looks extremely dangerous."
|
||||
|
||||
/obj/item/poi/brokenoldreactor/New()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/poi/brokenoldreactor/process()
|
||||
radiation_repository.radiate(src, 25)
|
||||
|
||||
/obj/item/poi/brokenoldreactor/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
lit = TRUE
|
||||
visible_message(flavor_text)
|
||||
set_light(CANDLE_LUM)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/flame/candle/process()
|
||||
if(!lit)
|
||||
|
||||
@@ -67,7 +67,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
item_state = "cigoff"
|
||||
name = "burnt match"
|
||||
desc = "A match. This one has seen better days."
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
//////////////////
|
||||
//FINE SMOKABLES//
|
||||
@@ -177,12 +177,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
T.visible_message(flavor_text)
|
||||
update_icon()
|
||||
set_light(2, 0.25, "#E38F46")
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/mask/smokable/proc/die(var/nomessage = 0)
|
||||
var/turf/T = get_turf(src)
|
||||
set_light(0)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if (type_butt)
|
||||
var/obj/item/butt = new type_butt(T)
|
||||
transfer_fingerprints_to(butt)
|
||||
@@ -215,7 +215,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
/obj/item/clothing/mask/smokable/proc/quench()
|
||||
lit = 0
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/clothing/mask/smokable/attack(mob/living/carbon/human/H, mob/user, def_zone)
|
||||
@@ -541,7 +541,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
user.visible_message("<span class='notice'>After a few attempts, [user] manages to light the [src], they however burn their finger in the process.</span>")
|
||||
|
||||
set_light(2)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
lit = 0
|
||||
icon_state = "[base_state]"
|
||||
@@ -552,7 +552,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
user.visible_message("<span class='notice'>[user] quietly shuts off the [src].</span>")
|
||||
|
||||
set_light(0)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
/obj/item/weapon/flamethrower/process()
|
||||
if(!lit)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return null
|
||||
var/turf/location = loc
|
||||
if(istype(location, /mob/))
|
||||
@@ -144,7 +144,7 @@
|
||||
if(!status) return
|
||||
lit = !lit
|
||||
if(lit)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(href_list["amount"])
|
||||
throw_amount = throw_amount + text2num(href_list["amount"])
|
||||
throw_amount = max(50, min(5000, throw_amount))
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
Destroy()
|
||||
QDEL_NULL(detonator)
|
||||
QDEL_NULL_LIST(beakers)
|
||||
QDEL_LIST_NULL(beakers)
|
||||
return ..()
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
/obj/item/weapon/grenade/supermatter/Destroy()
|
||||
if(implode_at)
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/grenade/supermatter/detonate()
|
||||
..()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
implode_at = world.time + 10 SECONDS
|
||||
update_icon()
|
||||
playsound(src, 'sound/weapons/wave.ogg', 100)
|
||||
|
||||
@@ -110,10 +110,10 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
|
||||
..()
|
||||
|
||||
/obj/item/weapon/implant/tracking/post_implant(var/mob/source)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/implant/tracking/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/implant/tracking/process()
|
||||
@@ -126,7 +126,7 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
|
||||
desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
|
||||
icon_state = "implant_melted"
|
||||
malfunction = MALFUNCTION_PERMANENT
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/implant/tracking/get_data()
|
||||
@@ -529,7 +529,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
// a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Security")
|
||||
// a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Medical")
|
||||
qdel(a)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if ("emp")
|
||||
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
|
||||
var/name = prob(50) ? t.name : pick(teleportlocs)
|
||||
@@ -543,7 +543,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
// a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Security")
|
||||
// a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Medical")
|
||||
qdel(a)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
|
||||
if (malfunction) //so I'm just going to add a meltdown chance here
|
||||
@@ -556,14 +556,14 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
meltdown()
|
||||
else if (prob(60)) //but more likely it will just quietly die
|
||||
malfunction = MALFUNCTION_PERMANENT
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
spawn(20)
|
||||
malfunction--
|
||||
|
||||
/obj/item/weapon/implant/death_alarm/post_implant(mob/source as mob)
|
||||
mobname = source.real_name
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
//////////////////////////////
|
||||
// Compressed Matter Implant
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
if(H.isSynthetic() && H.get_FBP_type() != FBP_CYBORG) //If this on an FBP, it's just an extra inefficient attachment to whatever their brain is.
|
||||
robotic_brain = TRUE
|
||||
if(my_brain && my_brain.can_assist())
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/implant/neural/Destroy()
|
||||
if(my_brain)
|
||||
if(my_brain.owner)
|
||||
to_chat(my_brain.owner, "<span class='critical'>You feel a pressure in your mind as something is ripped away.</span>")
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
my_brain = null
|
||||
return ..()
|
||||
|
||||
@@ -92,7 +92,7 @@ Implant Specifics:<BR>"}
|
||||
|
||||
/obj/item/weapon/implant/neural/meltdown()
|
||||
..()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
var/mob/living/carbon/human/H = null
|
||||
if(my_brain && my_brain.owner)
|
||||
if(ishuman(my_brain.owner))
|
||||
|
||||
@@ -57,7 +57,7 @@ var/global/list/ashtray_cache = list()
|
||||
var/obj/item/clothing/mask/smokable/cigarette/cig = W
|
||||
if (cig.lit == 1)
|
||||
src.visible_message("[user] crushes [cig] in \the [src], putting it out.")
|
||||
processing_objects.Remove(cig)
|
||||
STOP_PROCESSING(SSobj, cig)
|
||||
var/obj/item/butt = new cig.type_butt(src)
|
||||
cig.transfer_fingerprints_to(butt)
|
||||
qdel(cig)
|
||||
|
||||
@@ -17,11 +17,11 @@ obj/item/weapon/chainsaw/New()
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("fuel", max_fuel)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
obj/item/weapon/chainsaw/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
..()
|
||||
|
||||
@@ -41,7 +41,7 @@ Protectiveness | Armor %
|
||||
set_material(material_key)
|
||||
|
||||
/obj/item/clothing/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/get_material()
|
||||
@@ -58,7 +58,7 @@ Protectiveness | Armor %
|
||||
if(applies_material_color)
|
||||
color = material.icon_colour
|
||||
if(material.products_need_process())
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_armor()
|
||||
|
||||
// This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc).
|
||||
|
||||
@@ -67,11 +67,11 @@
|
||||
if(applies_material_colour)
|
||||
color = material.icon_colour
|
||||
if(material.products_need_process())
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_force()
|
||||
|
||||
/obj/item/weapon/material/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/material/apply_hit_effect()
|
||||
|
||||
@@ -268,11 +268,11 @@
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(lrange, lpower, lcolor)
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/attack_self(mob/user as mob)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/obj/item/weapon/mop_deploy/New()
|
||||
create_reagents(5)
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/turf/proc/clean_deploy(atom/source)
|
||||
if(source.reagents.has_reagent("water", 1))
|
||||
@@ -48,7 +48,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/weapon/mop_deploy/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/mop_deploy/attack_self(mob/user as mob)
|
||||
|
||||
@@ -401,7 +401,7 @@
|
||||
W.lit = 1
|
||||
W.damtype = "burn"
|
||||
W.icon_state = "match_lit"
|
||||
processing_objects.Add(W)
|
||||
START_PROCESSING(SSobj, W)
|
||||
W.update_icon()
|
||||
return
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@ var/list/global/tank_gauge_cache = list()
|
||||
src.air_contents = new /datum/gas_mixture()
|
||||
src.air_contents.volume = volume //liters
|
||||
src.air_contents.temperature = T20C
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_gauge()
|
||||
return
|
||||
|
||||
/obj/item/weapon/tank/Destroy()
|
||||
QDEL_NULL(air_contents)
|
||||
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(src.proxyassembly)
|
||||
|
||||
if(istype(loc, /obj/item/device/transfer_valve))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,7 +106,7 @@
|
||||
|
||||
/obj/effect/energy_net/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/effect/energy_net/Destroy()
|
||||
if(has_buckled_mobs())
|
||||
@@ -114,7 +114,7 @@
|
||||
to_chat(A,"<span class='notice'>You are free of the net!</span>")
|
||||
unbuckle_mob(A)
|
||||
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/energy_net/process()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
|
||||
|
||||
/obj/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/Topic(href, href_list, var/datum/topic_state/state = default_state)
|
||||
@@ -58,10 +58,6 @@
|
||||
|
||||
/obj/item/proc/is_used_on(obj/O, mob/user)
|
||||
|
||||
/obj/proc/process()
|
||||
processing_objects.Remove(src)
|
||||
return 0
|
||||
|
||||
/obj/assume_air(datum/gas_mixture/giver)
|
||||
if(loc)
|
||||
return loc.assume_air(giver)
|
||||
|
||||
@@ -159,14 +159,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/burn()
|
||||
@@ -342,14 +342,14 @@
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
processing_objects += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/burn()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/closet/statue/process()
|
||||
@@ -55,7 +55,7 @@
|
||||
M.setOxyLoss(intialOxy)
|
||||
if (timer <= 0)
|
||||
dump_contents()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/statue/dump_contents()
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
/obj/structure/girder/Destroy()
|
||||
if(girder_material.products_need_process())
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/girder/process()
|
||||
if(!radiate())
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
/obj/structure/girder/proc/radiate()
|
||||
@@ -53,9 +53,9 @@
|
||||
if(applies_material_colour)
|
||||
color = girder_material.icon_colour
|
||||
if(girder_material.products_need_process()) //Am I radioactive or some other? Process me!
|
||||
processing_objects |= src
|
||||
else if(src in processing_objects) //If I happened to be radioactive or s.o. previously, and am not now, stop processing.
|
||||
processing_objects -= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
else if(is_processing) //If I happened to be radioactive or s.o. previously, and am not now, stop processing.
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/girder/get_material()
|
||||
return girder_material
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/structure/prop/nest/Initialize()
|
||||
..()
|
||||
den_mobs = list()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
last_spawn = world.time
|
||||
if(randomize_spawning) //Not the biggest shift in spawntime, but it's here.
|
||||
var/delayshift_clamp = spawn_delay / 10
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
/obj/structure/prop/nest/Destroy()
|
||||
den_mobs = null
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/prop/nest/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
else
|
||||
set_opacity(1)
|
||||
if(material.products_need_process())
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
|
||||
/obj/structure/simple_door/Destroy()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_nearby_tiles()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -283,9 +283,6 @@ var/const/enterloopsanity = 100
|
||||
L.Add(t)
|
||||
return L
|
||||
|
||||
/turf/proc/process()
|
||||
return PROCESS_KILL
|
||||
|
||||
/turf/proc/contains_dense_objects()
|
||||
if(density)
|
||||
return 1
|
||||
|
||||
@@ -8,7 +8,6 @@ var/global/datum/datacore/data_core = null
|
||||
var/global/list/all_areas = list()
|
||||
var/global/list/machines = list() // ALL Machines, wether processing or not.
|
||||
var/global/list/processing_machines = list() // TODO - Move into SSmachines
|
||||
var/global/list/processing_objects = list()
|
||||
var/global/list/processing_power_items = list() // TODO - Move into SSmachines
|
||||
var/global/list/active_diseases = list()
|
||||
var/global/list/hud_icon_reference = list()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
cameras() // Sets up both cameras and last alarm area.
|
||||
set_source_data(source, duration, severity, hidden)
|
||||
|
||||
/datum/alarm/proc/process()
|
||||
/datum/alarm/process()
|
||||
// Has origin gone missing?
|
||||
if(!origin && !end_time)
|
||||
end_time = world.time + ALARM_RESET_DELAY
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin.
|
||||
var/list/listeners = new // A list of all objects interested in alarm changes.
|
||||
|
||||
/datum/alarm_handler/proc/process()
|
||||
/datum/alarm_handler/process()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
A.process()
|
||||
check_alarm_cleared(A)
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
/obj/item/weapon/deadringer/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/weapon/deadringer/Destroy() //just in case some smartass tries to stay invisible by destroying the watch
|
||||
uncloak()
|
||||
processing_objects -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/deadringer/dropped()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
|
||||
/obj/item/device/assembly/process()
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
tmr.time=5
|
||||
tmr.secured = 1
|
||||
tmr.holder = src
|
||||
processing_objects.Add(tmr)
|
||||
START_PROCESSING(SSobj, tmr)
|
||||
a_left = tmr
|
||||
a_right = ign
|
||||
secured = 1
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
/obj/item/device/assembly/infra/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
on = 0
|
||||
if(first) qdel(first)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
/obj/item/device/assembly/prox_sensor/toggle_secure()
|
||||
secured = !secured
|
||||
if(secured)
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
scanning = 0
|
||||
timing = 0
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
@@ -156,13 +156,13 @@ Code:
|
||||
|
||||
/obj/item/device/assembly/signaler/process()
|
||||
if(!deadman)
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
var/mob/M = src.loc
|
||||
if(!M || !ismob(M))
|
||||
if(prob(5))
|
||||
signal()
|
||||
deadman = 0
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
else if(prob(5))
|
||||
M.visible_message("[M]'s finger twitches a bit over [src]'s signal button!")
|
||||
return
|
||||
@@ -172,7 +172,7 @@ Code:
|
||||
set name = "Threaten to push the button!"
|
||||
set desc = "BOOOOM!"
|
||||
deadman = 1
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSobj, src)
|
||||
log_and_message_admins("is threatening to trigger a signaler deadman's switch")
|
||||
usr.visible_message("<font color='red'>[usr] moves their finger over [src]'s signal button...</font>")
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user