This commit is contained in:
kevinz000
2018-10-14 19:45:38 -07:00
parent 8a185305df
commit 84ea3c0931
61 changed files with 885 additions and 244 deletions

View File

@@ -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 gases.Cut() // Do not qdel the gases, we don't own them
return ..() return ..()
proc/process() process()
//Equalize gases amongst pipe if called for //Equalize gases amongst pipe if called for
if(update) if(update)
update = 0 update = 0

View File

@@ -20,7 +20,7 @@ datum/pipeline
edges = null 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 //Check to see if pressure is within acceptable limits
var/pressure = air.return_pressure() var/pressure = air.return_pressure()

View File

@@ -1,16 +1,82 @@
#define MC_TICK_CHECK ( ( TICK_USAGE > GLOB.CURRENT_TICKLIMIT || src.state != SS_RUNNING ) ? pause() : 0 ) #define MC_TICK_CHECK ( ( TICK_USAGE > Master.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_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
#define MC_SPLIT_TICK \ #define MC_SPLIT_TICK \
if(split_tick_phases > 1){\ if(split_tick_phases > 1){\
GLOB.CURRENT_TICKLIMIT = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\ Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\
--split_tick_phases;\ --split_tick_phases;\
} else {\ } else {\
GLOB.CURRENT_TICKLIMIT = original_tick_limit;\ 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. // 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)\ #define INTERNAL_PROCESS_STEP(this_step, initial_step, proc_to_call, cost_var, next_step)\
if(current_step == this_step || (initial_step && !resumed)) /* So we start at step 1 if not resumed.*/ {\ if(current_step == this_step || (initial_step && !resumed)) /* So we start at step 1 if not resumed.*/ {\
@@ -23,71 +89,3 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st
resumed = 0;\ resumed = 0;\
current_step = next_step;\ 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
View 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);\
}

View File

@@ -3,7 +3,7 @@
#define TICK_LIMIT_MC 70 #define TICK_LIMIT_MC 70
#define TICK_LIMIT_MC_INIT_DEFAULT 98 #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 CHECK_TICK if TICK_CHECK stoplag()
#define TICK_USAGE world.tick_usage #define TICK_USAGE world.tick_usage

6
code/__defines/flags.dm Normal file
View File

@@ -0,0 +1,6 @@
#define ALL (~0)
#define NONE 0
// datum_flags
#define DF_VAR_EDITED (1<<0)
#define DF_ISPROCESSING (1<<1)

View File

@@ -22,7 +22,13 @@
#define QDELETED(X) (!X || X.gc_destroyed) #define QDELETED(X) (!X || X.gc_destroyed)
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) #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(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(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(); } #define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }

View File

@@ -1,18 +1,23 @@
//Timing subsystem //Timing subsystem
//Don't run if there is an identical unique timer active //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 //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. //Timing should be based on how timing progresses on clients, not the sever.
// tracking this is more expensive, // tracking this is more expensive,
// should only be used in conjuction with things that have to progress client side, such as animate() or sound() // 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() //Timer can be stopped using deltimer()
#define TIMER_STOPPABLE 0x8 #define TIMER_STOPPABLE (1<<3)
//To be used with TIMER_UNIQUE //To be used with TIMER_UNIQUE
//prevents distinguishing identical timers with the wait variable //prevents distinguishing identical timers with the wait variable
#define TIMER_NO_HASH_WAIT 0x10 #define TIMER_NO_HASH_WAIT (1<<4)
#define TIMER_NO_INVOKE_WARNING 600 //number of byond ticks that are allowed to pass before the timer subsystem thinks it hung on something //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_INSSATOMS 0 //New should not call Initialize
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE) #define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
@@ -51,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_ATOMS 15 #define INIT_ORDER_ATOMS 15
#define INIT_ORDER_MACHINES 10 #define INIT_ORDER_MACHINES 10
#define INIT_ORDER_SHUTTLES 3 #define INIT_ORDER_SHUTTLES 3
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0 #define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_LIGHTING 0 #define INIT_ORDER_LIGHTING 0
#define INIT_ORDER_AIR -1 #define INIT_ORDER_AIR -1
@@ -68,6 +74,8 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_GARBAGE 15 #define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_AIRFLOW 30 #define FIRE_PRIORITY_AIRFLOW 30
#define FIRE_PRIORITY_AIR 35 #define FIRE_PRIORITY_AIR 35
#define FIRE_PRIORITY_OBJ 40
#define FIRE_PRIORITY_PROCESS 45
#define FIRE_PRIORITY_DEFAULT 50 #define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PLANETS 75 #define FIRE_PRIORITY_PLANETS 75
#define FIRE_PRIORITY_MACHINES 100 #define FIRE_PRIORITY_MACHINES 100

View File

@@ -42,3 +42,6 @@
. = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME] . = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME]
if (!.) if (!.)
. = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT] . = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT]
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
return a.timeToRun - b.timeToRun

View File

@@ -140,7 +140,7 @@ var/round_start_time = 0
. += CEILING(i*DELTA_CALC, 1) . += CEILING(i*DELTA_CALC, 1)
sleep(i*world.tick_lag*DELTA_CALC) sleep(i*world.tick_lag*DELTA_CALC)
i *= 2 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 #undef DELTA_CALC

View File

@@ -65,32 +65,4 @@
#define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE) #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)]") } #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;

View File

@@ -155,7 +155,7 @@
/datum/controller/process/proc/setup() /datum/controller/process/proc/setup()
/datum/controller/process/proc/process() /datum/controller/process/process()
started() started()
doWork() doWork()
finished() finished()

View File

@@ -70,7 +70,7 @@ var/global/datum/controller/processScheduler/processScheduler
spawn(0) spawn(0)
process() process()
/datum/controller/processScheduler/proc/process() /datum/controller/processScheduler/process()
while(isRunning) while(isRunning)
checkRunningProcesses() checkRunningProcesses()
queueProcesses() queueProcesses()

View File

@@ -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")

View File

@@ -66,7 +66,7 @@ var/datum/controller/supply/supply_controller = new()
// Supply shuttle ticker - handles supply point regeneration // Supply shuttle ticker - handles supply point regeneration
// This is called by the process scheduler every thirty seconds // This is called by the process scheduler every thirty seconds
/datum/controller/supply/proc/process() /datum/controller/supply/process()
points += points_per_process points += points_per_process
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.

View File

@@ -10,7 +10,7 @@ datum/controller/transfer_controller/New()
datum/controller/transfer_controller/Destroy() datum/controller/transfer_controller/Destroy()
processing_objects -= src processing_objects -= src
datum/controller/transfer_controller/proc/process() datum/controller/transfer_controller/process()
currenttick = currenttick + 1 currenttick = currenttick + 1
if (round_duration_in_ticks >= timerbuffer - 1 MINUTE) if (round_duration_in_ticks >= timerbuffer - 1 MINUTE)
vote.autotransfer() vote.autotransfer()

View File

@@ -26,7 +26,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
escape_pods = list() escape_pods = list()
..() ..()
/datum/emergency_shuttle_controller/proc/process() /datum/emergency_shuttle_controller/process()
if (wait_for_launch) if (wait_for_launch)
if (evac && auto_recall && world.time >= auto_recall_time) if (evac && auto_recall && world.time >= auto_recall_time)
recall() recall()

View File

@@ -13,14 +13,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
//THIS IS THE INIT ORDER //THIS IS THE INIT ORDER
//Master -> SSPreInit -> GLOB -> world -> config -> SSInit -> Failsafe //Master -> SSPreInit -> GLOB -> world -> config -> SSInit -> Failsafe
//GOT IT MEMORIZED? //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 /datum/controller/master
name = "Master" name = "Master"
@@ -62,6 +54,10 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
var/static/restart_timeout = 0 var/static/restart_timeout = 0
var/static/restart_count = 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() /datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new. // Highlander-style: there can only be one! Kill off the old and replace it with the new.
var/list/_subsystems = list() 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 // -1 if we encountered a runtime trying to recreate it
/proc/Recreate_MC() /proc/Recreate_MC()
. = -1 //so if we runtime, things know we failed . = -1 //so if we runtime, things know we failed
if (world.time < GLOB.MC_restart_timeout) if (world.time < Master.restart_timeout)
return 0 return 0
if (world.time < GLOB.MC_restart_clear) if (world.time < Master.restart_clear)
GLOB.MC_restart_count *= 0.5 Master.restart_count *= 0.5
var/delay = 50 * ++GLOB.MC_restart_count var/delay = 50 * ++Master.restart_count
GLOB.MC_restart_timeout = world.time + delay Master.restart_timeout = world.time + delay
GLOB.MC_restart_clear = world.time + (delay * 2) Master.restart_clear = world.time + (delay * 2)
Master.processing = FALSE //stop ticking this one Master.processing = FALSE //stop ticking this one
try try
new/datum/controller/master() new/datum/controller/master()
@@ -176,13 +172,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
var/start_timeofday = REALTIMEOFDAY var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems. // 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) for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_NO_INIT) if (SS.flags & SS_NO_INIT)
continue continue
SS.Initialize(REALTIMEOFDAY) SS.Initialize(REALTIMEOFDAY)
CHECK_TICK CHECK_TICK
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING current_ticklimit = TICK_LIMIT_RUNNING
var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!" 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))) tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
var/starting_tick_usage = TICK_USAGE var/starting_tick_usage = TICK_USAGE
if (processing <= 0) if (processing <= 0)
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING current_ticklimit = TICK_LIMIT_RUNNING
sleep(10) sleep(10)
continue 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) // (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. 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 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)) sleep(world.tick_lag * (processing * sleep_delta))
continue continue
@@ -346,7 +342,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
if (!error_level) if (!error_level)
iteration++ iteration++
error_level++ error_level++
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING current_ticklimit = TICK_LIMIT_RUNNING
sleep(10) sleep(10)
continue continue
@@ -358,7 +354,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
if (!error_level) if (!error_level)
iteration++ iteration++
error_level++ error_level++
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING current_ticklimit = TICK_LIMIT_RUNNING
sleep(10) sleep(10)
continue continue
error_level-- error_level--
@@ -369,9 +365,9 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
iteration++ iteration++
last_run = world.time last_run = world.time
src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta) 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) 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)) 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. // Reduce tick allocation for subsystems that overran on their last tick.
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun) 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)) if (!(queue_node_flags & SS_TICKER))
ran_non_ticker = TRUE ran_non_ticker = TRUE

View File

@@ -0,0 +1,6 @@
//Fires five times every second.
PROCESSING_SUBSYSTEM_DEF(fastprocess)
name = "Fast Processing"
wait = 2
stat_tag = "FP"

View File

@@ -0,0 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(obj)
name = "Objects"
priority = FIRE_PRIORITY_OBJ
flags = SS_NO_INIT
wait = 20

View 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

View 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

View 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*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))
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

View File

@@ -32,7 +32,7 @@ var/global/list/round_voters = list() // Keeps track of the individuals voting f
// Tell qdel() to Del() this object. // Tell qdel() to Del() this object.
return QDEL_HINT_HARDDEL_NOW return QDEL_HINT_HARDDEL_NOW
/datum/controller/vote/proc/process() //called by master_controller /datum/controller/vote/process() //called by master_controller
if(mode) if(mode)
// No more change mode votes after the game has started. // No more change mode votes after the game has started.
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP) if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)

View File

@@ -5,8 +5,9 @@
/datum /datum
var/gc_destroyed //Time when this object was destroyed. 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/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 #ifdef TESTING
var/tmp/running_find_references var/tmp/running_find_references
@@ -17,6 +18,16 @@
// This should be overridden to remove all references pointing to the object being destroyed. // 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. // Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
/datum/proc/Destroy(force=FALSE) /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. weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
tag = null tag = null
GLOB.nanomanager.close_uis(src) GLOB.nanomanager.close_uis(src)

View File

@@ -1,3 +1,7 @@
/*
DO NOT USE THIS. THIS IS BEING DEPRECATED BY PROCESSING SUBSYSTEMS (controllers/subsystems/processing) AND TIMERS.
*/
/* /*
README: 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.") CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.")
return 1 return 1
proc/process()
return
proc/active() proc/active()
return control_switch return control_switch

View File

@@ -13,7 +13,7 @@
///process() ///process()
///Called by the gameticker ///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. // Slow this down a bit so latejoiners have a chance of being antags.
process_count++ process_count++
if(process_count >= 10) if(process_count >= 10)

View File

@@ -309,7 +309,7 @@ var/global/datum/controller/gameticker/ticker
to_chat(M, "Colony Directorship not forced on anyone.") to_chat(M, "Colony Directorship not forced on anyone.")
proc/process() process()
if(current_state != GAME_STATE_PLAYING) if(current_state != GAME_STATE_PLAYING)
return 0 return 0

View File

@@ -43,7 +43,7 @@
// Proc: process() // Proc: process()
// Parameters: None // Parameters: None
// Description: Processes CPU gain and research progress based on "realtime" calculation. // 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. if(idle) // No power or running on APU. Do nothing.
last_tick = world.time last_tick = world.time
return return

View File

@@ -7,7 +7,7 @@
var/datum/malf_research_ability/next = null // Next research (if applicable). 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 invested += time
if(invested >= price) if(invested >= price)
unlocked = 1 unlocked = 1

View File

@@ -117,7 +117,7 @@ Programs are a file that can be executed
/* /*
The computer object will transfer process() calls to the program. The computer object will transfer process() calls to the program.
*/ */
/datum/file/program/proc/process() /datum/file/program/process()
if(refresh && computer && !computer.stat) if(refresh && computer && !computer.stat)
computer.updateDialog() computer.updateDialog()
update_icon() update_icon()

View File

@@ -17,7 +17,7 @@
/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param) /datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
return return
/datum/computer/file/embedded_program/proc/process() /datum/computer/file/embedded_program/process()
return return
/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) /datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line)

View File

@@ -115,6 +115,8 @@ Class Procs:
var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/interact_offline = 0 // Can the machine be interacted with while de-powered.
var/obj/item/weapon/circuitboard/circuit = null var/obj/item/weapon/circuitboard/circuit = null
var/speed_process = FALSE //If false, SSmachines. If true, SSfastprocess.
/obj/machinery/New(l, d=0) /obj/machinery/New(l, d=0)
..(l) ..(l)
if(d) if(d)
@@ -125,10 +127,16 @@ Class Procs:
/obj/machinery/initialize() /obj/machinery/initialize()
. = ..() . = ..()
global.machines += src global.machines += src
if(!speed_process)
START_MACHINE_PROCESSING(src) START_MACHINE_PROCESSING(src)
else
START_PROCESSING(SSfastprocess, src)
/obj/machinery/Destroy() /obj/machinery/Destroy()
if(!speed_process)
STOP_MACHINE_PROCESSING(src) STOP_MACHINE_PROCESSING(src)
else
STOP_PROCESSING(SSfastprocess, src)
global.machines -= src global.machines -= src
if(component_parts) if(component_parts)
for(var/atom/A in component_parts) for(var/atom/A in component_parts)
@@ -151,8 +159,6 @@ Class Procs:
if(!(use_power || idle_power_usage || active_power_usage)) if(!(use_power || idle_power_usage || active_power_usage))
return PROCESS_KILL return PROCESS_KILL
return
/obj/machinery/emp_act(severity) /obj/machinery/emp_act(severity)
if(use_power && stat == 0) if(use_power && stat == 0)
use_power(7500/severity) use_power(7500/severity)

View File

@@ -105,7 +105,7 @@ steam.start() -- spawns the effect
/obj/effect/effect/sparks/initialize() /obj/effect/effect/sparks/initialize()
. = ..() . = ..()
schedule_task_in(5 SECONDS, /proc/qdel, list(src)) QDEL_IN(src, 5 SECONDS)
/obj/effect/effect/sparks/Destroy() /obj/effect/effect/sparks/Destroy()
var/turf/T = src.loc var/turf/T = src.loc

View File

@@ -144,7 +144,7 @@
if(!status) return if(!status) return
lit = !lit lit = !lit
if(lit) if(lit)
processing_objects.Add(src) START_PROCESSING(SSobj, src)
if(href_list["amount"]) if(href_list["amount"])
throw_amount = throw_amount + text2num(href_list["amount"]) throw_amount = throw_amount + text2num(href_list["amount"])
throw_amount = max(50, min(5000, throw_amount)) throw_amount = max(50, min(5000, throw_amount))

View File

@@ -21,7 +21,7 @@
Destroy() Destroy()
QDEL_NULL(detonator) QDEL_NULL(detonator)
QDEL_NULL_LIST(beakers) QDEL_LIST_NULL(beakers)
return ..() return ..()
attack_self(mob/user as mob) attack_self(mob/user as mob)

View File

@@ -58,10 +58,6 @@
/obj/item/proc/is_used_on(obj/O, mob/user) /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) /obj/assume_air(datum/gas_mixture/giver)
if(loc) if(loc)
return loc.assume_air(giver) return loc.assume_air(giver)

View File

@@ -279,9 +279,6 @@ var/const/enterloopsanity = 100
L.Add(t) L.Add(t)
return L return L
/turf/proc/process()
return PROCESS_KILL
/turf/proc/contains_dense_objects() /turf/proc/contains_dense_objects()
if(density) if(density)
return 1 return 1

View File

@@ -8,7 +8,6 @@ var/global/datum/datacore/data_core = null
var/global/list/all_areas = list() var/global/list/all_areas = list()
var/global/list/machines = list() // ALL Machines, wether processing or not. 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_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/processing_power_items = list() // TODO - Move into SSmachines
var/global/list/active_diseases = list() var/global/list/active_diseases = list()
var/global/list/hud_icon_reference = list() var/global/list/hud_icon_reference = list()

View File

@@ -31,7 +31,7 @@
cameras() // Sets up both cameras and last alarm area. cameras() // Sets up both cameras and last alarm area.
set_source_data(source, duration, severity, hidden) set_source_data(source, duration, severity, hidden)
/datum/alarm/proc/process() /datum/alarm/process()
// Has origin gone missing? // Has origin gone missing?
if(!origin && !end_time) if(!origin && !end_time)
end_time = world.time + ALARM_RESET_DELAY end_time = world.time + ALARM_RESET_DELAY

View File

@@ -7,7 +7,7 @@
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin. 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. 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) for(var/datum/alarm/A in alarms)
A.process() A.process()
check_alarm_cleared(A) check_alarm_cleared(A)

View File

@@ -17,7 +17,7 @@ var/datum/lore/atc_controller/atc = new/datum/lore/atc_controller
next_message = world.time + rand(delay_min,delay_max) next_message = world.time + rand(delay_min,delay_max)
process() process()
/datum/lore/atc_controller/proc/process() /datum/lore/atc_controller/process()
if(world.time >= next_message) if(world.time >= next_message)
if(squelched) if(squelched)
next_message = world.time + backoff_delay next_message = world.time + backoff_delay

View File

@@ -94,7 +94,7 @@
//Do not override this proc, instead use the appropiate procs. //Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs. //This proc will handle the calls to the appropiate procs.
/datum/event/proc/process() /datum/event/process()
if(activeFor > startWhen && activeFor < endWhen) if(activeFor > startWhen && activeFor < endWhen)
tick() tick()

View File

@@ -21,7 +21,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
var/last_world_time = 0 var/last_world_time = 0
/datum/event_container/proc/process() /datum/event_container/process()
if(!next_event_time) if(!next_event_time)
set_event_delay() set_event_delay()

View File

@@ -23,7 +23,7 @@
/datum/event_manager/New() /datum/event_manager/New()
allEvents = typesof(/datum/event) - /datum/event allEvents = typesof(/datum/event) - /datum/event
/datum/event_manager/proc/process() /datum/event_manager/process()
for(var/datum/event/E in event_manager.active_events) for(var/datum/event/E in event_manager.active_events)
E.process() E.process()

View File

@@ -22,7 +22,7 @@
for(var/datum/gm_action/action in available_actions) for(var/datum/gm_action/action in available_actions)
action.gm = src action.gm = src
/datum/game_master/proc/process() /datum/game_master/process()
if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended) if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended)
adjust_staleness(1) adjust_staleness(1)
adjust_danger(-1) adjust_danger(-1)

View File

@@ -131,7 +131,7 @@ var/global/datum/controller/plants/plant_controller // Set in New().
seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200) seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200)
return seed return seed
/datum/controller/plants/proc/process() /datum/controller/plants/process()
processing = 1 processing = 1
spawn(0) spawn(0)
set background = 1 set background = 1

View File

@@ -44,7 +44,7 @@
/datum/plane_holder/Destroy() /datum/plane_holder/Destroy()
my_mob = null my_mob = null
QDEL_NULL_LIST(plane_masters) //Goodbye my children, be free QDEL_LIST_NULL(plane_masters) //Goodbye my children, be free
return ..() return ..()
/datum/plane_holder/proc/set_vis(var/which = null, var/state = FALSE) /datum/plane_holder/proc/set_vis(var/which = null, var/state = FALSE)

View File

@@ -502,7 +502,7 @@ nanoui is used to open and update nano browser uis
* *
* @return nothing * @return nothing
*/ */
/datum/nanoui/proc/process(update = 0) /datum/nanoui/process(update = 0)
if (!src_object || !user) if (!src_object || !user)
close() close()
return return

View File

@@ -45,7 +45,7 @@
)) ))
update_sun() update_sun()
/datum/planet/proc/process(last_fire) /datum/planet/process(last_fire)
if(current_time) if(current_time)
var/difference = world.time - last_fire var/difference = world.time - last_fire
current_time = current_time.add_seconds((difference / 10) * PLANET_TIME_MODIFIER) current_time = current_time.add_seconds((difference / 10) * PLANET_TIME_MODIFIER)

View File

@@ -40,7 +40,7 @@
our_planet.update_sun() our_planet.update_sun()
log_debug("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]&deg;K ([temperature - T0C]&deg;C | [temperature * 1.8 - 459.67]&deg;F).") log_debug("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]&deg;K ([temperature - T0C]&deg;C | [temperature * 1.8 - 459.67]&deg;F).")
/datum/weather_holder/proc/process() /datum/weather_holder/process()
if(world.time >= next_weather_shift) if(world.time >= next_weather_shift)
if(!current_weather) // Roundstart (hopefully). if(!current_weather) // Roundstart (hopefully).
initialize_weather() initialize_weather()

View File

@@ -96,7 +96,7 @@
return progress return progress
/datum/chemical_reaction/proc/process(var/datum/reagents/holder) /datum/chemical_reaction/process(var/datum/reagents/holder)
//determine how far the reaction can proceed //determine how far the reaction can proceed
var/list/reaction_limits = list() var/list/reaction_limits = list()
for(var/reactant in required_reagents) for(var/reactant in required_reagents)

View File

@@ -1,3 +1,7 @@
#define OFF 0
#define FORWARDS 1
#define BACKWARDS 2
//conveyor2 is pretty much like the original, except it supports corners, but not diverters. //conveyor2 is pretty much like the original, except it supports corners, but not diverters.
//note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards. //note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards.
@@ -10,7 +14,7 @@
layer = ABOVE_TURF_LAYER layer = ABOVE_TURF_LAYER
anchored = 1 anchored = 1
circuit = /obj/item/weapon/circuitboard/conveyor circuit = /obj/item/weapon/circuitboard/conveyor
var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off var/operating = OFF // 1 if running forward, -1 if backwards, 0 if off
var/operable = 1 // true if can operate (no broken segments in this belt run) var/operable = 1 // true if can operate (no broken segments in this belt run)
var/forwards // this is the default (forward) direction, set by the map dir var/forwards // this is the default (forward) direction, set by the map dir
var/backwards // hopefully self-explanatory var/backwards // hopefully self-explanatory
@@ -36,7 +40,7 @@
backwards = turn(dir, 180) backwards = turn(dir, 180)
if(on) if(on)
operating = 1 operating = FORWARDS
setmove() setmove()
component_parts = list() component_parts = list()
@@ -48,22 +52,23 @@
RefreshParts() RefreshParts()
/obj/machinery/conveyor/proc/setmove() /obj/machinery/conveyor/proc/setmove()
if(operating == 1) if(operating == FORWARDS)
movedir = forwards movedir = forwards
else if(operating == -1) else if(operating == BACKWARDS)
movedir = backwards movedir = backwards
else operating = 0 else
operating = OFF
update() update()
/obj/machinery/conveyor/proc/update() /obj/machinery/conveyor/proc/update()
if(stat & BROKEN) if(stat & BROKEN)
icon_state = "conveyor-broken" icon_state = "conveyor-broken"
operating = 0 operating = OFF
return return
if(!operable) if(!operable)
operating = 0 operating = OFF
if(stat & NOPOWER) if(stat & NOPOWER)
operating = 0 operating = OFF
icon_state = "conveyor[operating]" icon_state = "conveyor[operating]"
// machine process // machine process

View File

@@ -42,7 +42,7 @@
return ..() return ..()
/obj/machinery/shield_gen/Destroy() /obj/machinery/shield_gen/Destroy()
QDEL_NULL_LIST(field) QDEL_LIST_NULL(field)
return ..() return ..()
/obj/machinery/shield_gen/emag_act(var/remaining_charges, var/mob/user) /obj/machinery/shield_gen/emag_act(var/remaining_charges, var/mob/user)

View File

@@ -37,7 +37,7 @@
supply_controller.shuttle = null supply_controller.shuttle = null
. = ..() . = ..()
/datum/shuttle/proc/process() /datum/shuttle/process()
return return
/datum/shuttle/proc/init_docking_controllers() /datum/shuttle/proc/init_docking_controllers()

View File

@@ -64,7 +64,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now
//still_recharging_msg = "<span class='notice'>[name] is still recharging.</span>" //still_recharging_msg = "<span class='notice'>[name] is still recharging.</span>"
charge_counter = charge_max charge_counter = charge_max
/spell/proc/process() /spell/process()
spawn while(charge_counter < charge_max) spawn while(charge_counter < charge_max)
charge_counter++ charge_counter++
sleep(1) sleep(1)

View File

@@ -87,7 +87,7 @@ Notes:
/datum/tooltip/proc/hide() /datum/tooltip/proc/hide()
if (queueHide) if (queueHide)
schedule_task_with_source_in(1, src, .proc/do_hide) addtimer(CALLBACK(src, .proc/do_hide), 1)
else else
do_hide() do_hide()

View File

@@ -60,7 +60,7 @@
/datum/artifact_effect/proc/DoEffectPulse(var/atom/holder) /datum/artifact_effect/proc/DoEffectPulse(var/atom/holder)
/datum/artifact_effect/proc/UpdateMove() /datum/artifact_effect/proc/UpdateMove()
/datum/artifact_effect/proc/process() /datum/artifact_effect/process()
if(chargelevel < chargelevelmax) if(chargelevel < chargelevelmax)
chargelevel++ chargelevel++

View File

@@ -15,7 +15,7 @@
if(holder_atom) if(holder_atom)
processing_objects.Add(src) processing_objects.Add(src)
/datum/talking_atom/proc/process() /datum/talking_atom/process()
if(!holder_atom) if(!holder_atom)
processing_objects.Remove(src) processing_objects.Remove(src)

View File

@@ -20,6 +20,7 @@
#include "code\world.dm" #include "code\world.dm"
#include "code\__datastructures\globals.dm" #include "code\__datastructures\globals.dm"
#include "code\__defines\_compile_options.dm" #include "code\__defines\_compile_options.dm"
#include "code\__defines\_lists.dm"
#include "code\__defines\_planes+layers.dm" #include "code\__defines\_planes+layers.dm"
#include "code\__defines\_tick.dm" #include "code\__defines\_tick.dm"
#include "code\__defines\admin.dm" #include "code\__defines\admin.dm"
@@ -31,6 +32,7 @@
#include "code\__defines\construction.dm" #include "code\__defines\construction.dm"
#include "code\__defines\damage_organs.dm" #include "code\__defines\damage_organs.dm"
#include "code\__defines\dna.dm" #include "code\__defines\dna.dm"
#include "code\__defines\flags.dm"
#include "code\__defines\gamemode.dm" #include "code\__defines\gamemode.dm"
#include "code\__defines\holomap.dm" #include "code\__defines\holomap.dm"
#include "code\__defines\integrated_circuits.dm" #include "code\__defines\integrated_circuits.dm"
@@ -181,9 +183,7 @@
#include "code\controllers\Processes\inactivity.dm" #include "code\controllers\Processes\inactivity.dm"
#include "code\controllers\Processes\mob.dm" #include "code\controllers\Processes\mob.dm"
#include "code\controllers\Processes\nanoui.dm" #include "code\controllers\Processes\nanoui.dm"
#include "code\controllers\Processes\obj.dm"
#include "code\controllers\Processes\radiation.dm" #include "code\controllers\Processes\radiation.dm"
#include "code\controllers\Processes\scheduler.dm"
#include "code\controllers\Processes\sun.dm" #include "code\controllers\Processes\sun.dm"
#include "code\controllers\Processes\supply.dm" #include "code\controllers\Processes\supply.dm"
#include "code\controllers\Processes\ticker.dm" #include "code\controllers\Processes\ticker.dm"
@@ -203,7 +203,12 @@
#include "code\controllers\subsystems\overlays.dm" #include "code\controllers\subsystems\overlays.dm"
#include "code\controllers\subsystems\planets.dm" #include "code\controllers\subsystems\planets.dm"
#include "code\controllers\subsystems\shuttles.dm" #include "code\controllers\subsystems\shuttles.dm"
#include "code\controllers\subsystems\time_track.dm"
#include "code\controllers\subsystems\timer.dm"
#include "code\controllers\subsystems\xenoarch.dm" #include "code\controllers\subsystems\xenoarch.dm"
#include "code\controllers\subsystems\processing\fastprocess.dm"
#include "code\controllers\subsystems\processing\obj.dm"
#include "code\controllers\subsystems\processing\processing.dm"
#include "code\datums\ai_law_sets.dm" #include "code\datums\ai_law_sets.dm"
#include "code\datums\ai_laws.dm" #include "code\datums\ai_laws.dm"
#include "code\datums\beam.dm" #include "code\datums\beam.dm"
@@ -257,7 +262,6 @@
#include "code\datums\observation\logged_in.dm" #include "code\datums\observation\logged_in.dm"
#include "code\datums\observation\moved.dm" #include "code\datums\observation\moved.dm"
#include "code\datums\observation\observation.dm" #include "code\datums\observation\observation.dm"
#include "code\datums\observation\task_triggered.dm"
#include "code\datums\observation\turf_changed.dm" #include "code\datums\observation\turf_changed.dm"
#include "code\datums\observation\unequipped.dm" #include "code\datums\observation\unequipped.dm"
#include "code\datums\observation\~cleanup.dm" #include "code\datums\observation\~cleanup.dm"