diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm index 74134e6ff2..eb5e89276e 100644 --- a/code/ATMOSPHERICS/datum_pipe_network.dm +++ b/code/ATMOSPHERICS/datum_pipe_network.dm @@ -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 diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 28391c4352..fc47bca938 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -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() diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index ad03630666..2683922820 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -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 \ No newline at end of file diff --git a/code/__defines/_lists.dm b/code/__defines/_lists.dm new file mode 100644 index 0000000000..f011662cec --- /dev/null +++ b/code/__defines/_lists.dm @@ -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);\ + } diff --git a/code/__defines/_tick.dm b/code/__defines/_tick.dm index 7ca3fb23a2..2c761b86f9 100644 --- a/code/__defines/_tick.dm +++ b/code/__defines/_tick.dm @@ -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 diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm new file mode 100644 index 0000000000..5de8214191 --- /dev/null +++ b/code/__defines/flags.dm @@ -0,0 +1,6 @@ +#define ALL (~0) +#define NONE 0 + +// datum_flags +#define DF_VAR_EDITED (1<<0) +#define DF_ISPROCESSING (1<<1) diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm index 51c6db5325..ab85326658 100644 --- a/code/__defines/qdel.dm +++ b/code/__defines/qdel.dm @@ -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(); } diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 391aa3a117..ab54ade1f3 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -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 diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index b9e5dd8623..855aa9c138 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -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) diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index 7fd07ec711..2e3411a220 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -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 diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm index 8348796665..d4c918a55a 100644 --- a/code/_helpers/time.dm +++ b/code/_helpers/time.dm @@ -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 diff --git a/code/_macros.dm b/code/_macros.dm index c977617d4a..13afdb27b8 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -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; \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index 2965a52abe..6bbcb62a54 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -155,7 +155,7 @@ /datum/controller/process/proc/setup() -/datum/controller/process/proc/process() +/datum/controller/process/process() started() doWork() finished() diff --git a/code/controllers/ProcessScheduler/core/processScheduler.dm b/code/controllers/ProcessScheduler/core/processScheduler.dm index 86dcdac287..c5b658de15 100644 --- a/code/controllers/ProcessScheduler/core/processScheduler.dm +++ b/code/controllers/ProcessScheduler/core/processScheduler.dm @@ -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() diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm deleted file mode 100644 index 6032cbb541..0000000000 --- a/code/controllers/Processes/obj.dm +++ /dev/null @@ -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") \ No newline at end of file diff --git a/code/controllers/Processes/supply.dm b/code/controllers/Processes/supply.dm index 2234b7a9ac..781e285371 100644 --- a/code/controllers/Processes/supply.dm +++ b/code/controllers/Processes/supply.dm @@ -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. diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm index 34b535c2f6..89dfb5b86f 100644 --- a/code/controllers/autotransfer.dm +++ b/code/controllers/autotransfer.dm @@ -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) diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 05468bee76..bcc7187a3c 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -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() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 050251fb0d..0b292e45c4 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -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 diff --git a/code/controllers/subsystems/processing/fastprocess.dm b/code/controllers/subsystems/processing/fastprocess.dm new file mode 100644 index 0000000000..9622e02146 --- /dev/null +++ b/code/controllers/subsystems/processing/fastprocess.dm @@ -0,0 +1,6 @@ +//Fires five times every second. + +PROCESSING_SUBSYSTEM_DEF(fastprocess) + name = "Fast Processing" + wait = 2 + stat_tag = "FP" diff --git a/code/controllers/subsystems/processing/obj.dm b/code/controllers/subsystems/processing/obj.dm new file mode 100644 index 0000000000..26021fb267 --- /dev/null +++ b/code/controllers/subsystems/processing/obj.dm @@ -0,0 +1,5 @@ +PROCESSING_SUBSYSTEM_DEF(obj) + name = "Objects" + priority = FIRE_PRIORITY_OBJ + flags = SS_NO_INIT + wait = 20 diff --git a/code/controllers/subsystems/processing/processing.dm b/code/controllers/subsystems/processing/processing.dm new file mode 100644 index 0000000000..c5d6dfa126 --- /dev/null +++ b/code/controllers/subsystems/processing/processing.dm @@ -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 diff --git a/code/controllers/subsystems/time_track.dm b/code/controllers/subsystems/time_track.dm new file mode 100644 index 0000000000..aed175ed27 --- /dev/null +++ b/code/controllers/subsystems/time_track.dm @@ -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 diff --git a/code/controllers/subsystems/timer.dm b/code/controllers/subsystems/timer.dm new file mode 100644 index 0000000000..3cd4ffe6ba --- /dev/null +++ b/code/controllers/subsystems/timer.dm @@ -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 diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 32cc5129c9..8cb040e5e1 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -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() diff --git a/code/datums/datum.dm b/code/datums/datum.dm index fd58220657..36d430a0ed 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -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) diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm index d511b5d233..2ebab5582d 100644 --- a/code/datums/helper_datums/global_iterator.dm +++ b/code/datums/helper_datums/global_iterator.dm @@ -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 diff --git a/code/datums/observation/task_triggered.dm b/code/datums/observation/task_triggered.dm deleted file mode 100644 index 0c04ef2ead..0000000000 --- a/code/datums/observation/task_triggered.dm +++ /dev/null @@ -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 diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm index 35526be0d6..ed27a49ba0 100644 --- a/code/game/gamemodes/changeling/powers/armblade.dm +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -64,7 +64,7 @@ /obj/item/weapon/melee/changeling/New(location) ..() - processing_objects |= src + START_PROCESSING(SSobj, src) if(ismob(loc)) visible_message("A grotesque weapon forms around [loc.name]\'s arm!", "Our arm twists and mutates, transforming it into a deadly weapon.", @@ -81,7 +81,7 @@ qdel(src) /obj/item/weapon/melee/changeling/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) creator = null ..() diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index 1051587d13..4559911b79 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -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. diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm index 7f7310f996..aef330c144 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -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 diff --git a/code/game/gamemodes/game_mode_latespawn.dm b/code/game/gamemodes/game_mode_latespawn.dm index ecafc0dbc5..578c1a0d8c 100644 --- a/code/game/gamemodes/game_mode_latespawn.dm +++ b/code/game/gamemodes/game_mode_latespawn.dm @@ -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) diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 7424b514c4..f25deb9e97 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -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 diff --git a/code/game/gamemodes/malfunction/malf_research.dm b/code/game/gamemodes/malfunction/malf_research.dm index da7a4df668..58f7d56c13 100644 --- a/code/game/gamemodes/malfunction/malf_research.dm +++ b/code/game/gamemodes/malfunction/malf_research.dm @@ -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 diff --git a/code/game/gamemodes/malfunction/malf_research_ability.dm b/code/game/gamemodes/malfunction/malf_research_ability.dm index c6916208bd..8002dcead8 100644 --- a/code/game/gamemodes/malfunction/malf_research_ability.dm +++ b/code/game/gamemodes/malfunction/malf_research_ability.dm @@ -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 \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm index 830de5a5f1..9400e24bf1 100644 --- a/code/game/gamemodes/technomancer/core_obj.dm +++ b/code/game/gamemodes/technomancer/core_obj.dm @@ -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. diff --git a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm index 0056675afc..11343fdeac 100644 --- a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm +++ b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm @@ -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() diff --git a/code/game/gamemodes/technomancer/spells/aspect_aura.dm b/code/game/gamemodes/technomancer/spells/aspect_aura.dm index c585f13ee9..833f72a2fb 100644 --- a/code/game/gamemodes/technomancer/spells/aspect_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aspect_aura.dm @@ -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() diff --git a/code/game/gamemodes/technomancer/spells/aura/aura.dm b/code/game/gamemodes/technomancer/spells/aura/aura.dm index f3c7c93876..be986bb7ee 100644 --- a/code/game/gamemodes/technomancer/spells/aura/aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/aura.dm @@ -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 ..() diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm index 345b632282..7855014890 100644 --- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm +++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm @@ -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() diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm index 336dbc4314..d73e45774c 100644 --- a/code/game/gamemodes/technomancer/spells/phase_shift.dm +++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm @@ -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() diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm index fe7d83f713..d86428354e 100644 --- a/code/game/gamemodes/technomancer/spells/radiance.dm +++ b/code/game/gamemodes/technomancer/spells/radiance.dm @@ -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 ..() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index d507403043..570a8a2965 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -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 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 20304fa2ba..e8b845ca78 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -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()) diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index f3e7eb33d6..eaea426c07 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -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() diff --git a/code/game/machinery/computer3/program.dm b/code/game/machinery/computer3/program.dm index b39998bdfd..bf84c1622e 100644 --- a/code/game/machinery/computer3/program.dm +++ b/code/game/machinery/computer3/program.dm @@ -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() diff --git a/code/game/machinery/embedded_controller/embedded_program_base.dm b/code/game/machinery/embedded_controller/embedded_program_base.dm index f579aca6f7..a8be295ccd 100644 --- a/code/game/machinery/embedded_controller/embedded_program_base.dm +++ b/code/game/machinery/embedded_controller/embedded_program_base.dm @@ -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) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 75a056dd1c..0729121195 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -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) diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index 03f743db6b..4455f049ca 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -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) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index fd843fa9df..3b1584ca19 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -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) ..() diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index a52f67c6ea..f21d6443fb 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -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() diff --git a/code/game/objects/effects/map_effects/radiation_emitter.dm b/code/game/objects/effects/map_effects/radiation_emitter.dm index 0d9af4d2da..3fb31d3c5d 100644 --- a/code/game/objects/effects/map_effects/radiation_emitter.dm +++ b/code/game/objects/effects/map_effects/radiation_emitter.dm @@ -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 \ No newline at end of file diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 72ab9da44b..9e2b12ab26 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -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 ..() diff --git a/code/game/objects/items/devices/ai_detector.dm b/code/game/objects/items/devices/ai_detector.dm index 7fa6f74521..fde112706f 100644 --- a/code/game/objects/items/devices/ai_detector.dm +++ b/code/game/objects/items/devices/ai_detector.dm @@ -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() diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index ec9c09c161..6324af7fb5 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -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) diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 8d85efb753..7f0b8b6dac 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -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, "\The [src] feel pleasantly warm.") 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. diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 938cb24286..4543a6d726 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -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("[user] activates the flare.", "You pull the cord on the flare, activating it!") 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("[user] cracks and shakes the glowstick.", "You crack and shake the glowstick, turning it on!") - processing_objects += src + START_PROCESSING(SSobj, src) /obj/item/device/flashlight/glowstick/red name = "red glowstick" diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm index dbac918609..9ab63afce7 100644 --- a/code/game/objects/items/devices/geiger.dm +++ b/code/game/objects/items/devices/geiger.dm @@ -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() diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index c35ec18e59..ee77a47de9 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -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, "You've overused the battery of [src], now it needs time to recharge!") recharge_locked = 1 diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 6ea73e8c78..26daccfc92 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -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("[user] activates [src]!") 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("[user] deactivates [src]!") 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() diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 9962b99cf2..571fd5f39d 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -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) diff --git a/code/game/objects/items/devices/radio/jammer.dm b/code/game/objects/items/devices/radio/jammer.dm index b129657d19..4a57f855ee 100644 --- a/code/game/objects/items/devices/radio/jammer.dm +++ b/code/game/objects/items/devices/radio/jammer.dm @@ -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,"\The [src] deactivates.") - 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,"\The [src] is now active.") - processing_objects.Add(src) + START_PROCESSING(SSobj, src) active_radio_jammers += src on = TRUE update_icon() diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 6efc045785..5a6d5872c4 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -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 diff --git a/code/game/objects/items/devices/t_scanner.dm b/code/game/objects/items/devices/t_scanner.dm index 5610828bfe..0709429ac1 100644 --- a/code/game/objects/items/devices/t_scanner.dm +++ b/code/game/objects/items/devices/t_scanner.dm @@ -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() diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 2778f46b03..0bdb5a6b72 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -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) diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index 5de7ae3730..2e73e89e67 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -34,7 +34,7 @@ var/obj/effect/spider/spiderling/S = A user.visible_message("[user] scoops [S] into \the [src].", "You scoop [S] into \the [src].") 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("[user] releases [S] from \the [src].", "You release [S] from \the [src].") - 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 diff --git a/code/game/objects/items/poi_items.dm b/code/game/objects/items/poi_items.dm index 30b6e12763..6fd6d7debd 100644 --- a/code/game/objects/items/poi_items.dm +++ b/code/game/objects/items/poi_items.dm @@ -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 ..() diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 22a661fe77..61290fc91f 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -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) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 5d60c8485b..bd24642c67 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -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("After a few attempts, [user] manages to light the [src], they however burn their finger in the process.") 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("[user] quietly shuts off the [src].") set_light(0) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 919f8cb016..1d9a926e2e 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -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)) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 442e6c3f1d..c5c8075c63 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -21,7 +21,7 @@ Destroy() QDEL_NULL(detonator) - QDEL_NULL_LIST(beakers) + QDEL_LIST_NULL(beakers) return ..() attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/grenades/supermatter.dm b/code/game/objects/items/weapons/grenades/supermatter.dm index 1bf35d1e1c..7eff5accd4 100644 --- a/code/game/objects/items/weapons/grenades/supermatter.dm +++ b/code/game/objects/items/weapons/grenades/supermatter.dm @@ -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) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index f5bd38dcc1..1804d576fd 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -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 diff --git a/code/game/objects/items/weapons/implants/neuralbasic.dm b/code/game/objects/items/weapons/implants/neuralbasic.dm index a42778f58e..d744c80fde 100644 --- a/code/game/objects/items/weapons/implants/neuralbasic.dm +++ b/code/game/objects/items/weapons/implants/neuralbasic.dm @@ -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, "You feel a pressure in your mind as something is ripped away.") - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) my_brain = null return ..() @@ -92,7 +92,7 @@ Implant Specifics:
"} /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)) diff --git a/code/game/objects/items/weapons/material/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm index 8becb48010..5a26720b7c 100644 --- a/code/game/objects/items/weapons/material/ashtray.dm +++ b/code/game/objects/items/weapons/material/ashtray.dm @@ -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) diff --git a/code/game/objects/items/weapons/material/chainsaw.dm b/code/game/objects/items/weapons/material/chainsaw.dm index 703512bf52..f98fe79f51 100644 --- a/code/game/objects/items/weapons/material/chainsaw.dm +++ b/code/game/objects/items/weapons/material/chainsaw.dm @@ -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) ..() diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm index ecd328f3ab..d8fba58175 100644 --- a/code/game/objects/items/weapons/material/material_armor.dm +++ b/code/game/objects/items/weapons/material/material_armor.dm @@ -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). diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm index 06444f6a37..4f08c61a4c 100644 --- a/code/game/objects/items/weapons/material/material_weapons.dm +++ b/code/game/objects/items/weapons/material/material_weapons.dm @@ -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() diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index d70de28a7e..6c4930950e 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -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) diff --git a/code/game/objects/items/weapons/mop_deploy.dm b/code/game/objects/items/weapons/mop_deploy.dm index 30a6991a53..93b3657f49 100644 --- a/code/game/objects/items/weapons/mop_deploy.dm +++ b/code/game/objects/items/weapons/mop_deploy.dm @@ -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) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 2dd06bc0bc..cdf5f347d2 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -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 diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index aab34d8f82..c5443d5f16 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -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)) diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm index 2772cf154e..e984a1ad7d 100644 --- a/code/game/objects/items/weapons/tools/weldingtool.dm +++ b/code/game/objects/items/weapons/tools/weldingtool.dm @@ -1,605 +1,1222 @@ -#define WELDER_FUEL_BURN_INTERVAL 13 -/* - * Welding Tool - */ -/obj/item/weapon/weldingtool - name = "\improper welding tool" - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - flags = CONDUCT - slot_flags = SLOT_BELT - - //Amount of OUCH when it's thrown - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 5 - w_class = ITEMSIZE_SMALL - - //Cost to make in the autolathe - matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 30) - - //R&D tech level - origin_tech = list(TECH_ENGINEERING = 1) - - //Welding tool specific stuff - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = 1 //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - usesound = 'sound/items/Welder2.ogg' - var/change_icons = TRUE - var/flame_intensity = 2 //how powerful the emitted light is when used. - var/flame_color = "#FF9933" // What color the welder light emits when its on. Default is an orange-ish color. - var/eye_safety_modifier = 0 // Increasing this will make less eye protection needed to stop eye damage. IE at 1, sunglasses will fully protect. - var/burned_fuel_for = 0 // Keeps track of how long the welder's been on, used to gradually empty the welder if left one, without RNG. - var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel. - toolspeed = 1 - -/obj/item/weapon/weldingtool/New() -// var/random_fuel = min(rand(10,20),max_fuel) - var/datum/reagents/R = new/datum/reagents(max_fuel) - reagents = R - R.my_atom = src - R.add_reagent("fuel", max_fuel) - update_icon() - if(always_process) - processing_objects |= src - ..() - -/obj/item/weapon/weldingtool/Destroy() - if(welding || always_process) - processing_objects -= src - return ..() - -/obj/item/weapon/weldingtool/examine(mob/user) - if(..(user, 0)) - if(max_fuel) - to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel )) - -/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone) - if(ishuman(A) && user.a_intent == I_HELP) - var/mob/living/carbon/human/H = A - var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] - - if(!S || S.robotic < ORGAN_ROBOT || S.open == 3) - return ..() - - if(!welding) - to_chat(user, "You'll need to turn [src] on to patch the damage on [H]'s [S.name]!") - return 1 - - if(S.robo_repair(15, BRUTE, "some dents", src, user)) - remove_fuel(1, user) - return 1 - - return ..() - -/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob) - if(istype(W,/obj/item/weapon/tool/screwdriver)) - if(welding) - to_chat(user, "Stop welding first!") - return - status = !status - if(status) - to_chat(user, "You secure the welder.") - else - to_chat(user, "The welder can now be attached and modified.") - src.add_fingerprint(user) - return - - if((!status) && (istype(W,/obj/item/stack/rods))) - var/obj/item/stack/rods/R = W - R.use(1) - var/obj/item/weapon/flamethrower/F = new/obj/item/weapon/flamethrower(user.loc) - src.loc = F - F.weldtool = src - if (user.client) - user.client.screen -= src - if (user.r_hand == src) - user.remove_from_mob(src) - else - user.remove_from_mob(src) - src.master = F - src.layer = initial(src.layer) - user.remove_from_mob(src) - if (user.client) - user.client.screen -= src - src.loc = F - src.add_fingerprint(user) - return - - ..() - return - - -/obj/item/weapon/weldingtool/process() - if(welding) - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - if(get_fuel() < 1) - setWelding(0) - - //I'm not sure what this does. I assume it has to do with starting fires... - //...but it doesnt check to see if the welder is on or not. - var/turf/location = src.loc - if(istype(location, /mob/living)) - var/mob/living/M = location - if(M.item_is_in_hands(src)) - location = get_turf(M) - if (istype(location, /turf)) - location.hotspot_expose(700, 5) - -/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity) - if(!proximity) return - if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1) - if(!welding && max_fuel) - O.reagents.trans_to_obj(src, max_fuel) - to_chat(user, "Welder refueled") - playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) - return - else if(!welding) - to_chat(user, "[src] doesn't use fuel.") - return - else - message_admins("[key_name_admin(user)] triggered a fueltank explosion with a welding tool.") - log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.") - to_chat(user, "You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.") - var/obj/structure/reagent_dispensers/fueltank/tank = O - tank.explode() - return - if (src.welding) - remove_fuel(1) - var/turf/location = get_turf(user) - if(isliving(O)) - var/mob/living/L = O - L.IgniteMob() - if (istype(location, /turf)) - location.hotspot_expose(700, 50, 1) - -/obj/item/weapon/weldingtool/attack_self(mob/user as mob) - setWelding(!welding, usr) - -//Returns the amount of fuel in the welder -/obj/item/weapon/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("fuel") - -/obj/item/weapon/weldingtool/proc/get_max_fuel() - return max_fuel - -//Removes fuel from the welding tool. If a mob is passed, it will perform an eyecheck on the mob. This should probably be renamed to use() -/obj/item/weapon/weldingtool/proc/remove_fuel(var/amount = 1, var/mob/M = null) - if(!welding) - return 0 - if(amount) - burned_fuel_for = 0 // Reset the counter since we're removing fuel. - if(get_fuel() >= amount) - reagents.remove_reagent("fuel", amount) - if(M) - eyecheck(M) - update_icon() - return 1 - else - if(M) - to_chat(M, "You need more welding fuel to complete this task.") - update_icon() - return 0 - -//Returns whether or not the welding tool is currently on. -/obj/item/weapon/weldingtool/proc/isOn() - return welding - -/obj/item/weapon/weldingtool/update_icon() - ..() - overlays.Cut() - // Welding overlay. - if(welding) - var/image/I = image(icon, src, "[icon_state]-on") - overlays.Add(I) - item_state = "[initial(item_state)]1" - else - item_state = initial(item_state) - - // Fuel counter overlay. - if(change_icons && get_max_fuel()) - var/ratio = get_fuel() / get_max_fuel() - ratio = CEILING(ratio * 4, 1) * 25 - var/image/I = image(icon, src, "[icon_state][ratio]") - overlays.Add(I) - - // Lights - if(welding && flame_intensity) - set_light(flame_intensity, flame_intensity, flame_color) - else - set_light(0) - -// icon_state = welding ? "[icon_state]1" : "[initial(icon_state)]" - var/mob/M = loc - if(istype(M)) - M.update_inv_l_hand() - M.update_inv_r_hand() - -/obj/item/weapon/weldingtool/MouseDrop(obj/over_object as obj) - if(!canremove) - return - - if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist - - if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why? - return - - if (!( istype(over_object, /obj/screen) )) - return ..() - - //makes sure that the thing is equipped, so that we can't drag it into our hand from miles away. - //there's got to be a better way of doing this. - if (!(src.loc == usr) || (src.loc && src.loc.loc == usr)) - return - - if (( usr.restrained() ) || ( usr.stat )) - return - - if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src)) - return - - switch(over_object.name) - if("r_hand") - usr.u_equip(src) - usr.put_in_r_hand(src) - if("l_hand") - usr.u_equip(src) - usr.put_in_l_hand(src) - src.add_fingerprint(usr) - -//Sets the welding state of the welding tool. If you see W.welding = 1 anywhere, please change it to W.setWelding(1) -//so that the welding tool updates accordingly -/obj/item/weapon/weldingtool/proc/setWelding(var/set_welding, var/mob/M) - if(!status) return - - var/turf/T = get_turf(src) - //If we're turning it on - if(set_welding && !welding) - if (get_fuel() > 0) - if(M) - to_chat(M, "You switch the [src] on.") - else if(T) - T.visible_message("\The [src] turns on.") - playsound(loc, acti_sound, 50, 1) - src.force = 15 - src.damtype = "fire" - src.w_class = ITEMSIZE_LARGE - src.hitsound = 'sound/items/welder.ogg' - welding = 1 - update_icon() - if(!always_process) - processing_objects |= src - else - if(M) - var/msg = max_fuel ? "welding fuel" : "charge" - to_chat(M, "You need more [msg] to complete this task.") - return - //Otherwise - else if(!set_welding && welding) - if(!always_process) - processing_objects -= src - if(M) - to_chat(M, "You switch \the [src] off.") - else if(T) - T.visible_message("\The [src] turns off.") - playsound(loc, deac_sound, 50, 1) - src.force = 3 - src.damtype = "brute" - src.w_class = initial(src.w_class) - src.welding = 0 - src.hitsound = initial(src.hitsound) - update_icon() - -//Decides whether or not to damage a player's eyes based on what they're wearing as protection -//Note: This should probably be moved to mob -/obj/item/weapon/weldingtool/proc/eyecheck(mob/living/carbon/user) - if(!istype(user)) - return 1 - var/safety = user.eyecheck() - safety = between(-1, safety + eye_safety_modifier, 2) - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] - if(!E) - return - if(H.nif && H.nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) return //VOREStation Add - NIF - switch(safety) - if(1) - to_chat(usr, "Your eyes sting a little.") - E.damage += rand(1, 2) - if(E.damage > 12) - user.eye_blurry += rand(3,6) - if(0) - to_chat(usr, "Your eyes burn.") - E.damage += rand(2, 4) - if(E.damage > 10) - E.damage += rand(4,10) - if(-1) - to_chat(usr, "Your thermals intensify the welder's glow. Your eyes itch and burn severely.") - user.eye_blurry += rand(12,20) - E.damage += rand(12, 16) - if(safety<2) - - if(E.damage > 10) - to_chat(user, "Your eyes are really starting to hurt. This can't be good for you!") - - if (E.damage >= E.min_broken_damage) - to_chat(user, "You go blind!") - user.sdisabilities |= BLIND - else if (E.damage >= E.min_bruised_damage) - to_chat(user, "You go blind!") - user.Blind(5) - user.eye_blurry = 5 - user.disabilities |= NEARSIGHTED - spawn(100) - user.disabilities &= ~NEARSIGHTED - return - -/obj/item/weapon/weldingtool/is_hot() - return isOn() - -/obj/item/weapon/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - origin_tech = list(TECH_ENGINEERING = 2, TECH_PHORON = 2) - matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 60) - -/obj/item/weapon/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weapon/weldingtool/hugetank - name = "upgraded welding tool" - desc = "A much larger welder with a huge tank." - icon_state = "indwelder" - max_fuel = 80 - w_class = ITEMSIZE_NORMAL - origin_tech = list(TECH_ENGINEERING = 3) - matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) - -/obj/item/weapon/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = ITEMSIZE_SMALL - matter = list(MAT_METAL = 30, MAT_GLASS = 10) - change_icons = 0 - toolspeed = 2 - eye_safety_modifier = 1 // Safer on eyes. - -/obj/item/weapon/weldingtool/alien - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - flame_color = "#6699FF" // Light bluish. - eye_safety_modifier = 2 - change_icons = 0 - origin_tech = list(TECH_PHORON = 5 ,TECH_ENGINEERING = 5) - always_process = TRUE - -/obj/item/weapon/weldingtool/alien/process() - if(get_fuel() <= get_max_fuel()) - reagents.add_reagent("fuel", 1) - ..() - -/obj/item/weapon/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of synthesizing its own fuel from waste compounds. It can output a flame hotter than regular welders." - icon_state = "exwelder" - max_fuel = 40 - w_class = ITEMSIZE_NORMAL - origin_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3) - matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) - toolspeed = 0.5 - change_icons = 0 - flame_intensity = 3 - always_process = TRUE - var/nextrefueltick = 0 - -/obj/item/weapon/weldingtool/experimental/process() - ..() - if(get_fuel() < get_max_fuel() && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("fuel", 1) - -/* - * Backpack Welder. - */ - -/obj/item/weapon/weldingtool/tubefed - name = "tube-fed welding tool" - desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank." - icon_state = "tubewelder" - max_fuel = 10 - w_class = ITEMSIZE_NO_CONTAINER - matter = null - toolspeed = 1.25 - change_icons = 0 - flame_intensity = 1 - eye_safety_modifier = 1 - always_process = TRUE - var/obj/item/weapon/weldpack/mounted_pack = null - -/obj/item/weapon/weldingtool/tubefed/New(location) - ..() - if(istype(location, /obj/item/weapon/weldpack)) - var/obj/item/weapon/weldpack/holder = location - mounted_pack = holder - else - qdel(src) - -/obj/item/weapon/weldingtool/tubefed/Destroy() - mounted_pack.nozzle = null - mounted_pack = null - return ..() - -/obj/item/weapon/weldingtool/tubefed/process() - if(mounted_pack) - if(!istype(mounted_pack.loc,/mob/living/carbon/human)) - mounted_pack.return_nozzle() - else - var/mob/living/carbon/human/H = mounted_pack.loc - if(H.back != mounted_pack) - mounted_pack.return_nozzle() - - if(mounted_pack.loc != src.loc && src.loc != mounted_pack) - mounted_pack.return_nozzle() - visible_message("\The [src] retracts to its fueltank.") - - if(get_fuel() <= get_max_fuel()) - mounted_pack.reagents.trans_to_obj(src, 1) - - ..() - -/obj/item/weapon/weldingtool/tubefed/dropped(mob/user) - ..() - if(src.loc != user) - mounted_pack.return_nozzle() - to_chat(user, "\The [src] retracts to its fueltank.") - -/* - * Electric/Arc Welder - */ - -/obj/item/weapon/weldingtool/electric //AND HIS WELDING WAS ELECTRIC - name = "electric welding tool" - desc = "A welder which runs off of electricity." - icon_state = "arcwelder" - max_fuel = 0 //We'll handle the consumption later. - item_state = "ewelder" - var/obj/item/weapon/cell/power_supply //What type of power cell this uses - var/charge_cost = 24 //The rough equivalent of 1 unit of fuel, based on us wanting 10 welds per battery - var/cell_type = /obj/item/weapon/cell/device - var/use_external_power = 0 //If in a borg or hardsuit, this needs to = 1 - flame_color = "#00CCFF" // Blue-ish, to set it apart from the gas flames. - acti_sound = 'sound/effects/sparks4.ogg' - deac_sound = 'sound/effects/sparks4.ogg' - -/obj/item/weapon/weldingtool/electric/unloaded/New() - cell_type = null - -/obj/item/weapon/weldingtool/electric/New() - ..() - if(cell_type == null) - update_icon() - else if(cell_type) - power_supply = new cell_type(src) - else - power_supply = new /obj/item/weapon/cell/device(src) - update_icon() - -/obj/item/weapon/weldingtool/electric/get_cell() - return power_supply - -/obj/item/weapon/weldingtool/electric/examine(mob/user) - if(get_dist(src, user) > 1) - to_chat(user, desc) - else // The << need to stay, for some reason - if(power_supply) - user << text("\icon[] The [] has [] charge left.", src, src.name, get_fuel()) - else - user << text("\icon[] The [] has no power cell!", src, src.name) - -/obj/item/weapon/weldingtool/electric/get_fuel() - if(use_external_power) - var/obj/item/weapon/cell/external = get_external_power_supply() - if(external) - return external.charge - else if(power_supply) - return power_supply.charge - else - return 0 - -/obj/item/weapon/weldingtool/electric/get_max_fuel() - if(use_external_power) - var/obj/item/weapon/cell/external = get_external_power_supply() - if(external) - return external.maxcharge - else if(power_supply) - return power_supply.maxcharge - return 0 - -/obj/item/weapon/weldingtool/electric/remove_fuel(var/amount = 1, var/mob/M = null) - if(!welding) - return 0 - if(get_fuel() >= amount) - power_supply.checked_use(charge_cost) - if(use_external_power) - var/obj/item/weapon/cell/external = get_external_power_supply() - if(!external || !external.use(charge_cost)) //Take power from the borg... - power_supply.give(charge_cost) //Give it back to the cell. - if(M) - eyecheck(M) - update_icon() - return 1 - else - if(M) - to_chat(M, "You need more energy to complete this task.") - update_icon() - return 0 - -/obj/item/weapon/weldingtool/electric/attack_hand(mob/user as mob) - if(user.get_inactive_hand() == src) - if(power_supply) - power_supply.update_icon() - user.put_in_hands(power_supply) - power_supply = null - to_chat(user, "You remove the cell from the [src].") - setWelding(0) - update_icon() - return - ..() - else - return ..() - -/obj/item/weapon/weldingtool/electric/attackby(obj/item/weapon/W, mob/user as mob) - if(istype(W, /obj/item/weapon/cell)) - if(istype(W, /obj/item/weapon/cell/device)) - if(!power_supply) - user.drop_item() - W.loc = src - power_supply = W - to_chat(user, "You install a cell in \the [src].") - update_icon() - else - to_chat(user, "\The [src] already has a cell.") - else - to_chat(user, "\The [src] cannot use that type of cell.") - else - ..() - -/obj/item/weapon/weldingtool/electric/proc/get_external_power_supply() - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - return R.cell - if(istype(src.loc, /obj/item/rig_module)) - var/obj/item/rig_module/module = src.loc - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit)) - return suit.cell - return null - -/obj/item/weapon/weldingtool/electric/mounted - use_external_power = 1 - -/obj/item/weapon/weldingtool/electric/mounted/cyborg - toolspeed = 0.5 - -#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file +<<<<<<< HEAD +#define WELDER_FUEL_BURN_INTERVAL 13 +/* + * Welding Tool + */ +/obj/item/weapon/weldingtool + name = "\improper welding tool" + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + flags = CONDUCT + slot_flags = SLOT_BELT + + //Amount of OUCH when it's thrown + force = 3.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 5 + w_class = ITEMSIZE_SMALL + + //Cost to make in the autolathe + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 30) + + //R&D tech level + origin_tech = list(TECH_ENGINEERING = 1) + + //Welding tool specific stuff + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = 1 //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + usesound = 'sound/items/Welder2.ogg' + var/change_icons = TRUE + var/flame_intensity = 2 //how powerful the emitted light is when used. + var/flame_color = "#FF9933" // What color the welder light emits when its on. Default is an orange-ish color. + var/eye_safety_modifier = 0 // Increasing this will make less eye protection needed to stop eye damage. IE at 1, sunglasses will fully protect. + var/burned_fuel_for = 0 // Keeps track of how long the welder's been on, used to gradually empty the welder if left one, without RNG. + var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel. + toolspeed = 1 + +/obj/item/weapon/weldingtool/New() +// var/random_fuel = min(rand(10,20),max_fuel) + var/datum/reagents/R = new/datum/reagents(max_fuel) + reagents = R + R.my_atom = src + R.add_reagent("fuel", max_fuel) + update_icon() + if(always_process) + processing_objects |= src + ..() + +/obj/item/weapon/weldingtool/Destroy() + if(welding || always_process) + processing_objects -= src + return ..() + +/obj/item/weapon/weldingtool/examine(mob/user) + if(..(user, 0)) + if(max_fuel) + to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel )) + +/obj/item/weapon/weldingtool/attack(var/atom/A, var/mob/living/user, var/def_zone) + if(ishuman(A) && user.a_intent == I_HELP) + var/mob/living/carbon/human/H = A + var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] + + if(!S || S.robotic < ORGAN_ROBOT || S.open == 3) + return ..() + + if(!welding) + to_chat(user, "You'll need to turn [src] on to patch the damage on [H]'s [S.name]!") + return 1 + + if(S.robo_repair(15, BRUTE, "some dents", src, user)) + remove_fuel(1, user) + return 1 + + return ..() + +/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob) + if(istype(W,/obj/item/weapon/tool/screwdriver)) + if(welding) + to_chat(user, "Stop welding first!") + return + status = !status + if(status) + to_chat(user, "You secure the welder.") + else + to_chat(user, "The welder can now be attached and modified.") + src.add_fingerprint(user) + return + + if((!status) && (istype(W,/obj/item/stack/rods))) + var/obj/item/stack/rods/R = W + R.use(1) + var/obj/item/weapon/flamethrower/F = new/obj/item/weapon/flamethrower(user.loc) + src.loc = F + F.weldtool = src + if (user.client) + user.client.screen -= src + if (user.r_hand == src) + user.remove_from_mob(src) + else + user.remove_from_mob(src) + src.master = F + src.layer = initial(src.layer) + user.remove_from_mob(src) + if (user.client) + user.client.screen -= src + src.loc = F + src.add_fingerprint(user) + return + + ..() + return + + +/obj/item/weapon/weldingtool/process() + if(welding) + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + + + + if(get_fuel() < 1) + setWelding(0) + + //I'm not sure what this does. I assume it has to do with starting fires... + //...but it doesnt check to see if the welder is on or not. + var/turf/location = src.loc + if(istype(location, /mob/living)) + var/mob/living/M = location + if(M.item_is_in_hands(src)) + location = get_turf(M) + if (istype(location, /turf)) + location.hotspot_expose(700, 5) + + +/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity) + if(!proximity) return + if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1) + if(!welding && max_fuel) + O.reagents.trans_to_obj(src, max_fuel) + to_chat(user, "Welder refueled") + playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) + return + else if(!welding) + to_chat(user, "[src] doesn't use fuel.") + return + else + message_admins("[key_name_admin(user)] triggered a fueltank explosion with a welding tool.") + log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.") + to_chat(user, "You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.") + var/obj/structure/reagent_dispensers/fueltank/tank = O + tank.explode() + return + if (src.welding) + remove_fuel(1) + var/turf/location = get_turf(user) + if(isliving(O)) + var/mob/living/L = O + L.IgniteMob() + if (istype(location, /turf)) + location.hotspot_expose(700, 50, 1) + return + + +/obj/item/weapon/weldingtool/attack_self(mob/user as mob) + setWelding(!welding, usr) + return + +//Returns the amount of fuel in the welder +/obj/item/weapon/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("fuel") + +/obj/item/weapon/weldingtool/proc/get_max_fuel() + return max_fuel + +//Removes fuel from the welding tool. If a mob is passed, it will perform an eyecheck on the mob. This should probably be renamed to use() +/obj/item/weapon/weldingtool/proc/remove_fuel(var/amount = 1, var/mob/M = null) + if(!welding) + return 0 + if(amount) + burned_fuel_for = 0 // Reset the counter since we're removing fuel. + if(get_fuel() >= amount) + reagents.remove_reagent("fuel", amount) + if(M) + eyecheck(M) + update_icon() + return 1 + else + if(M) + to_chat(M, "You need more welding fuel to complete this task.") + update_icon() + return 0 + +//Returns whether or not the welding tool is currently on. +/obj/item/weapon/weldingtool/proc/isOn() + return src.welding + +/obj/item/weapon/weldingtool/update_icon() + ..() + overlays.Cut() + // Welding overlay. + if(welding) + var/image/I = image(icon, src, "[icon_state]-on") + overlays.Add(I) + item_state = "[initial(item_state)]1" + else + item_state = initial(item_state) + + // Fuel counter overlay. + if(change_icons && get_max_fuel()) + var/ratio = get_fuel() / get_max_fuel() + ratio = Ceiling(ratio*4) * 25 + var/image/I = image(icon, src, "[icon_state][ratio]") + overlays.Add(I) + + // Lights + if(welding && flame_intensity) + set_light(flame_intensity, flame_intensity, flame_color) + else + set_light(0) + +// icon_state = welding ? "[icon_state]1" : "[initial(icon_state)]" + var/mob/M = loc + if(istype(M)) + M.update_inv_l_hand() + M.update_inv_r_hand() + +/obj/item/weapon/weldingtool/MouseDrop(obj/over_object as obj) + if(!canremove) + return + + if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist + + if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why? + return + + if (!( istype(over_object, /obj/screen) )) + return ..() + + //makes sure that the thing is equipped, so that we can't drag it into our hand from miles away. + //there's got to be a better way of doing this. + if (!(src.loc == usr) || (src.loc && src.loc.loc == usr)) + return + + if (( usr.restrained() ) || ( usr.stat )) + return + + if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src)) + return + + switch(over_object.name) + if("r_hand") + usr.u_equip(src) + usr.put_in_r_hand(src) + if("l_hand") + usr.u_equip(src) + usr.put_in_l_hand(src) + src.add_fingerprint(usr) + +//Sets the welding state of the welding tool. If you see W.welding = 1 anywhere, please change it to W.setWelding(1) +//so that the welding tool updates accordingly +/obj/item/weapon/weldingtool/proc/setWelding(var/set_welding, var/mob/M) + if(!status) return + + var/turf/T = get_turf(src) + //If we're turning it on + if(set_welding && !welding) + if (get_fuel() > 0) + if(M) + to_chat(M, "You switch the [src] on.") + else if(T) + T.visible_message("\The [src] turns on.") + playsound(loc, acti_sound, 50, 1) + src.force = 15 + src.damtype = "fire" + src.w_class = ITEMSIZE_LARGE + src.hitsound = 'sound/items/welder.ogg' + welding = 1 + update_icon() + if(!always_process) + processing_objects |= src + else + if(M) + var/msg = max_fuel ? "welding fuel" : "charge" + to_chat(M, "You need more [msg] to complete this task.") + return + //Otherwise + else if(!set_welding && welding) + if(!always_process) + processing_objects -= src + if(M) + to_chat(M, "You switch \the [src] off.") + else if(T) + T.visible_message("\The [src] turns off.") + playsound(loc, deac_sound, 50, 1) + src.force = 3 + src.damtype = "brute" + src.w_class = initial(src.w_class) + src.welding = 0 + src.hitsound = initial(src.hitsound) + update_icon() + +//Decides whether or not to damage a player's eyes based on what they're wearing as protection +//Note: This should probably be moved to mob +/obj/item/weapon/weldingtool/proc/eyecheck(mob/living/carbon/user) + if(!istype(user)) + return 1 + var/safety = user.eyecheck() + safety = between(-1, safety + eye_safety_modifier, 2) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] + if(!E) + return + if(H.nif && H.nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) return //VOREStation Add - NIF + switch(safety) + if(1) + to_chat(usr, "Your eyes sting a little.") + E.damage += rand(1, 2) + if(E.damage > 12) + user.eye_blurry += rand(3,6) + if(0) + to_chat(usr, "Your eyes burn.") + E.damage += rand(2, 4) + if(E.damage > 10) + E.damage += rand(4,10) + if(-1) + to_chat(usr, "Your thermals intensify the welder's glow. Your eyes itch and burn severely.") + user.eye_blurry += rand(12,20) + E.damage += rand(12, 16) + if(safety<2) + + if(E.damage > 10) + to_chat(user, "Your eyes are really starting to hurt. This can't be good for you!") + + if (E.damage >= E.min_broken_damage) + to_chat(user, "You go blind!") + user.sdisabilities |= BLIND + else if (E.damage >= E.min_bruised_damage) + to_chat(user, "You go blind!") + user.Blind(5) + user.eye_blurry = 5 + user.disabilities |= NEARSIGHTED + spawn(100) + user.disabilities &= ~NEARSIGHTED + return + +/obj/item/weapon/weldingtool/is_hot() + return isOn() + +/obj/item/weapon/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + origin_tech = list(TECH_ENGINEERING = 2, TECH_PHORON = 2) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 60) + +/obj/item/weapon/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weapon/weldingtool/hugetank + name = "upgraded welding tool" + desc = "A much larger welder with a huge tank." + icon_state = "indwelder" + max_fuel = 80 + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_ENGINEERING = 3) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) + +/obj/item/weapon/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = ITEMSIZE_SMALL + matter = list(MAT_METAL = 30, MAT_GLASS = 10) + change_icons = 0 + toolspeed = 2 + eye_safety_modifier = 1 // Safer on eyes. + +/obj/item/weapon/weldingtool/alien + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + flame_color = "#6699FF" // Light bluish. + eye_safety_modifier = 2 + change_icons = 0 + origin_tech = list(TECH_PHORON = 5 ,TECH_ENGINEERING = 5) + always_process = TRUE + +/obj/item/weapon/weldingtool/alien/process() + if(get_fuel() <= get_max_fuel()) + reagents.add_reagent("fuel", 1) + ..() + +/obj/item/weapon/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of synthesizing its own fuel from waste compounds. It can output a flame hotter than regular welders." + icon_state = "exwelder" + max_fuel = 40 + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) + toolspeed = 0.5 + change_icons = 0 + flame_intensity = 3 + always_process = TRUE + var/nextrefueltick = 0 + +/obj/item/weapon/weldingtool/experimental/process() + ..() + if(get_fuel() < get_max_fuel() && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("fuel", 1) + +/* + * Backpack Welder. + */ + +/obj/item/weapon/weldingtool/tubefed + name = "tube-fed welding tool" + desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank." + icon_state = "tubewelder" + max_fuel = 10 + w_class = ITEMSIZE_NO_CONTAINER + matter = null + toolspeed = 1.25 + change_icons = 0 + flame_intensity = 1 + eye_safety_modifier = 1 + always_process = TRUE + var/obj/item/weapon/weldpack/mounted_pack = null + +/obj/item/weapon/weldingtool/tubefed/New(location) + ..() + if(istype(location, /obj/item/weapon/weldpack)) + var/obj/item/weapon/weldpack/holder = location + mounted_pack = holder + else + qdel(src) + +/obj/item/weapon/weldingtool/tubefed/Destroy() + mounted_pack.nozzle = null + mounted_pack = null + return ..() + +/obj/item/weapon/weldingtool/tubefed/process() + if(mounted_pack) + if(!istype(mounted_pack.loc,/mob/living/carbon/human)) + mounted_pack.return_nozzle() + else + var/mob/living/carbon/human/H = mounted_pack.loc + if(H.back != mounted_pack) + mounted_pack.return_nozzle() + + if(mounted_pack.loc != src.loc && src.loc != mounted_pack) + mounted_pack.return_nozzle() + visible_message("\The [src] retracts to its fueltank.") + + if(get_fuel() <= get_max_fuel()) + mounted_pack.reagents.trans_to_obj(src, 1) + + ..() + +/obj/item/weapon/weldingtool/tubefed/dropped(mob/user) + ..() + if(src.loc != user) + mounted_pack.return_nozzle() + to_chat(user, "\The [src] retracts to its fueltank.") + +/* + * Electric/Arc Welder + */ + +/obj/item/weapon/weldingtool/electric //AND HIS WELDING WAS ELECTRIC + name = "electric welding tool" + desc = "A welder which runs off of electricity." + icon_state = "arcwelder" + max_fuel = 0 //We'll handle the consumption later. + item_state = "ewelder" + var/obj/item/weapon/cell/power_supply //What type of power cell this uses + var/charge_cost = 24 //The rough equivalent of 1 unit of fuel, based on us wanting 10 welds per battery + var/cell_type = /obj/item/weapon/cell/device + var/use_external_power = 0 //If in a borg or hardsuit, this needs to = 1 + flame_color = "#00CCFF" // Blue-ish, to set it apart from the gas flames. + acti_sound = 'sound/effects/sparks4.ogg' + deac_sound = 'sound/effects/sparks4.ogg' + +/obj/item/weapon/weldingtool/electric/unloaded/New() + cell_type = null + +/obj/item/weapon/weldingtool/electric/New() + ..() + if(cell_type == null) + update_icon() + else if(cell_type) + power_supply = new cell_type(src) + else + power_supply = new /obj/item/weapon/cell/device(src) + update_icon() + +/obj/item/weapon/weldingtool/electric/get_cell() + return power_supply + +/obj/item/weapon/weldingtool/electric/examine(mob/user) + if(get_dist(src, user) > 1) + to_chat(user, desc) + else // The << need to stay, for some reason + if(power_supply) + user << text("\icon[] The [] has [] charge left.", src, src.name, get_fuel()) + else + user << text("\icon[] The [] has no power cell!", src, src.name) + +/obj/item/weapon/weldingtool/electric/get_fuel() + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(external) + return external.charge + else if(power_supply) + return power_supply.charge + else + return 0 + +/obj/item/weapon/weldingtool/electric/get_max_fuel() + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(external) + return external.maxcharge + else if(power_supply) + return power_supply.maxcharge + return 0 + +/obj/item/weapon/weldingtool/electric/remove_fuel(var/amount = 1, var/mob/M = null) + if(!welding) + return 0 + if(get_fuel() >= amount) + power_supply.checked_use(charge_cost) + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(!external || !external.use(charge_cost)) //Take power from the borg... + power_supply.give(charge_cost) //Give it back to the cell. + if(M) + eyecheck(M) + update_icon() + return 1 + else + if(M) + to_chat(M, "You need more energy to complete this task.") + update_icon() + return 0 + +/obj/item/weapon/weldingtool/electric/attack_hand(mob/user as mob) + if(user.get_inactive_hand() == src) + if(power_supply) + power_supply.update_icon() + user.put_in_hands(power_supply) + power_supply = null + to_chat(user, "You remove the cell from the [src].") + setWelding(0) + update_icon() + return + ..() + else + return ..() + +/obj/item/weapon/weldingtool/electric/attackby(obj/item/weapon/W, mob/user as mob) + if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/cell/device)) + if(!power_supply) + user.drop_item() + W.loc = src + power_supply = W + to_chat(user, "You install a cell in \the [src].") + update_icon() + else + to_chat(user, "\The [src] already has a cell.") + else + to_chat(user, "\The [src] cannot use that type of cell.") + else + ..() + +/obj/item/weapon/weldingtool/electric/proc/get_external_power_supply() + if(isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + return R.cell + if(istype(src.loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = src.loc + if(module.holder && module.holder.wearer) + var/mob/living/carbon/human/H = module.holder.wearer + if(istype(H) && H.back) + var/obj/item/weapon/rig/suit = H.back + if(istype(suit)) + return suit.cell + return null + +/obj/item/weapon/weldingtool/electric/mounted + use_external_power = 1 + +/obj/item/weapon/weldingtool/electric/mounted/cyborg + toolspeed = 0.5 + +#undef WELDER_FUEL_BURN_INTERVAL +======= +#define WELDER_FUEL_BURN_INTERVAL 13 +/* + * Welding Tool + */ +/obj/item/weapon/weldingtool + name = "\improper welding tool" + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + flags = CONDUCT + slot_flags = SLOT_BELT + + //Amount of OUCH when it's thrown + force = 3.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 5 + w_class = ITEMSIZE_SMALL + + //Cost to make in the autolathe + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 30) + + //R&D tech level + origin_tech = list(TECH_ENGINEERING = 1) + + //Welding tool specific stuff + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = 1 //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + usesound = 'sound/items/Welder2.ogg' + var/change_icons = TRUE + var/flame_intensity = 2 //how powerful the emitted light is when used. + var/flame_color = "#FF9933" // What color the welder light emits when its on. Default is an orange-ish color. + var/eye_safety_modifier = 0 // Increasing this will make less eye protection needed to stop eye damage. IE at 1, sunglasses will fully protect. + var/burned_fuel_for = 0 // Keeps track of how long the welder's been on, used to gradually empty the welder if left one, without RNG. + var/always_process = FALSE // If true, keeps the welder on the process list even if it's off. Used for when it needs to regenerate fuel. + toolspeed = 1 + +/obj/item/weapon/weldingtool/New() +// var/random_fuel = min(rand(10,20),max_fuel) + var/datum/reagents/R = new/datum/reagents(max_fuel) + reagents = R + R.my_atom = src + R.add_reagent("fuel", max_fuel) + update_icon() + if(always_process) + START_PROCESSING(SSobj, src) + ..() + +/obj/item/weapon/weldingtool/Destroy() + if(welding || always_process) + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/weapon/weldingtool/examine(mob/user) + if(..(user, 0)) + if(max_fuel) + to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel )) + +/obj/item/weapon/weldingtool/attack(atom/A, mob/living/user, def_zone) + if(ishuman(A) && user.a_intent == I_HELP) + var/mob/living/carbon/human/H = A + var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] + + if(!S || S.robotic < ORGAN_ROBOT || S.open == 3) + return ..() + + if(!welding) + to_chat(user, "You'll need to turn [src] on to patch the damage on [H]'s [S.name]!") + return 1 + + if(S.robo_repair(15, BRUTE, "some dents", src, user)) + remove_fuel(1, user) + return 1 + + return ..() + +/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob) + if(istype(W,/obj/item/weapon/tool/screwdriver)) + if(welding) + to_chat(user, "Stop welding first!") + return + status = !status + if(status) + to_chat(user, "You secure the welder.") + else + to_chat(user, "The welder can now be attached and modified.") + src.add_fingerprint(user) + return + + if((!status) && (istype(W,/obj/item/stack/rods))) + var/obj/item/stack/rods/R = W + R.use(1) + var/obj/item/weapon/flamethrower/F = new/obj/item/weapon/flamethrower(user.loc) + src.loc = F + F.weldtool = src + if (user.client) + user.client.screen -= src + if (user.r_hand == src) + user.remove_from_mob(src) + else + user.remove_from_mob(src) + src.master = F + src.layer = initial(src.layer) + user.remove_from_mob(src) + if (user.client) + user.client.screen -= src + src.loc = F + src.add_fingerprint(user) + return + + ..() + return + +/obj/item/weapon/weldingtool/process() + if(welding) + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + if(get_fuel() < 1) + setWelding(0) + //I'm not sure what this does. I assume it has to do with starting fires... + //...but it doesnt check to see if the welder is on or not. + var/turf/location = src.loc + if(istype(location, /mob/living)) + var/mob/living/M = location + if(M.item_is_in_hands(src)) + location = get_turf(M) + if (istype(location, /turf)) + location.hotspot_expose(700, 5) + +/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity) + if(!proximity) return + if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1) + if(!welding && max_fuel) + O.reagents.trans_to_obj(src, max_fuel) + to_chat(user, "Welder refueled") + playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) + return + else if(!welding) + to_chat(user, "[src] doesn't use fuel.") + return + else + message_admins("[key_name_admin(user)] triggered a fueltank explosion with a welding tool.") + log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.") + to_chat(user, "You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.") + var/obj/structure/reagent_dispensers/fueltank/tank = O + tank.explode() + return + if (src.welding) + remove_fuel(1) + var/turf/location = get_turf(user) + if(isliving(O)) + var/mob/living/L = O + L.IgniteMob() + if (istype(location, /turf)) + location.hotspot_expose(700, 50, 1) + return + + +/obj/item/weapon/weldingtool/attack_self(mob/user as mob) + setWelding(!welding, usr) + return + +//Returns the amount of fuel in the welder +/obj/item/weapon/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("fuel") + +/obj/item/weapon/weldingtool/proc/get_max_fuel() + return max_fuel + +//Removes fuel from the welding tool. If a mob is passed, it will perform an eyecheck on the mob. This should probably be renamed to use() +/obj/item/weapon/weldingtool/proc/remove_fuel(var/amount = 1, var/mob/M = null) + if(!welding) + return 0 + if(amount) + burned_fuel_for = 0 // Reset the counter since we're removing fuel. + if(get_fuel() >= amount) + reagents.remove_reagent("fuel", amount) + if(M) + eyecheck(M) + update_icon() + return 1 + else + if(M) + to_chat(M, "You need more welding fuel to complete this task.") + update_icon() + return 0 + +//Returns whether or not the welding tool is currently on. +/obj/item/weapon/weldingtool/proc/isOn() + return welding + +/obj/item/weapon/weldingtool/update_icon() + ..() + overlays.Cut() + // Welding overlay. + if(welding) + var/image/I = image(icon, src, "[icon_state]-on") + overlays.Add(I) + item_state = "[initial(item_state)]1" + else + item_state = initial(item_state) + + // Fuel counter overlay. + if(change_icons && get_max_fuel()) + var/ratio = get_fuel() / get_max_fuel() + ratio = CEILING(ratio * 4, 1) * 25 + var/image/I = image(icon, src, "[icon_state][ratio]") + overlays.Add(I) + + // Lights + if(welding && flame_intensity) + set_light(flame_intensity, flame_intensity, flame_color) + else + set_light(0) + +// icon_state = welding ? "[icon_state]1" : "[initial(icon_state)]" + var/mob/M = loc + if(istype(M)) + M.update_inv_l_hand() + M.update_inv_r_hand() + +/obj/item/weapon/weldingtool/MouseDrop(obj/over_object as obj) + if(!canremove) + return + + if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist + + if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why? + return + + if (!( istype(over_object, /obj/screen) )) + return ..() + + //makes sure that the thing is equipped, so that we can't drag it into our hand from miles away. + //there's got to be a better way of doing this. + if (!(src.loc == usr) || (src.loc && src.loc.loc == usr)) + return + + if (( usr.restrained() ) || ( usr.stat )) + return + + if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src)) + return + + switch(over_object.name) + if("r_hand") + usr.u_equip(src) + usr.put_in_r_hand(src) + if("l_hand") + usr.u_equip(src) + usr.put_in_l_hand(src) + src.add_fingerprint(usr) + +//Sets the welding state of the welding tool. If you see W.welding = 1 anywhere, please change it to W.setWelding(1) +//so that the welding tool updates accordingly +/obj/item/weapon/weldingtool/proc/setWelding(var/set_welding, var/mob/M) + if(!status) return + + var/turf/T = get_turf(src) + //If we're turning it on + if(set_welding && !welding) + if (get_fuel() > 0) + if(M) + to_chat(M, "You switch the [src] on.") + else if(T) + T.visible_message("\The [src] turns on.") + playsound(loc, acti_sound, 50, 1) + src.force = 15 + src.damtype = "fire" + src.w_class = ITEMSIZE_LARGE + src.hitsound = 'sound/items/welder.ogg' + welding = 1 + update_icon() + if(!always_process) + START_PROCESSING(SSobj, src) + else + if(M) + var/msg = max_fuel ? "welding fuel" : "charge" + to_chat(M, "You need more [msg] to complete this task.") + return + //Otherwise + else if(!set_welding && welding) + if(!always_process) + STOP_PROCESSING(SSobj, src) + if(M) + to_chat(M, "You switch \the [src] off.") + else if(T) + T.visible_message("\The [src] turns off.") + playsound(loc, deac_sound, 50, 1) + src.force = 3 + src.damtype = "brute" + src.w_class = initial(src.w_class) + src.welding = 0 + src.hitsound = initial(src.hitsound) + update_icon() + +//Decides whether or not to damage a player's eyes based on what they're wearing as protection +//Note: This should probably be moved to mob +/obj/item/weapon/weldingtool/proc/eyecheck(mob/living/carbon/user) + if(!istype(user)) + return 1 + var/safety = user.eyecheck() + safety = between(-1, safety + eye_safety_modifier, 2) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] + if(!E) + return + switch(safety) + if(1) + to_chat(usr, "Your eyes sting a little.") + E.damage += rand(1, 2) + if(E.damage > 12) + user.eye_blurry += rand(3,6) + if(0) + to_chat(usr, "Your eyes burn.") + E.damage += rand(2, 4) + if(E.damage > 10) + E.damage += rand(4,10) + if(-1) + to_chat(usr, "Your thermals intensify the welder's glow. Your eyes itch and burn severely.") + user.eye_blurry += rand(12,20) + E.damage += rand(12, 16) + if(safety<2) + + if(E.damage > 10) + to_chat(user, "Your eyes are really starting to hurt. This can't be good for you!") + + if (E.damage >= E.min_broken_damage) + to_chat(user, "You go blind!") + user.sdisabilities |= BLIND + else if (E.damage >= E.min_bruised_damage) + to_chat(user, "You go blind!") + user.Blind(5) + user.eye_blurry = 5 + user.disabilities |= NEARSIGHTED + spawn(100) + user.disabilities &= ~NEARSIGHTED + return + +/obj/item/weapon/weldingtool/is_hot() + return isOn() + +/obj/item/weapon/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + origin_tech = list(TECH_ENGINEERING = 2, TECH_PHORON = 2) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 60) + +/obj/item/weapon/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weapon/weldingtool/hugetank + name = "upgraded welding tool" + desc = "A much larger welder with a huge tank." + icon_state = "indwelder" + max_fuel = 80 + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_ENGINEERING = 3) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) + +/obj/item/weapon/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = ITEMSIZE_SMALL + matter = list(MAT_METAL = 30, MAT_GLASS = 10) + change_icons = 0 + toolspeed = 2 + eye_safety_modifier = 1 // Safer on eyes. + +/obj/item/weapon/weldingtool/alien + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + flame_color = "#6699FF" // Light bluish. + eye_safety_modifier = 2 + change_icons = 0 + origin_tech = list(TECH_PHORON = 5 ,TECH_ENGINEERING = 5) + always_process = TRUE + +/obj/item/weapon/weldingtool/alien/process() + if(get_fuel() <= get_max_fuel()) + reagents.add_reagent("fuel", 1) + ..() + +/obj/item/weapon/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of synthesizing its own fuel from waste compounds. It can output a flame hotter than regular welders." + icon_state = "exwelder" + max_fuel = 40 + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3) + matter = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120) + toolspeed = 0.5 + change_icons = 0 + flame_intensity = 3 + always_process = TRUE + var/nextrefueltick = 0 + +/obj/item/weapon/weldingtool/experimental/process() + ..() + if(get_fuel() < get_max_fuel() && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("fuel", 1) + +/* + * Backpack Welder. + */ + +/obj/item/weapon/weldingtool/tubefed + name = "tube-fed welding tool" + desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank." + icon_state = "tubewelder" + max_fuel = 10 + w_class = ITEMSIZE_NO_CONTAINER + matter = null + toolspeed = 1.25 + change_icons = 0 + flame_intensity = 1 + eye_safety_modifier = 1 + always_process = TRUE + var/obj/item/weapon/weldpack/mounted_pack = null + +/obj/item/weapon/weldingtool/tubefed/New(location) + ..() + if(istype(location, /obj/item/weapon/weldpack)) + var/obj/item/weapon/weldpack/holder = location + mounted_pack = holder + else + qdel(src) + +/obj/item/weapon/weldingtool/tubefed/Destroy() + mounted_pack.nozzle = null + mounted_pack = null + return ..() + +/obj/item/weapon/weldingtool/tubefed/process() + if(mounted_pack) + if(!istype(mounted_pack.loc,/mob/living/carbon/human)) + mounted_pack.return_nozzle() + else + var/mob/living/carbon/human/H = mounted_pack.loc + if(H.back != mounted_pack) + mounted_pack.return_nozzle() + + if(mounted_pack.loc != src.loc && src.loc != mounted_pack) + mounted_pack.return_nozzle() + visible_message("\The [src] retracts to its fueltank.") + + if(get_fuel() <= get_max_fuel()) + mounted_pack.reagents.trans_to_obj(src, 1) + + ..() + +/obj/item/weapon/weldingtool/tubefed/dropped(mob/user) + ..() + if(src.loc != user) + mounted_pack.return_nozzle() + to_chat(user, "\The [src] retracts to its fueltank.") + +/* + * Electric/Arc Welder + */ + +/obj/item/weapon/weldingtool/electric //AND HIS WELDING WAS ELECTRIC + name = "electric welding tool" + desc = "A welder which runs off of electricity." + icon_state = "arcwelder" + max_fuel = 0 //We'll handle the consumption later. + item_state = "ewelder" + var/obj/item/weapon/cell/power_supply //What type of power cell this uses + var/charge_cost = 24 //The rough equivalent of 1 unit of fuel, based on us wanting 10 welds per battery + var/cell_type = /obj/item/weapon/cell/device + var/use_external_power = 0 //If in a borg or hardsuit, this needs to = 1 + flame_color = "#00CCFF" // Blue-ish, to set it apart from the gas flames. + acti_sound = 'sound/effects/sparks4.ogg' + deac_sound = 'sound/effects/sparks4.ogg' + +/obj/item/weapon/weldingtool/electric/unloaded/New() + cell_type = null + +/obj/item/weapon/weldingtool/electric/New() + ..() + if(cell_type == null) + update_icon() + else if(cell_type) + power_supply = new cell_type(src) + else + power_supply = new /obj/item/weapon/cell/device(src) + update_icon() + +/obj/item/weapon/weldingtool/electric/get_cell() + return power_supply + +/obj/item/weapon/weldingtool/electric/examine(mob/user) + if(get_dist(src, user) > 1) + to_chat(user, desc) + else // The << need to stay, for some reason + if(power_supply) + user << text("\icon[] The [] has [] charge left.", src, src.name, get_fuel()) + else + user << text("\icon[] The [] has no power cell!", src, src.name) + +/obj/item/weapon/weldingtool/electric/get_fuel() + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(external) + return external.charge + else if(power_supply) + return power_supply.charge + else + return 0 + +/obj/item/weapon/weldingtool/electric/get_max_fuel() + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(external) + return external.maxcharge + else if(power_supply) + return power_supply.maxcharge + return 0 + +/obj/item/weapon/weldingtool/electric/remove_fuel(var/amount = 1, var/mob/M = null) + if(!welding) + return 0 + if(get_fuel() >= amount) + power_supply.checked_use(charge_cost) + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(!external || !external.use(charge_cost)) //Take power from the borg... + power_supply.give(charge_cost) //Give it back to the cell. + if(M) + eyecheck(M) + update_icon() + return 1 + else + if(M) + to_chat(M, "You need more energy to complete this task.") + update_icon() + return 0 + +/obj/item/weapon/weldingtool/electric/attack_hand(mob/user as mob) + if(user.get_inactive_hand() == src) + if(power_supply) + power_supply.update_icon() + user.put_in_hands(power_supply) + power_supply = null + to_chat(user, "You remove the cell from the [src].") + setWelding(0) + update_icon() + return + ..() + else + return ..() + +/obj/item/weapon/weldingtool/electric/attackby(obj/item/weapon/W, mob/user as mob) + if(istype(W, /obj/item/weapon/cell)) + if(istype(W, /obj/item/weapon/cell/device)) + if(!power_supply) + user.drop_item() + W.loc = src + power_supply = W + to_chat(user, "You install a cell in \the [src].") + update_icon() + else + to_chat(user, "\The [src] already has a cell.") + else + to_chat(user, "\The [src] cannot use that type of cell.") + else + ..() + +/obj/item/weapon/weldingtool/electric/proc/get_external_power_supply() + if(isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + return R.cell + if(istype(src.loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = src.loc + if(module.holder && module.holder.wearer) + var/mob/living/carbon/human/H = module.holder.wearer + if(istype(H) && H.back) + var/obj/item/weapon/rig/suit = H.back + if(istype(suit)) + return suit.cell + return null + +/obj/item/weapon/weldingtool/electric/mounted + use_external_power = 1 + +/obj/item/weapon/weldingtool/electric/mounted/cyborg + toolspeed = 0.5 + +#undef WELDER_FUEL_BURN_INTERVAL + +/obj/item/weapon/weldingtool/attack_self(mob/user) + setWelding(!welding, user) \ No newline at end of file diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index b5ae0912e9..65c61fce9d 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -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,"You are free of the net!") unbuckle_mob(A) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/effect/energy_net/process() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9c2fb60434..fd48ab1837 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -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) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 390ddc88a3..f4360f92cf 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -159,14 +159,14 @@ if(burning) burning = FALSE update_icon() - processing_objects -= src + STOP_PROCESSING(SSobj, src) visible_message("\The [src] stops burning.") /obj/structure/bonfire/proc/ignite() if(!burning && get_fuel_amount()) burning = TRUE update_icon() - processing_objects += src + START_PROCESSING(SSobj, src) visible_message("\The [src] starts burning!") /obj/structure/bonfire/proc/burn() @@ -342,14 +342,14 @@ if(burning) burning = FALSE update_icon() - processing_objects -= src + STOP_PROCESSING(SSobj, src) visible_message("\The [src] stops burning.") /obj/structure/fireplace/proc/ignite() if(!burning && get_fuel_amount()) burning = TRUE update_icon() - processing_objects += src + START_PROCESSING(SSobj, src) visible_message("\The [src] starts burning!") /obj/structure/fireplace/proc/burn() diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 2ff44ee9df..2ea6372aef 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -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() diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 4a858d5cce..8c2d8e70fd 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -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 diff --git a/code/game/objects/structures/props/nest.dm b/code/game/objects/structures/props/nest.dm index 89d94871ed..4cb515fc36 100644 --- a/code/game/objects/structures/props/nest.dm +++ b/code/game/objects/structures/props/nest.dm @@ -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. diff --git a/code/game/objects/structures/simple_doors.dm b/code/game/objects/structures/simple_doors.dm index 23e2ac1f76..f9d5b2250a 100644 --- a/code/game/objects/structures/simple_doors.dm +++ b/code/game/objects/structures/simple_doors.dm @@ -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 ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 005c8ac727..f4c35b6e04 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -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 diff --git a/code/global.dm b/code/global.dm index 686d555195..1f22567d8e 100644 --- a/code/global.dm +++ b/code/global.dm @@ -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() diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm index 26ffdade04..f8d853ca8c 100644 --- a/code/modules/alarm/alarm.dm +++ b/code/modules/alarm/alarm.dm @@ -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 diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm index a07ca8bd3b..d7a7cdf713 100644 --- a/code/modules/alarm/alarm_handler.dm +++ b/code/modules/alarm/alarm_handler.dm @@ -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) diff --git a/code/modules/artifice/deadringer.dm b/code/modules/artifice/deadringer.dm index c19da40873..bdac793daf 100644 --- a/code/modules/artifice/deadringer.dm +++ b/code/modules/artifice/deadringer.dm @@ -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() diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 8c965f0deb..317765be97 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -113,7 +113,7 @@ /obj/item/device/assembly/process() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 0cc5f49682..1a02474a8e 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -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 diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 849729f332..73574acd08 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -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 diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index c08b908dc4..a03130ea92 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -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 diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index cd4c253f66..c78a70b37d 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -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("[usr] moves their finger over [src]'s signal button...") diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index b8d0112066..488083d11a 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -25,10 +25,10 @@ /obj/item/device/assembly/timer/toggle_secure() secured = !secured if(secured) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else timing = 0 - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) update_icon() return secured diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index 32303eed8d..e859bdd237 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -167,11 +167,11 @@ return /obj/effect/blob/core/New(loc) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) return ..(loc) /obj/effect/blob/core/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/effect/blob/core/process() diff --git a/code/modules/blob2/blobs/core.dm b/code/modules/blob2/blobs/core.dm index fc4cbc7967..17ecd2429f 100644 --- a/code/modules/blob2/blobs/core.dm +++ b/code/modules/blob2/blobs/core.dm @@ -83,7 +83,7 @@ var/list/blob_cores = list() /obj/structure/blob/core/New(var/newloc, var/client/new_overmind = null, new_rate = 2, placed = 0) ..(newloc) blob_cores += src - processing_objects += src + START_PROCESSING(SSobj, src) update_icon() //so it atleast appears if(!placed && !overmind) create_overmind(new_overmind) @@ -97,7 +97,7 @@ var/list/blob_cores = list() overmind.blob_core = null qdel(overmind) overmind = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/structure/blob/core/update_icon() diff --git a/code/modules/blob2/blobs/node.dm b/code/modules/blob2/blobs/node.dm index 65d47fa1af..aa1dcb3e8f 100644 --- a/code/modules/blob2/blobs/node.dm +++ b/code/modules/blob2/blobs/node.dm @@ -12,12 +12,12 @@ var/list/blob_nodes = list() /obj/structure/blob/node/New(var/newloc) ..() blob_nodes += src - processing_objects += src + START_PROCESSING(SSobj, src) update_icon() /obj/structure/blob/node/Destroy() blob_nodes -= src - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/structure/blob/node/update_icon() diff --git a/code/modules/busy_space/air_traffic.dm b/code/modules/busy_space/air_traffic.dm index e90392d9d0..3eb9771ac0 100644 --- a/code/modules/busy_space/air_traffic.dm +++ b/code/modules/busy_space/air_traffic.dm @@ -17,7 +17,7 @@ var/datum/lore/atc_controller/atc = new/datum/lore/atc_controller next_message = world.time + rand(delay_min,delay_max) process() -/datum/lore/atc_controller/proc/process() +/datum/lore/atc_controller/process() if(world.time >= next_message) if(squelched) next_message = world.time + backoff_delay diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 9a2d3868dd..b706e71e9d 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -113,7 +113,7 @@ /obj/item/clothing/head/cakehat/process() if(!onfire) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return var/turf/location = src.loc @@ -131,7 +131,7 @@ force = 3 damtype = "fire" icon_state = "cake1" - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else force = null damtype = "brute" @@ -237,12 +237,12 @@ /obj/item/clothing/head/psy_crown/equipped(var/mob/living/carbon/human/H) ..() if(istype(H) && H.head == src && H.is_sentient()) - processing_objects += src + START_PROCESSING(SSobj, src) to_chat(H, flavor_equip) /obj/item/clothing/head/psy_crown/dropped(var/mob/living/carbon/human/H) ..() - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(H.is_sentient()) if(loc == H) // Still inhand. to_chat(H, flavor_unequip) @@ -250,7 +250,7 @@ to_chat(H, flavor_drop) /obj/item/clothing/head/psy_crown/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/clothing/head/psy_crown/process() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index da60d48940..854aa3456f 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -124,7 +124,7 @@ spark_system.set_up(5, 0, src) spark_system.attach(src) - processing_objects |= src + START_PROCESSING(SSobj, src) if(initial_modules && initial_modules.len) for(var/path in initial_modules) @@ -176,7 +176,7 @@ if(istype(M)) M.drop_from_inventory(piece) qdel(piece) - processing_objects -= src + STOP_PROCESSING(SSobj, src) qdel(wires) wires = null qdel(spark_system) diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 32eb1ad4f4..1ff202778c 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -34,7 +34,7 @@ update_name() /obj/item/weapon/reagent_containers/glass/rag/Destroy() - processing_objects -= src //so we don't continue turning to ash while gc'd + STOP_PROCESSING(SSobj, src) //so we don't continue turning to ash while gc'd return ..() /obj/item/weapon/reagent_containers/glass/rag/attack_self(mob/user as mob) @@ -187,14 +187,14 @@ qdel(src) return - processing_objects += src + START_PROCESSING(SSobj, src) set_light(2, null, "#E38F46") on_fire = 1 update_name() update_icon() /obj/item/weapon/reagent_containers/glass/rag/proc/extinguish() - processing_objects -= src + STOP_PROCESSING(SSobj, src) set_light(0) on_fire = 0 @@ -221,7 +221,7 @@ location.hotspot_expose(700, 5) if(burn_time <= 0) - processing_objects -= src + STOP_PROCESSING(SSobj, src) new /obj/effect/decal/cleanable/ash(location) qdel(src) return diff --git a/code/modules/detectivework/tools/uvlight.dm b/code/modules/detectivework/tools/uvlight.dm index 6997e3a04a..6d14b48087 100644 --- a/code/modules/detectivework/tools/uvlight.dm +++ b/code/modules/detectivework/tools/uvlight.dm @@ -21,12 +21,12 @@ on = !on if(on) set_light(range, 2, "#007fff") - processing_objects |= src + START_PROCESSING(SSobj, src) icon_state = "uv_on" else set_light(0) clear_last_scan() - processing_objects -= src + STOP_PROCESSING(SSobj, src) icon_state = "uv_off" /obj/item/device/uv_light/proc/clear_last_scan() diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm index 4912b238c8..5311cb28b4 100644 --- a/code/modules/events/event.dm +++ b/code/modules/events/event.dm @@ -94,7 +94,7 @@ //Do not override this proc, instead use 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) tick() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index e7f6e87aae..dee085dc2b 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -21,7 +21,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT var/last_world_time = 0 -/datum/event_container/proc/process() +/datum/event_container/process() if(!next_event_time) set_event_delay() diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index 534c5aa56d..e4c728f1df 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -23,7 +23,7 @@ /datum/event_manager/New() 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) E.process() diff --git a/code/modules/gamemaster/game_master.dm b/code/modules/gamemaster/game_master.dm index c435e868f6..16a6a03887 100644 --- a/code/modules/gamemaster/game_master.dm +++ b/code/modules/gamemaster/game_master.dm @@ -22,7 +22,7 @@ for(var/datum/gm_action/action in available_actions) action.gm = src -/datum/game_master/proc/process() +/datum/game_master/process() if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended) adjust_staleness(1) adjust_danger(-1) diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm index b0aaab0a7c..27e6347e5a 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/modules/hydroponics/seed_controller.dm @@ -131,7 +131,7 @@ var/global/datum/controller/plants/plant_controller // Set in New(). seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200) return seed -/datum/controller/plants/proc/process() +/datum/controller/plants/process() processing = 1 spawn(0) set background = 1 diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 7c6ad87a00..60a290924f 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -22,12 +22,12 @@ /obj/item/device/electronic_assembly/Initialize() battery = new(src) - processing_objects |= src + START_PROCESSING(SSobj, src) return ..() /obj/item/device/electronic_assembly/Destroy() battery = null // It will be qdel'd by ..() if still in our contents - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/device/electronic_assembly/process() diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index b03a5a2ada..c77b86efd4 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -85,17 +85,17 @@ /obj/item/integrated_circuit/time/ticker/Destroy() if(is_running) - processing_objects -= src + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/integrated_circuit/time/ticker/on_data_written() var/do_tick = get_pin_data(IC_INPUT, 1) if(do_tick && !is_running) is_running = TRUE - processing_objects |= src + START_PROCESSING(SSobj, src) else if(is_running) is_running = FALSE - processing_objects -= src + STOP_PROCESSING(SSobj, src) ticks_completed = 0 /obj/item/integrated_circuit/time/ticker/process() diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index 75acc807bc..bd44db119b 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -30,7 +30,7 @@ for (var/dir in cardinal) src.output = locate(/obj/machinery/mineral/output, get_step(src, dir)) if(src.output) break - processing_objects.Add(src) + START_PROCESSING(SSobj, src) return return diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 3779b7075f..25ee7c64be 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -23,10 +23,10 @@ var/list/holder_mob_icon_cache = list() /obj/item/weapon/holder/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/holder/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/holder/process() diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm index f4022366a8..53d3576125 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm @@ -13,7 +13,7 @@ /obj/item/alien_embryo/New() if(istype(loc, /mob/living)) affected_mob = loc - processing_objects.Add(src) + START_PROCESSING(SSobj, src) spawn(0) AddInfectionImages(affected_mob) else @@ -30,7 +30,7 @@ if(!affected_mob) return if(loc != affected_mob) affected_mob.status_flags &= ~(XENO_HOST) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) spawn(0) RemoveInfectionImages(affected_mob) affected_mob = null diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm index 7ba78df35c..a290996f7e 100644 --- a/code/modules/mob/living/carbon/metroid/items.dm +++ b/code/modules/mob/living/carbon/metroid/items.dm @@ -266,7 +266,7 @@ New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) process() var/mob/observer/dead/ghost @@ -366,11 +366,11 @@ /obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow() grown = 1 icon_state = "slime egg-grown" - processing_objects.Add(src) + START_PROCESSING(SSobj, src) return /obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) var/turf/T = get_turf(src) src.visible_message(" The [name] pulsates and quivers!") spawn(rand(50,100)) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index d52a5da531..c87fa7d88c 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -307,11 +307,11 @@ var/last_flash = 0 //Stores the time of last flash /obj/item/borg/combat/shield/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) ..() /obj/item/borg/combat/shield/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/borg/combat/shield/attack_self(var/mob/living/user) diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm new file mode 100644 index 0000000000..534bbf6000 --- /dev/null +++ b/code/modules/mob/living/simple_animal/animals/farm_animals.dm @@ -0,0 +1,292 @@ +//goat +/mob/living/simple_animal/retaliate/goat + name = "goat" + desc = "Not known for their pleasant disposition." + tt_desc = "E Oreamnos americanus" + icon_state = "goat" + icon_living = "goat" + icon_dead = "goat_dead" + + faction = "goat" + intelligence_level = SA_ANIMAL + + health = 40 + turns_per_move = 5 + see_in_dark = 6 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + melee_damage_lower = 1 + melee_damage_upper = 5 + attacktext = list("kicked") + + speak_chance = 1 + speak = list("EHEHEHEHEH","eh?") + speak_emote = list("brays") + emote_hear = list("brays") + emote_see = list("shakes its head", "stamps a foot", "glares around") + + meat_amount = 4 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/datum/reagents/udder = null + +/mob/living/simple_animal/retaliate/goat/New() + udder = new(50) + udder.my_atom = src + ..() + +/mob/living/simple_animal/retaliate/goat/Life() + . = ..() + if(.) + if(stat == CONSCIOUS) + if(udder && prob(5)) + udder.add_reagent("milk", rand(5, 10)) + + if(locate(/obj/effect/plant) in loc) + var/obj/effect/plant/SV = locate() in loc + SV.die_off(1) + + if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc) + var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc + qdel(SP) + + if(!pulledby) + var/obj/effect/plant/food + food = locate(/obj/effect/plant) in oview(5,loc) + if(food) + var/step = get_step_to(src, food, 0) + Move(step) + +/mob/living/simple_animal/retaliate/goat/react_to_attack() + . = ..() + if(.) + visible_message("[src] gets an evil-looking gleam in their eye.") + +/mob/living/simple_animal/retaliate/goat/Move() + ..() + if(!stat) + for(var/obj/effect/plant/SV in loc) + SV.die_off(1) + +/mob/living/simple_animal/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob) + var/obj/item/weapon/reagent_containers/glass/G = O + if(stat == CONSCIOUS && istype(G) && G.is_open_container()) + user.visible_message("[user] milks [src] using \the [O].") + var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) + if(G.reagents.total_volume >= G.volume) + user << "The [O] is full." + if(!transfered) + user << "The udder is dry. Wait a bit longer..." + else + ..() +//cow +/mob/living/simple_animal/cow + name = "cow" + desc = "Known for their milk, just don't tip them over." + tt_desc = "E Bos taurus" + icon_state = "cow" + icon_living = "cow" + icon_dead = "cow_dead" + icon_gib = "cow_gib" + intelligence_level = SA_ANIMAL + + health = 50 + turns_per_move = 5 + see_in_dark = 6 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + speak_chance = 1 + speak = list("moo?","moo","MOOOOOO") + speak_emote = list("moos","moos hauntingly") + emote_hear = list("brays") + emote_see = list("shakes its head") + + meat_amount = 6 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/datum/reagents/udder = null + +/mob/living/simple_animal/cow/New() + udder = new(50) + udder.my_atom = src + ..() + +/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob) + var/obj/item/weapon/reagent_containers/glass/G = O + if(stat == CONSCIOUS && istype(G) && G.is_open_container()) + user.visible_message("[user] milks [src] using \the [O].") + var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) + if(G.reagents.total_volume >= G.volume) + user << "The [O] is full." + if(!transfered) + user << "The udder is dry. Wait a bit longer..." + else + ..() + +/mob/living/simple_animal/cow/Life() + . = ..() + if(stat == CONSCIOUS) + if(udder && prob(5)) + udder.add_reagent("milk", rand(5, 10)) + +/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob) + if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead) + M.visible_message("[M] tips over [src].","You tip over [src].") + Weaken(30) + icon_state = icon_dead + spawn(rand(20,50)) + if(!stat && M) + icon_state = icon_living + var/list/responses = list( "[src] looks at you imploringly.", + "[src] looks at you pleadingly", + "[src] looks at you with a resigned expression.", + "[src] seems resigned to its fate.") + M << pick(responses) + else + ..() + +/mob/living/simple_animal/chick + name = "\improper chick" + desc = "Adorable! They make such a racket though." + tt_desc = "E Gallus gallus" + icon_state = "chick" + icon_living = "chick" + icon_dead = "chick_dead" + icon_gib = "chick_gib" + intelligence_level = SA_ANIMAL + + health = 1 + turns_per_move = 2 + + pass_flags = PASSTABLE | PASSGRILLE + mob_size = MOB_MINISCULE + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + has_langs = list("Bird") + speak_chance = 2 + speak = list("Cherp.","Cherp?","Chirrup.","Cheep!") + speak_emote = list("cheeps") + emote_hear = list("cheeps") + emote_see = list("pecks at the ground","flaps its tiny wings") + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/amount_grown = 0 + +/mob/living/simple_animal/chick/New() + ..() + pixel_x = rand(-6, 6) + pixel_y = rand(0, 10) + +/mob/living/simple_animal/chick/Life() + . =..() + if(!.) + return + if(!stat) + amount_grown += rand(1,2) + if(amount_grown >= 100) + new /mob/living/simple_animal/chicken(src.loc) + qdel(src) + +var/const/MAX_CHICKENS = 50 +var/global/chicken_count = 0 + +/mob/living/simple_animal/chicken + name = "\improper chicken" + desc = "Hopefully the eggs are good this season." + tt_desc = "E Gallus gallus" + icon_state = "chicken" + icon_living = "chicken" + icon_dead = "chicken_dead" + intelligence_level = SA_ANIMAL + + health = 10 + turns_per_move = 3 + pass_flags = PASSTABLE + mob_size = MOB_SMALL + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + attacktext = list("kicked") + + has_langs = list("Bird") + speak_chance = 2 + speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.") + speak_emote = list("clucks","croons") + emote_hear = list("clucks") + emote_see = list("pecks at the ground","flaps its wings viciously") + + meat_amount = 2 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/eggsleft = 0 + var/body_color + +/mob/living/simple_animal/chicken/New() + ..() + if(!body_color) + body_color = pick( list("brown","black","white") ) + icon_state = "chicken_[body_color]" + icon_living = "chicken_[body_color]" + icon_dead = "chicken_[body_color]_dead" + pixel_x = rand(-6, 6) + pixel_y = rand(0, 10) + chicken_count += 1 + +/mob/living/simple_animal/chicken/death() + ..() + chicken_count -= 1 + +/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O + if(G.seed && G.seed.kitchen_tag == "wheat") + if(!stat && eggsleft < 8) + user.visible_message("[user] feeds [O] to [name]! It clucks happily.","You feed [O] to [name]! It clucks happily.") + user.drop_item() + qdel(O) + eggsleft += rand(1, 4) + else + user << "[name] doesn't seem hungry!" + else + user << "[name] doesn't seem interested in that." + else + ..() + +/mob/living/simple_animal/chicken/Life() + . =..() + if(!.) + return + if(!stat && prob(3) && eggsleft > 0) + visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") + eggsleft-- + var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src)) + E.pixel_x = rand(-6,6) + E.pixel_y = rand(-6,6) + if(chicken_count < MAX_CHICKENS && prob(10)) + START_PROCESSING(SSobj, E) + +/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0 +/obj/item/weapon/reagent_containers/food/snacks/egg/process() + if(isturf(loc)) + amount_grown += rand(1,2) + if(amount_grown >= 100) + visible_message("[src] hatches with a quiet cracking sound.") + new /mob/living/simple_animal/chick(get_turf(src)) + STOP_PROCESSING(SSobj, src) + qdel(src) + else + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm index 775f9ae6cb..2bf3568287 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm @@ -72,7 +72,7 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have? E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) if(GLOB.chicken_count < GLOB.MAX_CHICKENS && prob(10)) - processing_objects.Add(E) + START_PROCESSING(SSobj, E) @@ -89,10 +89,10 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have? if(amount_grown >= 100) visible_message("[src] hatches with a quiet cracking sound.") new /mob/living/simple_mob/animal/passive/chick(get_turf(src)) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) qdel(src) else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d41314a69b..26ea108d38 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -682,14 +682,18 @@ stat("Location:", "([x], [y], [z]) [loc]") stat("CPU:","[world.cpu]") stat("Instances:","[world.contents.len]") + stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") if(statpanel("Processes")) if(processScheduler) processScheduler.statProcesses() if(statpanel("MC")) + stat("Location:", "([x], [y], [z]) [loc]") stat("CPU:","[world.cpu]") stat("Instances:","[world.contents.len]") + stat("World Time:", world.time) + stat("Real time of day:", REALTIMEOFDAY) stat(null) if(Master) Master.stat_entry() @@ -703,10 +707,10 @@ stat(null) for(var/datum/controller/subsystem/SS in Master.subsystems) SS.stat_entry() - + if(statpanel("Tickets")) GLOB.ahelp_tickets.stat_entry() - + if(listed_turf && client) if(!TurfAdjacent(listed_turf)) listed_turf = null diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index e1cb3a16c3..2ba47421a4 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -44,7 +44,7 @@ /datum/plane_holder/Destroy() my_mob = null - QDEL_NULL_LIST(plane_masters) //Goodbye my children, be free + QDEL_LIST_NULL(plane_masters) //Goodbye my children, be free return ..() /datum/plane_holder/proc/set_vis(var/which = null, var/state = FALSE) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index bada05e300..4e4dd6af5b 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -502,7 +502,7 @@ nanoui is used to open and update nano browser uis * * @return nothing */ -/datum/nanoui/proc/process(update = 0) +/datum/nanoui/process(update = 0) if (!src_object || !user) close() return diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index f07a6b3192..4acb0174f7 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -91,7 +91,7 @@ var/list/organ_cache = list() if(robotic < ORGAN_ROBOT) status |= ORGAN_DEAD damage = max_damage - processing_objects -= src + STOP_PROCESSING(SSobj, src) if(owner && vital) owner.death() owner.can_defib = 0 @@ -335,8 +335,13 @@ var/list/organ_cache = list() var/obj/item/organ/external/affected = owner.get_organ(parent_organ) if(affected) affected.internal_organs -= src +<<<<<<< HEAD loc = owner.drop_location() processing_objects |= src +======= + loc = get_turf(owner) + START_PROCESSING(SSobj, src) +>>>>>>> 2c4b5af... Merge pull request #5677 from kevinz000/PS_PORT_SCHEDULER rejecting = null var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list if(!organ_blood || !organ_blood.data["blood_DNA"]) @@ -367,7 +372,7 @@ var/list/organ_cache = list() owner = target loc = owner - processing_objects -= src + STOP_PROCESSING(SSobj, src) target.internal_organs |= src affected.internal_organs |= src target.internal_organs_by_name[organ_tag] = src diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm index d0761e4011..b797e0ea0f 100644 --- a/code/modules/overmap/ships/ship.dm +++ b/code/modules/overmap/ships/ship.dm @@ -24,7 +24,7 @@ if (H.z == map_z) nav_control = H break - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/map/ship/relaymove(mob/user, direction) accelerate(direction) diff --git a/code/modules/planet/planet.dm b/code/modules/planet/planet.dm index 0364056b69..587b2b5bcd 100644 --- a/code/modules/planet/planet.dm +++ b/code/modules/planet/planet.dm @@ -45,7 +45,7 @@ )) update_sun() -/datum/planet/proc/process(last_fire) +/datum/planet/process(last_fire) if(current_time) var/difference = world.time - last_fire current_time = current_time.add_seconds((difference / 10) * PLANET_TIME_MODIFIER) diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm index 541a023c4f..e81cea6e85 100644 --- a/code/modules/planet/weather.dm +++ b/code/modules/planet/weather.dm @@ -40,7 +40,7 @@ our_planet.update_sun() log_debug("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]°K ([temperature - T0C]°C | [temperature * 1.8 - 459.67]°F).") -/datum/weather_holder/proc/process() +/datum/weather_holder/process() if(world.time >= next_weather_shift) if(!current_weather) // Roundstart (hopefully). initialize_weather() diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 2a18becdc1..238aaa3196 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -34,11 +34,11 @@ charge = maxcharge update_icon() if(self_recharge) - processing_objects |= src + START_PROCESSING(SSobj, src) /obj/item/weapon/cell/Destroy() if(self_recharge) - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/cell/get_cell() diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index 0dbf5af7e0..f0eca3add6 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -117,7 +117,7 @@ catcher.SetSize(7) particle_catchers.Add(catcher) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/fusion_em_field/process() //make sure the field generator is still intact @@ -496,7 +496,7 @@ if(owned_core) owned_core.owned_field = null owned_core = null - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) . = ..() /obj/effect/fusion_em_field/bullet_act(var/obj/item/projectile/Proj) diff --git a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm index 57bf585e5b..4149274351 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm @@ -28,7 +28,7 @@ if(material.radioactivity) radioactivity = material.radioactivity desc += " It is warm to the touch." - processing_objects += src + START_PROCESSING(SSobj, src) if(material.luminescence) set_light(material.luminescence, material.luminescence, material.icon_colour) else @@ -49,7 +49,7 @@ radiation_repository.radiate(src, max(1,CEILING(radioactivity/30, 1))) /obj/item/weapon/fuel_assembly/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() // Mapper shorthand. diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 878e92b072..3768ab9535 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -37,14 +37,14 @@ GLOBAL_LIST_BOILERPLATE(all_singularities, /obj/singularity) energy = starting_energy ..() - processing_objects += src + START_PROCESSING(SSobj, src) for(var/obj/machinery/power/singularity_beacon/singubeacon in machines) if(singubeacon.active) target = singubeacon break /obj/singularity/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/singularity/attack_hand(mob/user as mob) diff --git a/code/modules/projectiles/ammunition/smartmag.dm b/code/modules/projectiles/ammunition/smartmag.dm index 4b42f18251..3668145b41 100644 --- a/code/modules/projectiles/ammunition/smartmag.dm +++ b/code/modules/projectiles/ammunition/smartmag.dm @@ -27,11 +27,11 @@ var/emagged = 0 // If you emag the smart mag, you can get the bullets out by clicking it /obj/item/ammo_magazine/smart/New() - processing_objects |= src + START_PROCESSING(SSobj, src) ..() /obj/item/ammo_magazine/smart/Destroy() - processing_objects -= src + STOP_PROCESSING(SSobj, src) ..() /obj/item/ammo_magazine/smart/process() diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 9cfd0d152a..4d0f014c93 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -27,7 +27,7 @@ ..() if(self_recharge) power_supply = new /obj/item/weapon/cell/device/weapon(src) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else if(cell_type) power_supply = new cell_type(src) @@ -38,7 +38,7 @@ /obj/item/weapon/gun/energy/Destroy() if(self_recharge) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/gun/energy/get_cell() @@ -181,7 +181,7 @@ if(power_supply == null) power_supply = new /obj/item/weapon/cell/device/weapon(src) self_recharge = 1 - processing_objects.Add(src) + START_PROCESSING(SSobj, src) update_icon() /obj/item/weapon/gun/energy/get_description_interaction() diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index 298098698e..2d1234e84f 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -23,14 +23,14 @@ fire_sound = 'sound/weapons/railgun.ogg' /obj/item/weapon/gun/magnetic/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) if(capacitor) power_per_tick = (power_cost*0.15) * capacitor.rating update_icon() . = ..() /obj/item/weapon/gun/magnetic/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) QDEL_NULL(cell) QDEL_NULL(loaded) QDEL_NULL(capacitor) diff --git a/code/modules/projectiles/guns/vox.dm b/code/modules/projectiles/guns/vox.dm index ccbfe300ec..9686c22711 100644 --- a/code/modules/projectiles/guns/vox.dm +++ b/code/modules/projectiles/guns/vox.dm @@ -20,11 +20,11 @@ /obj/item/weapon/gun/launcher/spikethrower/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) last_regen = world.time /obj/item/weapon/gun/launcher/spikethrower/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/gun/launcher/spikethrower/process() diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm index 76d1804265..b20720c125 100644 --- a/code/modules/projectiles/targeting/targeting_overlay.dm +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -89,7 +89,7 @@ aiming_at = null owner = null aiming_with = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() obj/aiming_overlay/proc/update_aiming_deferred() @@ -176,7 +176,7 @@ obj/aiming_overlay/proc/update_aiming_deferred() if(istype(aiming_with, /obj/item/weapon/gun)) playsound(get_turf(owner), 'sound/weapons/TargetOn.ogg', 50,1) forceMove(get_turf(target)) - processing_objects |= src + START_PROCESSING(SSobj, src) aiming_at.aimed |= src toggle_active(1) @@ -222,5 +222,5 @@ obj/aiming_overlay/proc/update_aiming_deferred() aiming_at.aimed -= src aiming_at = null loc = null - processing_objects -= src + STOP_PROCESSING(SSobj, src) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index b351dc290d..28838d362a 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -96,7 +96,7 @@ 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 var/list/reaction_limits = list() for(var/reactant in required_reagents) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index d5a1f0571a..20147cc738 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -42,10 +42,10 @@ var/datum/reagent/R = chemical_reagents_list[T] reagent_names += R.name - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/reagent_containers/borghypo/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) return ..() /obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg+ diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 7cc04c7251..428484ea66 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -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. //note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards. @@ -10,7 +14,7 @@ layer = ABOVE_TURF_LAYER anchored = 1 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/forwards // this is the default (forward) direction, set by the map dir var/backwards // hopefully self-explanatory @@ -36,7 +40,7 @@ backwards = turn(dir, 180) if(on) - operating = 1 + operating = FORWARDS setmove() component_parts = list() @@ -48,22 +52,23 @@ RefreshParts() /obj/machinery/conveyor/proc/setmove() - if(operating == 1) + if(operating == FORWARDS) movedir = forwards - else if(operating == -1) + else if(operating == BACKWARDS) movedir = backwards - else operating = 0 + else + operating = OFF update() /obj/machinery/conveyor/proc/update() if(stat & BROKEN) icon_state = "conveyor-broken" - operating = 0 + operating = OFF return if(!operable) - operating = 0 + operating = OFF if(stat & NOPOWER) - operating = 0 + operating = OFF icon_state = "conveyor[operating]" // machine process diff --git a/code/modules/shieldgen/directional_shield.dm b/code/modules/shieldgen/directional_shield.dm index 67e08a9e44..279580ce89 100644 --- a/code/modules/shieldgen/directional_shield.dm +++ b/code/modules/shieldgen/directional_shield.dm @@ -102,14 +102,14 @@ var/low_color = "#FF0000" // Color the shield will drift towards as health is lowered. Deep red. /obj/item/shield_projector/New() - processing_objects += src + START_PROCESSING(SSobj, src) if(always_on) create_shields() ..() /obj/item/shield_projector/Destroy() destroy_shields() - processing_objects -= src + STOP_PROCESSING(SSobj, src) return ..() /obj/item/shield_projector/proc/create_shield(var/newloc, var/new_dir) diff --git a/code/modules/shieldgen/handheld_defuser.dm b/code/modules/shieldgen/handheld_defuser.dm index d65a0060a8..7b4fdd786b 100644 --- a/code/modules/shieldgen/handheld_defuser.dm +++ b/code/modules/shieldgen/handheld_defuser.dm @@ -16,7 +16,7 @@ qdel(cell) cell = null if(enabled) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) . = ..() /obj/item/weapon/shield_diffuser/get_cell() @@ -42,9 +42,9 @@ enabled = !enabled update_icon() if(enabled) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) to_chat(usr, "You turn \the [src] [enabled ? "on" : "off"].") /obj/item/weapon/shield_diffuser/examine() diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index f8c1428310..0562bbd9ff 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -42,7 +42,7 @@ return ..() /obj/machinery/shield_gen/Destroy() - QDEL_NULL_LIST(field) + QDEL_LIST_NULL(field) return ..() /obj/machinery/shield_gen/emag_act(var/remaining_charges, var/mob/user) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 20d6cf23f9..4ce211ee72 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -37,7 +37,7 @@ supply_controller.shuttle = null . = ..() -/datum/shuttle/proc/process() +/datum/shuttle/process() return /datum/shuttle/proc/init_docking_controllers() diff --git a/code/modules/spells/spell_code.dm b/code/modules/spells/spell_code.dm index c1af923f72..3415ad0ead 100644 --- a/code/modules/spells/spell_code.dm +++ b/code/modules/spells/spell_code.dm @@ -64,7 +64,7 @@ var/list/spells = typesof(/spell) //needed for the badmin verb for now //still_recharging_msg = "[name] is still recharging." charge_counter = charge_max -/spell/proc/process() +/spell/process() spawn while(charge_counter < charge_max) charge_counter++ sleep(1) diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index 1b03157e83..3f7fb158aa 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -87,7 +87,7 @@ Notes: /datum/tooltip/proc/hide() if (queueHide) - schedule_task_with_source_in(1, src, .proc/do_hide) + addtimer(CALLBACK(src, .proc/do_hide), 1) else do_hide() diff --git a/code/modules/xenoarcheaology/effect.dm b/code/modules/xenoarcheaology/effect.dm index 9a19c75441..11c9ab01b4 100644 --- a/code/modules/xenoarcheaology/effect.dm +++ b/code/modules/xenoarcheaology/effect.dm @@ -60,7 +60,7 @@ /datum/artifact_effect/proc/DoEffectPulse(var/atom/holder) /datum/artifact_effect/proc/UpdateMove() -/datum/artifact_effect/proc/process() +/datum/artifact_effect/process() if(chargelevel < chargelevelmax) chargelevel++ diff --git a/code/modules/xenoarcheaology/finds/special.dm b/code/modules/xenoarcheaology/finds/special.dm index 0798b4fcfb..040c42e20f 100644 --- a/code/modules/xenoarcheaology/finds/special.dm +++ b/code/modules/xenoarcheaology/finds/special.dm @@ -7,7 +7,7 @@ /obj/item/weapon/reagent_containers/glass/replenishing/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) spawning_id = pick("blood","holywater","lube","stoxin","ethanol","ice","glycerol","fuel","cleaner") /obj/item/weapon/reagent_containers/glass/replenishing/process() @@ -22,7 +22,7 @@ var/max_stored_messages = 100 /obj/item/clothing/mask/gas/poltergeist/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/clothing/mask/gas/poltergeist/process() if(heard_talk.len && istype(src.loc, /mob/living) && prob(10)) @@ -56,7 +56,7 @@ /obj/item/weapon/vampiric/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/vampiric/process() //see if we've identified anyone nearby @@ -143,7 +143,7 @@ /obj/effect/decal/cleanable/blood/splatter/animated/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) loc_last_process = src.loc /obj/effect/decal/cleanable/blood/splatter/animated/process() @@ -173,7 +173,7 @@ density = 1 /obj/effect/shadow_wight/New() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/effect/shadow_wight/process() if(src.loc) @@ -197,7 +197,7 @@ M.sleeping = max(M.sleeping,rand(5,10)) src.loc = null else - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) /obj/effect/shadow_wight/Bump(var/atom/obstacle) obstacle << "You feel a chill run down your spine!" diff --git a/code/modules/xenoarcheaology/finds/talking.dm b/code/modules/xenoarcheaology/finds/talking.dm index 72ff1330de..01af7f7a0e 100644 --- a/code/modules/xenoarcheaology/finds/talking.dm +++ b/code/modules/xenoarcheaology/finds/talking.dm @@ -13,11 +13,11 @@ /datum/talking_atom/proc/init() if(holder_atom) - processing_objects.Add(src) + START_PROCESSING(SSobj, src) -/datum/talking_atom/proc/process() +/datum/talking_atom/process() if(!holder_atom) - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) else if(heard_words.len >= 1 && world.time > last_talk_time + talk_interval && prob(talk_chance)) SaySomething() diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index a7fdae7553..ce4427d595 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -34,7 +34,7 @@ /obj/item/weapon/anodevice/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob) if(istype(I, /obj/item/weapon/anobattery)) @@ -190,7 +190,7 @@ icon_state = "anodev[round(p,25)]" /obj/item/weapon/anodevice/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/weapon/anodevice/attack(mob/living/M as mob, mob/living/user as mob, def_zone) diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index 78a1a992e7..00eb61b79b 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -229,10 +229,10 @@ /obj/item/device/beacon_locator/New() ..() - processing_objects.Add(src) + START_PROCESSING(SSobj, src) /obj/item/device/beacon_locator/Destroy() - processing_objects.Remove(src) + STOP_PROCESSING(SSobj, src) ..() /obj/item/device/beacon_locator/process() @@ -254,7 +254,7 @@ if(prob(scan_ticks * 10)) spawn(0) set background = 1 - if(processing_objects.Find(src)) + if(is_processing) //scan radios in the world to try and find one var/cur_dist = 999 for(var/obj/item/device/radio/beacon/R in all_beacons) diff --git a/vorestation.dme b/vorestation.dme index 9edb170e38..e91120eb27 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -23,6 +23,7 @@ #include "code\world.dm" #include "code\__datastructures\globals.dm" #include "code\__defines\_compile_options.dm" +#include "code\__defines\_lists.dm" #include "code\__defines\_planes+layers.dm" #include "code\__defines\_planes+layers_vr.dm" #include "code\__defines\_tick.dm" @@ -38,6 +39,7 @@ #include "code\__defines\construction.dm" #include "code\__defines\damage_organs.dm" #include "code\__defines\dna.dm" +#include "code\__defines\flags.dm" #include "code\__defines\gamemode.dm" #include "code\__defines\holomap.dm" #include "code\__defines\integrated_circuits.dm" @@ -204,8 +206,8 @@ #include "code\controllers\Processes\event.dm" #include "code\controllers\Processes\game_master.dm" #include "code\controllers\Processes\nanoui.dm" -#include "code\controllers\Processes\obj.dm" #include "code\controllers\Processes\radiation.dm" +<<<<<<< HEAD:vorestation.dme #include "code\controllers\Processes\scheduler.dm" #include "code\controllers\Processes\supply.dm" #include "code\controllers\Processes\ticker.dm" @@ -232,8 +234,16 @@ #include "code\controllers\subsystems\shuttles.dm" #include "code\controllers\subsystems\sun.dm" #include "code\controllers\subsystems\transcore_vr.dm" +======= +#include "code\controllers\subsystems\sun.dm" +#include "code\controllers\subsystems\time_track.dm" +#include "code\controllers\subsystems\timer.dm" +>>>>>>> 2c4b5af... Merge pull request #5677 from kevinz000/PS_PORT_SCHEDULER:polaris.dme #include "code\controllers\subsystems\vote.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_laws.dm" #include "code\datums\beam.dm" @@ -292,7 +302,6 @@ #include "code\datums\observation\logged_in.dm" #include "code\datums\observation\moved.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\unequipped.dm" #include "code\datums\observation\~cleanup.dm"