diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index 846599534d..cbcf2c1dd9 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -1,9 +1,9 @@ -#define MC_TICK_CHECK ( ( world.tick_usage > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 ) +#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){\ - Master.current_ticklimit = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\ + Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\ --split_tick_phases;\ } else {\ Master.current_ticklimit = original_tick_limit;\ @@ -22,7 +22,7 @@ #define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = TRUE;Processor.processing += Datum} #define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = FALSE;Processor.processing -= Datum -//SubSystem flags_1 (Please design any new flags_1 so that the default is off, to make adding flags_1 to subsystems easier) +//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 diff --git a/code/__DEFINES/_tick.dm b/code/__DEFINES/_tick.dm new file mode 100644 index 0000000000..93ac8ed70d --- /dev/null +++ b/code/__DEFINES/_tick.dm @@ -0,0 +1,10 @@ +#define TICK_LIMIT_RUNNING 80 +#define TICK_LIMIT_TO_RUN 78 +#define TICK_LIMIT_MC 70 +#define TICK_LIMIT_MC_INIT_DEFAULT 98 + +#define TICK_USAGE world.tick_usage //for general usage +#define TICK_USAGE_REAL world.tick_usage //to be used where the result isn't checked + +#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit ) +#define CHECK_TICK if TICK_CHECK stoplag() diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm index 3e781da6cd..534e0d3608 100644 --- a/code/__DEFINES/math.dm +++ b/code/__DEFINES/math.dm @@ -1,25 +1,25 @@ -#define PI 3.1415 -#define SPEED_OF_LIGHT 3e8 //not exact but hey! -#define SPEED_OF_LIGHT_SQ 9e+16 -#define INFINITY 1e31 //closer then enough - -//atmos -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -#define TCMB 2.7 // -270.3degC - -//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks -//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) -//collapsed to percent_of_tick_used * tick_lag -#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) -#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage-starting_tickusage)) - -#define PERCENT(val) (round(val*100, 0.1)) -#define CLAMP01(x) (Clamp(x, 0, 1)) - -//time of day but automatically adjusts to the server going into the next day within the same round. -//for when you need a reliable time number that doesn't depend on byond time. -#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) -#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) +#define PI 3.1415 +#define SPEED_OF_LIGHT 3e8 //not exact but hey! +#define SPEED_OF_LIGHT_SQ 9e+16 +#define INFINITY 1e31 //closer then enough + +//atmos +#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) +#define ONE_ATMOSPHERE 101.325 //kPa +#define T0C 273.15 // 0degC +#define T20C 293.15 // 20degC +#define TCMB 2.7 // -270.3degC + +//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks +//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio) +//collapsed to percent_of_tick_used * tick_lag +#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag) +#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage)) + +#define PERCENT(val) (round(val*100, 0.1)) +#define CLAMP01(x) (Clamp(x, 0, 1)) + +//time of day but automatically adjusts to the server going into the next day within the same round. +//for when you need a reliable time number that doesn't depend on byond time. +#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK)) +#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers ) diff --git a/code/__DEFINES/tick.dm b/code/__DEFINES/tick.dm deleted file mode 100644 index 4c88fd643e..0000000000 --- a/code/__DEFINES/tick.dm +++ /dev/null @@ -1,7 +0,0 @@ -#define TICK_LIMIT_RUNNING 80 -#define TICK_LIMIT_TO_RUN 78 -#define TICK_LIMIT_MC 70 -#define TICK_LIMIT_MC_INIT_DEFAULT 98 - -#define TICK_CHECK ( world.tick_usage > Master.current_ticklimit ) -#define CHECK_TICK if TICK_CHECK stoplag() diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 1606a3da98..a05d52087f 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -357,6 +357,17 @@ Turf and target are separate in case you want to teleport some distance from a t var/M = E/(SPEED_OF_LIGHT_SQ) return M +//Takes the value of energy used/produced/ect. +//Returns a text value of that number in W, kW, MW, or GW. +/proc/DisplayPower(var/powerused) + if(powerused < 1000) //Less than a kW + return "[powerused] W" + else if(powerused < 1000000) //Less than a MW + return "[round((powerused * 0.001),0.01)] kW" + else if(powerused < 1000000000) //Less than a GW + return "[round((powerused * 0.000001),0.001)] MW" + return "[round((powerused * 0.000000001),0.0001)] GW" + /proc/key_name(whom, include_link = null, include_name = 1) var/mob/M var/client/C @@ -1230,7 +1241,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) //Increases delay as the server gets more overloaded, //as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful -#define DELTA_CALC max(((max(world.tick_usage, world.cpu) / 100) * max(Master.sleep_delta,1)), 1) +#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta,1)), 1) /proc/stoplag() if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT)) @@ -1242,7 +1253,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) . += round(i*DELTA_CALC) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 - while (world.tick_usage > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) + while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) #undef DELTA_CALC diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 3625e3e0df..6981748198 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -53,20 +53,24 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/restart_clear = 0 var/static/restart_timeout = 0 var/static/restart_count = 0 - + //current tick limit, assigned 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 = TICK_LIMIT_RUNNING /datum/controller/master/New() // Highlander-style: there can only be one! Kill off the old and replace it with the new. - subsystems = list() + var/list/_subsystems = list() + subsystems = _subsystems if (Master != src) if (istype(Master)) Recover() qdel(Master) else - init_subtypes(/datum/controller/subsystem, subsystems) + var/list/subsytem_types = subtypesof(/datum/controller/subsystem) + sortTim(subsytem_types, /proc/cmp_subsystem_init) + for(var/I in subsytem_types) + _subsystems += new I Master = src if(!GLOB) @@ -131,7 +135,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new FireHim = TRUE if(3) msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined." - BadBoy.flags_1 |= SS_NO_FIRE + BadBoy.flags |= SS_NO_FIRE if(msg) to_chat(GLOB.admins, "[msg]") log_world(msg) @@ -167,7 +171,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new // Initialize subsystems. current_ticklimit = config.tick_limit_mc_init for (var/datum/controller/subsystem/SS in subsystems) - if (SS.flags_1 & SS_NO_INIT) + if (SS.flags & SS_NO_INIT) continue SS.Initialize(REALTIMEOFDAY) CHECK_TICK @@ -232,13 +236,13 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/timer = world.time for (var/thing in subsystems) var/datum/controller/subsystem/SS = thing - if (SS.flags_1 & SS_NO_FIRE) + if (SS.flags & SS_NO_FIRE) continue SS.queued_time = 0 SS.queue_next = null SS.queue_prev = null SS.state = SS_IDLE - if (SS.flags_1 & SS_TICKER) + if (SS.flags & SS_TICKER) tickersubsystems += SS timer += world.tick_lag * rand(1, 5) SS.next_fire = timer @@ -284,7 +288,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //if there are mutiple sleeping procs running before us hogging the cpu, we have to run later // because sleeps are processed in the order received, so longer sleeps are more likely to run first - if (world.tick_usage > TICK_LIMIT_MC) + if (TICK_USAGE > TICK_LIMIT_MC) sleep_delta += 2 current_ticklimit = TICK_LIMIT_RUNNING * 0.5 sleep(world.tick_lag * (processing + sleep_delta)) @@ -293,7 +297,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new sleep_delta = MC_AVERAGE_FAST(sleep_delta, 0) if (last_run + (world.tick_lag * processing) > world.time) sleep_delta += 1 - if (world.tick_usage > (TICK_LIMIT_MC*0.5)) + if (TICK_USAGE > (TICK_LIMIT_MC*0.5)) sleep_delta += 1 if (make_runtime) @@ -371,7 +375,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new continue if (SS.next_fire > world.time) continue - SS_flags = SS.flags_1 + SS_flags = SS.flags if (SS_flags & SS_NO_FIRE) subsystemstocheck -= SS continue @@ -399,16 +403,16 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //keep running while we have stuff to run and we haven't gone over a tick // this is so subsystems paused eariler can use tick time that later subsystems never used - while (ran && queue_head && world.tick_usage < TICK_LIMIT_MC) + while (ran && queue_head && TICK_USAGE < TICK_LIMIT_MC) ran = FALSE bg_calc = FALSE current_tick_budget = queue_priority_count queue_node = queue_head while (queue_node) - if (ran && world.tick_usage > TICK_LIMIT_RUNNING) + if (ran && TICK_USAGE > TICK_LIMIT_RUNNING) break - queue_node_flags = queue_node.flags_1 + queue_node_flags = queue_node.flags queue_node_priority = queue_node.queued_priority //super special case, subsystems where we can't make them pause mid way through @@ -417,7 +421,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new //(unless we haven't even ran anything this tick, since its unlikely they will ever be able run // in those cases, so we just let them run) if (queue_node_flags & SS_NO_TICK_CHECK) - if (queue_node.tick_usage > TICK_LIMIT_RUNNING - world.tick_usage && ran_non_ticker) + if (queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker) queue_node.queued_priority += queue_priority_count * 0.10 queue_priority_count -= queue_node_priority queue_priority_count += queue_node.queued_priority @@ -429,7 +433,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new current_tick_budget = queue_priority_count_bg bg_calc = TRUE - tick_remaining = TICK_LIMIT_RUNNING - world.tick_usage + tick_remaining = TICK_LIMIT_RUNNING - TICK_USAGE if (current_tick_budget > 0 && queue_node_priority > 0) tick_precentage = tick_remaining / (current_tick_budget / queue_node_priority) @@ -438,7 +442,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun) - current_ticklimit = round(world.tick_usage + tick_precentage) + current_ticklimit = round(TICK_USAGE + tick_precentage) if (!(queue_node_flags & SS_TICKER)) ran_non_ticker = TRUE @@ -449,9 +453,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new queue_node.state = SS_RUNNING - tick_usage = world.tick_usage + tick_usage = TICK_USAGE var/state = queue_node.ignite(queue_node_paused) - tick_usage = world.tick_usage - tick_usage + tick_usage = TICK_USAGE - tick_usage if (state == SS_RUNNING) state = SS_IDLE diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 48a8d74616..8eb7392db8 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(air) init_order = INIT_ORDER_AIR priority = 20 wait = 5 - flags_1 = SS_BACKGROUND + flags = SS_BACKGROUND runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/cost_turfs = 0 @@ -71,65 +71,65 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/fire(resumed = 0) - var/timer = world.tick_usage + var/timer = TICK_USAGE_REAL if(currentpart == SSAIR_PIPENETS || !resumed) process_pipenets(resumed) - cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_ATMOSMACHINERY if(currentpart == SSAIR_ATMOSMACHINERY) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_atmos_machinery(resumed) - cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_ACTIVETURFS if(currentpart == SSAIR_ACTIVETURFS) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_active_turfs(resumed) - cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_EXCITEDGROUPS if(currentpart == SSAIR_EXCITEDGROUPS) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_excited_groups(resumed) - cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_HIGHPRESSURE if(currentpart == SSAIR_HIGHPRESSURE) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_high_pressure_delta(resumed) - cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_HOTSPOTS if(currentpart == SSAIR_HOTSPOTS) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_hotspots(resumed) - cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 currentpart = SSAIR_SUPERCONDUCTIVITY if(currentpart == SSAIR_SUPERCONDUCTIVITY) - timer = world.tick_usage + timer = TICK_USAGE_REAL process_super_conductivity(resumed) - cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(world.tick_usage - timer)) + cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) if(state != SS_RUNNING) return resumed = 0 diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 57760071d5..8502280aaf 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(garbage) name = "Garbage" priority = 15 wait = 20 - flags_1 = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT + flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object @@ -67,9 +67,9 @@ SUBSYSTEM_DEF(garbage) HandleToBeQueued() if(state == SS_RUNNING) HandleQueue() - + if (state == SS_PAUSED) //make us wait again before the next run. - state = SS_RUNNING + state = SS_RUNNING //If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond. //Don't attempt to optimize, not worth the effort. @@ -114,7 +114,7 @@ SUBSYSTEM_DEF(garbage) var/type = A.type testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --") didntgc["[type]"]++ - + HardDelete(A) ++delslasttick @@ -147,15 +147,15 @@ SUBSYSTEM_DEF(garbage) //this is purely to separate things profile wise. /datum/controller/subsystem/garbage/proc/HardDelete(datum/A) var/time = world.timeofday - var/tick = world.tick_usage + var/tick = TICK_USAGE var/ticktime = world.time - + var/type = A.type var/refID = "\ref[A]" - + del(A) - - tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100)) + + tick = (TICK_USAGE-tick+((world.time-ticktime)/world.tick_lag*100)) if (tick > highest_del_tickusage) highest_del_tickusage = tick time = world.timeofday - time @@ -167,7 +167,7 @@ SUBSYSTEM_DEF(garbage) log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)") message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).") postpone(time/5) - + /datum/controller/subsystem/garbage/proc/HardQueue(datum/A) if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) tobequeued += A diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index b1a115954a..ec34cfb8ed 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(server_maint) name = "Server Tasks" wait = 6 - flags_1 = SS_POST_FIRE_TIMING + flags = SS_POST_FIRE_TIMING priority = 10 init_order = INIT_ORDER_SERVER_MAINT runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(server_maint) qdel(C) if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))) - winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]") + winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check return diff --git a/code/modules/client/verbs/ping.dm b/code/modules/client/verbs/ping.dm index 41bd1b889c..de19d0d52c 100644 --- a/code/modules/client/verbs/ping.dm +++ b/code/modules/client/verbs/ping.dm @@ -9,7 +9,7 @@ avgping = MC_AVERAGE_SLOW(avgping, ping) /client/proc/pingfromtime(time) - return ((world.time+world.tick_lag*world.tick_usage/100)-time)*100 + return ((world.time+world.tick_lag*TICK_USAGE_REAL/100)-time)*100 /client/verb/display_ping(time as num) set instant = TRUE @@ -19,4 +19,4 @@ /client/verb/ping() set name = "Ping" set category = "OOC" - winset(src, null, "command=.display_ping+[world.time+world.tick_lag*world.tick_usage/100]") \ No newline at end of file + winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") \ No newline at end of file