diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 3c707b3da2e..b3f7c083b54 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -20,9 +20,7 @@ Pipelines + Other Objects -> Pipe network var/initialize_directions = 0 var/pipe_color var/obj/item/pipe/stored - var/welded = 0 //Used on pumps and scrubbers - var/global/list/iconsetids = list() var/global/list/pipeimages = list() @@ -36,11 +34,27 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/New() ..() - + SSair.atmos_machinery += src SetInitDirections() if(can_unwrench) stored = new(src, make_from=src) +/obj/machinery/atmospherics/Destroy() + SSair.atmos_machinery -= src + if (stored) + qdel(stored) + stored = null + ..() + +//this is called just after the air controller sets up turfs +/obj/machinery/atmospherics/proc/atmosinit() + return + +//object initializion. done well after air is setup (build_network needs all pipes to be init'ed with atmosinit before hand) +/obj/machinery/atmospherics/initialize() + ..() + build_network() //make sure to build our pipe nets + /obj/machinery/atmospherics/proc/SetInitDirections() return diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index a869677a1c4..0fb64c3b1c4 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -74,7 +74,7 @@ nullifyPipenet(parent2) ..() -/obj/machinery/atmospherics/binary/initialize() +/obj/machinery/atmospherics/binary/atmosinit() var/node2_connect = dir var/node1_connect = turn(dir, 180) @@ -93,6 +93,7 @@ showpipe = 1 update_icon() + ..() /obj/machinery/atmospherics/binary/construction() ..() diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index 675590c6796..0d93a55d0ad 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -50,7 +50,7 @@ else last_pressure_delta = 0 -/obj/machinery/atmospherics/binary/circulator/process() +/obj/machinery/atmospherics/binary/circulator/process_atmos() ..() update_icon() diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 81874319732..496d11b61ff 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -53,7 +53,7 @@ else icon_state = "vent_in" -/obj/machinery/atmospherics/binary/dp_vent_pump/process() +/obj/machinery/atmospherics/binary/dp_vent_pump/process_atmos() ..() if(!on) @@ -133,11 +133,15 @@ return 1 -/obj/machinery/atmospherics/binary/dp_vent_pump/initialize() +/obj/machinery/atmospherics/binary/dp_vent_pump/atmosinit() ..() if(frequency) set_frequency(frequency) +/obj/machinery/atmospherics/binary/dp_vent_pump/initialize() + ..() + broadcast_status() + /obj/machinery/atmospherics/binary/dp_vent_pump/receive_signal(datum/signal/signal) if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 24771a56241..756097050ff 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -32,7 +32,7 @@ Passive gate is similar to the regular pump except: if(on & !(stat & NOPOWER)) overlays += getpipeimage('icons/obj/atmospherics/binary_devices.dmi', "passgate_on") -/obj/machinery/atmospherics/binary/passive_gate/process() +/obj/machinery/atmospherics/binary/passive_gate/process_atmos() ..() if(!on) return 0 @@ -98,7 +98,7 @@ Passive gate is similar to the regular pump except: user << browse("[src.name] control[dat]", "window=atmo_pump") onclose(user, "atmo_pump") -/obj/machinery/atmospherics/binary/passive_gate/initialize() +/obj/machinery/atmospherics/binary/passive_gate/atmosinit() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index d9547e0a1c3..ec57b2c8f60 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -41,7 +41,7 @@ Thus, the two variables affect pump operation are set in New(): icon_state = "pump_[on?"on":"off"]" -/obj/machinery/atmospherics/binary/pump/process() +/obj/machinery/atmospherics/binary/pump/process_atmos() // ..() if(stat & (NOPOWER|BROKEN)) return 0 @@ -106,7 +106,7 @@ Thus, the two variables affect pump operation are set in New(): user << browse("[src.name] control[dat]", "window=atmo_pump") onclose(user, "atmo_pump") -/obj/machinery/atmospherics/binary/pump/initialize() +/obj/machinery/atmospherics/binary/pump/atmosinit() ..() if(frequency) set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index 380e1c16bfe..195215c2242 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -41,7 +41,7 @@ Thus, the two variables affect pump operation are set in New(): icon_state = "volpump_[on?"on":"off"]" -/obj/machinery/atmospherics/binary/volume_pump/process() +/obj/machinery/atmospherics/binary/volume_pump/process_atmos() // ..() if(stat & (NOPOWER|BROKEN)) return @@ -104,7 +104,7 @@ Thus, the two variables affect pump operation are set in New(): -/obj/machinery/atmospherics/binary/volume_pump/initialize() +/obj/machinery/atmospherics/binary/volume_pump/atmosinit() ..() set_frequency(frequency) diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm index 4f9a62ea92d..b506bf17071 100644 --- a/code/ATMOSPHERICS/components/portables_connector.dm +++ b/code/ATMOSPHERICS/components/portables_connector.dm @@ -24,7 +24,7 @@ state = "pipe_exposed" underlays += getpipeimage('icons/obj/atmospherics/binary_devices.dmi', state, initialize_directions, col) -/obj/machinery/atmospherics/unary/portables_connector/process() +/obj/machinery/atmospherics/unary/portables_connector/process_atmos() if(!connected_device) return parent.update = 1 diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 839d3ecde24..94aa810ef72 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -62,7 +62,7 @@ Filter types: if(old_stat != stat) update_icon() -/obj/machinery/atmospherics/trinary/filter/process() +/obj/machinery/atmospherics/trinary/filter/process_atmos() ..() if(!on) return 0 @@ -136,7 +136,7 @@ Filter types: return 1 -/obj/machinery/atmospherics/trinary/filter/initialize() +/obj/machinery/atmospherics/trinary/filter/atmosinit() set_frequency(frequency) return ..() diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index c70dce74cf9..669bc073bb8 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -40,7 +40,7 @@ ..() air3.volume = 300 -/obj/machinery/atmospherics/trinary/mixer/process() +/obj/machinery/atmospherics/trinary/mixer/process_atmos() ..() if(!on) return 0 diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 0db4482b153..c0faefa71d6 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -94,7 +94,7 @@ Housekeeping and pipe network stuff below nullifyPipenet(parent3) ..() -/obj/machinery/atmospherics/trinary/initialize() +/obj/machinery/atmospherics/trinary/atmosinit() //Mixer: //1 and 2 is input @@ -131,6 +131,7 @@ Housekeeping and pipe network stuff below break update_icon() + ..() /obj/machinery/atmospherics/trinary/construction() ..() diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index dd518949b65..23f54001d7f 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -22,7 +22,7 @@ return -/obj/machinery/atmospherics/unary/cold_sink/process() +/obj/machinery/atmospherics/unary/cold_sink/process_atmos() ..() if(!on) return 0 diff --git a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm index 1c85c1c2049..61a35798bbd 100644 --- a/code/ATMOSPHERICS/components/unary/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary/heat_exchanger.dm @@ -20,7 +20,7 @@ return -/obj/machinery/atmospherics/unary/heat_exchanger/initialize() +/obj/machinery/atmospherics/unary/heat_exchanger/atmosinit() if(!partner) var/partner_connect = turn(dir,180) @@ -32,7 +32,7 @@ ..() -/obj/machinery/atmospherics/unary/heat_exchanger/process() +/obj/machinery/atmospherics/unary/heat_exchanger/process_atmos() ..() if(!partner) return 0 diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 88e7e22e967..e24457b54ef 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -24,7 +24,7 @@ return -/obj/machinery/atmospherics/unary/heat_reservoir/process() +/obj/machinery/atmospherics/unary/heat_reservoir/process_atmos() ..() if(!on) return 0 diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 226c5dbc365..523c42439a0 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -38,7 +38,7 @@ update_icon() -/obj/machinery/atmospherics/unary/outlet_injector/process() +/obj/machinery/atmospherics/unary/outlet_injector/process_atmos() ..() injecting = 0 @@ -101,12 +101,14 @@ return 1 -/obj/machinery/atmospherics/unary/outlet_injector/initialize() +/obj/machinery/atmospherics/unary/outlet_injector/atmosinit() + set_frequency(frequency) ..() - set_frequency(frequency) - spawn(rand(25,50)) - broadcast_status() +/obj/machinery/atmospherics/unary/outlet_injector/initialize() + ..() + broadcast_status() + /obj/machinery/atmospherics/unary/outlet_injector/receive_signal(datum/signal/signal) if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) diff --git a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm index 0103a1966cd..75e71181778 100644 --- a/code/ATMOSPHERICS/components/unary/oxygen_generator.dm +++ b/code/ATMOSPHERICS/components/unary/oxygen_generator.dm @@ -28,7 +28,7 @@ air_contents.volume = 50 -/obj/machinery/atmospherics/unary/oxygen_generator/process() +/obj/machinery/atmospherics/unary/oxygen_generator/process_atmos() ..() if(!on) return 0 diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index 5c3286df0cf..ed6f483cd47 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -60,7 +60,7 @@ Housekeeping and pipe network stuff below ..() -/obj/machinery/atmospherics/unary/initialize() +/obj/machinery/atmospherics/unary/atmosinit() for(var/obj/machinery/atmospherics/target in get_step(src, dir)) if(target.initialize_directions & get_dir(target,src)) node = target @@ -68,6 +68,7 @@ Housekeeping and pipe network stuff below if(level == 2) showpipe = 1 update_icon() + ..() /obj/machinery/atmospherics/unary/construction() ..() diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 17076ed8694..e573ba60528 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -84,7 +84,7 @@ else icon_state = "vent_in" -/obj/machinery/atmospherics/unary/vent_pump/process() +/obj/machinery/atmospherics/unary/vent_pump/process_atmos() ..() if(stat & (NOPOWER|BROKEN)) return @@ -181,14 +181,16 @@ return 1 -/obj/machinery/atmospherics/unary/vent_pump/initialize() - ..() - +/obj/machinery/atmospherics/unary/vent_pump/atmosinit() //some vents work his own spesial way radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null if(frequency) set_frequency(frequency) + ..() +/obj/machinery/atmospherics/unary/vent_pump/initialize() + ..() + broadcast_status() /obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal) if(stat & (NOPOWER|BROKEN)) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index f9ccca6c829..a6fe9999dca 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -98,14 +98,18 @@ return 1 -/obj/machinery/atmospherics/unary/vent_scrubber/initialize() - ..() +/obj/machinery/atmospherics/unary/vent_scrubber/atmosinit() radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null if (frequency) set_frequency(frequency) + ..() +/obj/machinery/atmospherics/unary/vent_scrubber/initialize() + ..() + broadcast_status() -/obj/machinery/atmospherics/unary/vent_scrubber/process() + +/obj/machinery/atmospherics/unary/vent_scrubber/process_atmos() ..() if(stat & (NOPOWER|BROKEN)) return diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 25ee7f8c956..eb11358a81f 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -38,6 +38,7 @@ update_icon_nopipes() parent1.update = 0 parent2.update = 0 + parent1.reconcile_air() investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", "atmos") return @@ -64,7 +65,7 @@ close() else open() - parent1.reconcile_air() + /obj/machinery/atmospherics/binary/valve/digital // can be controlled by AI name = "digital valve" diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index d09df8ed19e..f2c7f6b5f8e 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -10,10 +10,10 @@ var/alert_pressure = 0 /datum/pipeline/New() - SSpipe.networks += src + SSair.networks += src /datum/pipeline/Destroy() - SSpipe.networks -= src + SSair.networks -= src if(air && air.volume) temporarily_store_air() for(var/obj/machinery/atmospherics/pipe/P in members) @@ -22,10 +22,11 @@ A.nullifyPipenet(src) ..() -/datum/pipeline/process()//This use to be called called from the pipe networks +/datum/pipeline/process() if(update) update = 0 reconcile_air() + return /* //Check to see if pressure is within acceptable limits diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index 678ef6660c0..8b264a7db2a 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -36,7 +36,7 @@ if(SOUTHWEST) initialize_directions_he = SOUTH|WEST -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/initialize() +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmosinit() normalize_dir() var/N = 2 for(var/D in cardinal) @@ -51,8 +51,9 @@ node2 = target break update_icon() + ..() -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process_atmos() var/environment_temperature = 0 var/datum/gas_mixture/pipe_air = return_air() @@ -69,15 +70,18 @@ parent.temperature_interact(loc, volume, thermal_conductivity) - //Burn any mobs buckled to ourselves based on our temperature + //heatup/cooldown any mobs buckled to ourselves based on our temperature if(buckled_mob) var/hc = pipe_air.heat_capacity() var/avg_temp = (pipe_air.temperature * hc + buckled_mob.bodytemperature * 3500) / (hc + 3500) pipe_air.temperature = avg_temp buckled_mob.bodytemperature = avg_temp +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process() + var/datum/gas_mixture/pipe_air = return_air() + //Burn any mobs buckled to ourselves based on our temperature + if(buckled_mob) var/heat_limit = 1000 - if(pipe_air.temperature > heat_limit + 1) buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, "chest") @@ -131,7 +135,7 @@ var/have_node2 = node2?1:0 icon_state = "exposed[have_node1][have_node2]" -/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/initialize() +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmosinit() for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions)) if(target.initialize_directions & get_dir(target,src)) node1 = target @@ -141,4 +145,4 @@ node2 = target break update_icon() - return \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index a11c06a97a3..8b80ff0b044 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -38,7 +38,7 @@ if(WEST) initialize_directions = NORTH|EAST|SOUTH -/obj/machinery/atmospherics/pipe/manifold/initialize() +/obj/machinery/atmospherics/pipe/manifold/atmosinit() for(var/D in cardinal) if(D == dir) continue @@ -54,6 +54,7 @@ var/turf/T = src.loc // hide if turf is not intact hide(T.intact) update_icon() + ..() /obj/machinery/atmospherics/pipe/manifold/Destroy() if(node1) diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index b1e8844c230..3a5ff5c735a 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -28,7 +28,7 @@ /obj/machinery/atmospherics/pipe/manifold4w/SetInitDirections() return -/obj/machinery/atmospherics/pipe/manifold4w/initialize() +/obj/machinery/atmospherics/pipe/manifold4w/atmosinit() for(var/D in cardinal) for(var/obj/machinery/atmospherics/target in get_step(src, D)) if(target.initialize_directions & get_dir(target,src)) @@ -45,6 +45,7 @@ var/turf/T = src.loc // hide if turf is not intact hide(T.intact) update_icon() + ..() /obj/machinery/atmospherics/pipe/manifold4w/hide(var/i) if(level == 1 && istype(loc, /turf/simulated)) diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm index 3ce6e094a79..ccd3e147980 100644 --- a/code/ATMOSPHERICS/pipes/simple.dm +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -53,7 +53,7 @@ The regular pipe you see everywhere, including bent ones. if(SOUTHWEST) initialize_directions = SOUTH|WEST -/obj/machinery/atmospherics/pipe/simple/initialize() +/obj/machinery/atmospherics/pipe/simple/atmosinit() normalize_dir() var/N = 2 for(var/D in cardinal) @@ -70,6 +70,7 @@ The regular pipe you see everywhere, including bent ones. var/turf/T = loc // hide if turf is not intact hide(T.intact) update_icon() + ..() /obj/machinery/atmospherics/pipe/simple/Destroy() if(node1) diff --git a/code/ATMOSPHERICS/pipes/vent.dm b/code/ATMOSPHERICS/pipes/vent.dm deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index a8e338695bf..8570657c508 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -30,7 +30,7 @@ if(air_contents.oxygen < 0.5 || air_contents.toxins < 0.5) return 0 - active_hotspot = new(src) + active_hotspot = PoolOrNew(/obj/effect/hotspot, src) active_hotspot.temperature = exposed_temperature active_hotspot.volume = exposed_volume @@ -142,16 +142,17 @@ // Garbage collect itself by nulling reference to it /obj/effect/hotspot/proc/Kill() - SSair.hotspots -= src - DestroyTurf() - qdel(src) + PlaceInPool(src) /obj/effect/hotspot/Destroy() + SSair.hotspots -= src + DestroyTurf() if(istype(loc, /turf/simulated)) var/turf/simulated/T = loc if(T.active_hotspot == src) T.active_hotspot = null loc = null + return QDEL_HINT_PUTINPOOL /obj/effect/hotspot/proc/DestroyTurf() diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index f5d7d5fd1c0..d0abe20a58a 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -66,7 +66,7 @@ turf/simulated/New() turf/simulated/Del() if(active_hotspot) - qdel(active_hotspot) + active_hotspot.Kill() ..() turf/simulated/assume_air(datum/gas_mixture/giver) @@ -274,11 +274,11 @@ atom/movable/var/pressure_resistance = 5 atom/movable/var/last_forced_movement = 0 atom/movable/proc/experience_pressure_difference(pressure_difference, direction) - if(last_forced_movement >= SSair.times_fired) + if(last_forced_movement >= world.time-10) return 0 else if(!anchored) if(pressure_difference > pressure_resistance) - last_forced_movement = SSair.times_fired + last_forced_movement = world.time spawn step(src, direction) return 1 diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm new file mode 100644 index 00000000000..feb949b3241 --- /dev/null +++ b/code/__DEFINES/qdel.dm @@ -0,0 +1,10 @@ +//defines that give qdel hints. these can be given as a return in destory() or by calling + + +#define QDEL_HINT_QUEUE 0 //qdel should queue the object for deletion. +#define QDEL_HINT_LETMELIVE 1 //qdel should let the object live after calling destory. +#define QDEL_HINT_IWILLGC 2 //functionally the same as the above. qdel should assume the object will gc on its own, and not check it. +#define QDEL_HINT_HARDDEL 3 //qdel should assume this object won't gc, and queue a hard delete using a hard reference. +#define QDEL_HINT_HARDDEL_NOW 4 //qdel should assume this object won't gc, and hard del it post haste. +#define QDEL_HINT_PUTINPOOL 5 //qdel will put this object in the atom pool. + diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index fbde37f1d94..db6eb9a1da7 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -200,5 +200,4 @@ Reharging stations are available in robotics, the dormitory's bathrooms. and the return usr.client.Click(master, location, control, params) /obj/screen/alert/Destroy() - PlaceInPool(src) - return 1 // Don't destroy me, I have a family! \ No newline at end of file + return QDEL_HINT_PUTINPOOL // Don't destroy me, I have a family! \ No newline at end of file diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index cd9aced630c..4b077ab2fc1 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -23,22 +23,31 @@ var/global/datum/controller/game_controller/master_controller = new() init_subtypes(/datum/subsystem, subsystems) master_controller = src + calculateGCD() + /* calculate the longest number of ticks the MC can wait between each cycle without causing subsystems to not fire on schedule -Note: you can set the datum's defined processing_interval to some integer to set an -absolute- minimum wait duration. */ +/datum/controller/game_controller/proc/calculateGCD() var/GCD for(var/datum/subsystem/SS in subsystems) if(SS.wait) - GCD = Gcd(SS.wait, GCD) + GCD = Gcd(round(SS.wait*10), GCD) GCD = round(GCD) - if(GCD > processing_interval) - processing_interval = GCD + if(GCD < world.tick_lag*10) + GCD = world.tick_lag*10 + processing_interval = GCD/10 -/datum/controller/game_controller/proc/setup() +/datum/controller/game_controller/proc/setup(zlevel) + if (zlevel && zlevel > 0 && zlevel <= world.maxz) + for(var/datum/subsystem/S in subsystems) + S.Initialize(world.timeofday, zlevel) + sleep(-1) + return world << "Initializing Subsystems..." + //sort subsystems by priority, so they initialize in the correct order sortTim(subsystems, /proc/cmp_subsystem_priority) @@ -49,7 +58,7 @@ Note: you can set the datum's defined processing_interval to some integer to set //Eventually all this other setup stuff should be contained in subsystems and done in subsystem.Initialize() for(var/datum/subsystem/S in subsystems) - S.Initialize(world.timeofday) + S.Initialize(world.timeofday, zlevel) sleep(-1) world << "Initializations complete" @@ -74,7 +83,6 @@ Note: you can set the datum's defined processing_interval to some integer to set SS.next_fire = timer var/start_time - var/cpu while(1) //far more efficient than recursively calling ourself if(processing_interval > 0) @@ -85,16 +93,19 @@ Note: you can set the datum's defined processing_interval to some integer to set for(var/datum/subsystem/SS in subsystems) if(SS.can_fire > 0) if(SS.next_fire <= world.time) - SS.next_fire += SS.wait - timer = world.timeofday - cpu = world.cpu last_thing_processed = SS.type SS.last_fire = world.time SS.fire() - SS.cpu = MC_AVERAGE(SS.cpu, world.cpu - cpu) SS.cost = MC_AVERAGE(SS.cost, world.timeofday - timer) + if (SS.dynamic_wait) + var/oldwait = SS.wait + SS.wait = min(max(round(SS.cost*SS.dwait_delta),SS.dwait_lower),SS.dwait_upper) + if (oldwait != SS.wait) + calculateGCD() + SS.next_fire += SS.wait ++SS.times_fired + sleep(-1) cost = MC_AVERAGE(cost, world.timeofday - start_time) @@ -108,7 +119,7 @@ Note: you can set the datum's defined processing_interval to some integer to set /datum/controller/game_controller/proc/roundHasStarted() for(var/datum/subsystem/SS in subsystems) SS.can_fire = 1 - SS.next_fire = world.time + SS.next_fire = world.time + rand(0,SS.wait) /datum/controller/game_controller/proc/Recover() var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n" diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 19c086efa23..0555e5e60ee 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -3,12 +3,19 @@ var/datum/subsystem/air/SSair /datum/subsystem/air name = "Air" priority = 20 + cost = 5 + wait = 5 + dynamic_wait = 1 + dwait_lower = 5 + dwait_upper = 50 var/cost_turfs = 0 var/cost_groups = 0 var/cost_highpressure = 0 var/cost_hotspots = 0 var/cost_superconductivity = 0 + var/cost_pipenets = 0 + var/cost_atmos_mechinery = 0 var/obj/effect/overlay/plasma_overlay //overlay for plasma var/obj/effect/overlay/sleeptoxin_overlay //overlay for sleeptoxin @@ -16,6 +23,9 @@ var/datum/subsystem/air/SSair var/list/excited_groups = list() var/list/active_turfs = list() var/list/hotspots = list() + var/list/networks = list() + var/list/obj/machinery/atmos_machinery = list() + //Special functions lists var/list/turf/simulated/active_super_conductivity = list() @@ -28,14 +38,39 @@ var/datum/subsystem/air/SSair plasma_overlay = new /obj/effect/overlay{icon='icons/effects/tile_effects.dmi';mouse_opacity=0;layer=5;icon_state="plasma"}() sleeptoxin_overlay = new /obj/effect/overlay{icon='icons/effects/tile_effects.dmi';mouse_opacity=0;layer=5;icon_state="sleeping_agent"}() +/datum/subsystem/air/stat_entry(msg) + msg += "C:{" + msg += "AT:[round(cost_turfs,0.01)]|" + msg += "EG:[round(cost_groups,0.01)]|" + msg += "HP:[round(cost_highpressure,0.01)]|" + msg += "HS:[round(cost_hotspots,0.01)]|" + msg += "SC:[round(cost_superconductivity,0.01)]|" + msg += "PN:[round(cost_pipenets,0.01)]|" + msg += "AM:[round(cost_atmos_mechinery,0.01)]" + msg += "} " + msg += "AT:[active_turfs.len]|" + msg += "EG:[excited_groups.len]|" + msg += "HS:[hotspots.len]|" + msg += "AS:[active_super_conductivity.len]" + ..(msg) -/datum/subsystem/air/Initialize() - setup_allturfs() + +/datum/subsystem/air/Initialize(timeofday, zlevel) + setup_allturfs(zlevel) + setup_atmos_machinery(zlevel) ..() #define MC_AVERAGE(average, current) (0.8*(average) + 0.2*(current)) /datum/subsystem/air/fire() var/timer = world.timeofday + process_pipenets() + cost_pipenets = MC_AVERAGE(cost_pipenets, (world.timeofday - timer)) + + timer = world.timeofday + process_atmos_mechinery() + cost_atmos_mechinery = MC_AVERAGE(cost_atmos_mechinery, (world.timeofday - timer)) + + timer = world.timeofday process_active_turfs() cost_turfs = MC_AVERAGE(cost_turfs, (world.timeofday - timer)) @@ -55,9 +90,29 @@ var/datum/subsystem/air/SSair process_super_conductivity() cost_superconductivity = MC_AVERAGE(cost_superconductivity, (world.timeofday - timer)) + #undef MC_AVERAGE + +/datum/subsystem/air/proc/process_pipenets() + var/i=1 + for(var/thing in networks) + if(thing) + thing:process() + ++i + continue + networks.Cut(i, i+1) + + +/datum/subsystem/air/proc/process_atmos_mechinery() + var/seconds = wait * 0.1 + for(var/obj/machinery/M in atmos_machinery) + if(M && (M.process_atmos(seconds) != PROCESS_KILL)) + continue + atmos_machinery.Remove(M) + + /datum/subsystem/air/proc/process_super_conductivity() for(var/turf/simulated/T in active_super_conductivity) T.super_conduct() @@ -102,9 +157,26 @@ var/datum/subsystem/air/SSair if(istype(S)) add_to_active(S) +/datum/subsystem/air/proc/process_excited_groups() + for(var/datum/excited_group/EG in excited_groups) + EG.breakdown_cooldown ++ + if(EG.breakdown_cooldown == 10) + EG.self_breakdown() + return + if(EG.breakdown_cooldown > 20) + EG.dismantle() -/datum/subsystem/air/proc/setup_allturfs() - for(var/turf/simulated/T in world) +/datum/subsystem/air/proc/setup_allturfs(z_level) + var/z_start = 1 + var/z_finish = world.maxz + if(1 <= z_level && z_level <= world.maxz) + z_level = round(z_level) + z_start = z_level + z_finish = z_level + + var/list/turfs_to_init = block(locate(1, 1, z_start), locate(world.maxx, world.maxy, z_finish)) + + for(var/turf/simulated/T in turfs_to_init) T.CalculateAdjacentTurfs() if(!T.blocks_air) if(T.air.check_tile_graphic()) @@ -124,11 +196,8 @@ var/datum/subsystem/air/SSair T.excited = 1 active_turfs |= T -/datum/subsystem/air/proc/process_excited_groups() - for(var/datum/excited_group/EG in excited_groups) - EG.breakdown_cooldown ++ - if(EG.breakdown_cooldown == 10) - EG.self_breakdown() - return - if(EG.breakdown_cooldown > 20) - EG.dismantle() \ No newline at end of file +/datum/subsystem/air/proc/setup_atmos_machinery(z_level) + for (var/obj/machinery/atmospherics/AM in atmos_machinery) + if (z_level && AM.z != z_level) + continue + AM.atmosinit() \ No newline at end of file diff --git a/code/controllers/subsystem/bots.dm b/code/controllers/subsystem/bots.dm index 5b49ac0fc08..3a4d79d1cf3 100644 --- a/code/controllers/subsystem/bots.dm +++ b/code/controllers/subsystem/bots.dm @@ -9,6 +9,9 @@ var/datum/subsystem/bots/SSbot /datum/subsystem/bots/New() NEW_SS_GLOBAL(SSbot) +/datum/subsystem/bots/stat_entry(msg) + ..("P:[processing.len]") + /datum/subsystem/bots/fire() var/seconds = wait * 0.1 var/i=1 diff --git a/code/controllers/subsystem/diseases.dm b/code/controllers/subsystem/diseases.dm index 1febced4242..d28785d947f 100644 --- a/code/controllers/subsystem/diseases.dm +++ b/code/controllers/subsystem/diseases.dm @@ -9,6 +9,8 @@ var/datum/subsystem/diseases/SSdisease /datum/subsystem/diseases/New() NEW_SS_GLOBAL(SSdisease) +/datum/subsystem/diseases/stat_entry(msg) + ..("P:[processing.len]") /datum/subsystem/diseases/fire() var/i=1 diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 929d2078bb2..e2dfe59a2eb 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -19,7 +19,9 @@ var/datum/subsystem/events/SSevent NEW_SS_GLOBAL(SSevent) -/datum/subsystem/events/Initialize() +/datum/subsystem/events/Initialize(time, zlevel) + if (zlevel) + return ..() for(var/type in typesof(/datum/round_event_control)) var/datum/round_event_control/E = new type() if(!E.typepath) diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 6ebee701170..a99ac70899f 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -3,79 +3,122 @@ var/datum/subsystem/garbage_collector/SSgarbage /datum/subsystem/garbage_collector name = "Garbage" can_fire = 1 - wait = 60 - priority = 21 + wait = 5 + priority = -1 - var/collection_timeout = 300 //deciseconds to wait to let running procs finish before we just say fuck it and force del() the object - var/max_checks_multiplier = 5 //multiplier (per-decisecond) for calculating max number of tests per SS tick. These tests check if our GC'd objects are actually GC'd - var/max_forcedel_multiplier = 1 //multiplier (per-decisecond) for calculating max number of force del() calls per SS tick. + var/collection_timeout = 300// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object + var/max_run_time = 2 // how long, in deciseconds, can we run before waiting for the next tick + var/delslasttick = 0 // number of del()'s we've done this tick + var/gcedlasttick = 0 // number of things that gc'ed last tick + var/totaldels = 0 + var/totalgcs = 0 - var/dels = 0 // number of del()'s we've done this tick - var/list/destroyed = list() // list of refID's of things that should be garbage collected + var/list/queue = list() // list of refID's of things that should be garbage collected // refID's are associated with the time at which they time out and need to be manually del() // we do this so we aren't constantly locating them and preventing them from being gc'd - var/list/logging = list() // list of all types that have failed to GC associated with the number of times that's happened. + + var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened. // the types are stored as strings + /datum/subsystem/garbage_collector/New() NEW_SS_GLOBAL(SSgarbage) +/datum/subsystem/garbage_collector/stat_entry(msg) + msg += "Q:[queue.len]|D:[delslasttick]|G:[gcedlasttick]|" + msg += "GR:" + if (!(delslasttick+gcedlasttick)) + msg += "n/a|" + else + msg += "[round((gcedlasttick/(delslasttick+gcedlasttick))*100, 0.01)]%|" + + msg += "TD:[totaldels]|TG:[totalgcs]|" + if (!(totaldels+totalgcs)) + msg += "n/a|" + else + msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%" + ..(msg) + /datum/subsystem/garbage_collector/fire() - dels = 0 - + delslasttick = 0 + gcedlasttick = 0 + var/time_to_stop = world.timeofday + max_run_time var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del() - var/checkRemain = max_checks_multiplier * wait - var/maxDels = max_forcedel_multiplier * wait - while(destroyed.len && --checkRemain >= 0) - if(dels >= maxDels) -// testing("GC: Reached max force dels per tick [dels] vs [GC_FORCE_DEL_PER_TICK]") - break // Server's already pretty pounded, everything else can wait 2 seconds - var/refID = destroyed[1] - var/GCd_at_time = destroyed[refID] + + while(queue.len && world.timeofday < time_to_stop) + var/refID = queue[1] + if (!refID) + queue.Cut(1, 2) + continue + + var/GCd_at_time = queue[refID] if(GCd_at_time > time_to_kill) -// testing("GC: [refID] not old enough, breaking at [world.time] for [GCd_at_time - time_to_kill] deciseconds until [GCd_at_time + GC_COLLECTION_TIMEOUT]") break // Everything else is newer, skip them - var/atom/A = locate(refID) -// testing("GC: [refID] old enough to test: GCd_at_time: [GCd_at_time] time_to_kill: [time_to_kill] current: [world.time]") - if(A && A.gc_destroyed == GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake - // Something's still referring to the qdel'd object. Kill it. - testing("GC: -- \ref[A] | [A.type] was unable to be GC'd and was deleted --") - logging["[A.type]"]++ + + var/atom/A + if (!istext(refID)) del(A) - ++dels -// else -// testing("GC: [refID] properly GC'd at [world.time] with timeout [GCd_at_time]") - destroyed.Cut(1, 2) + else + A = locate(refID) + if (A && A.gc_destroyed == GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake + // Something's still referring to the qdel'd object. Kill it. + testing("GC: -- \ref[A] | [A.type] was unable to be GC'd and was deleted --") + didntgc["[A.type]"]++ + del(A) + ++delslasttick + ++totaldels + else + ++gcedlasttick + ++totalgcs + + queue.Cut(1, 2) -/datum/subsystem/garbage_collector/proc/AddTrash(datum/A) - if(!istype(A) || !isnull(A.gc_destroyed)) +/datum/subsystem/garbage_collector/proc/Queue(datum/A, harddel = 0) + if (!istype(A) || !isnull(A.gc_destroyed)) return -// testing("GC: AddTrash([A.type])") A.gc_destroyed = world.time - destroyed -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list. - destroyed["\ref[A]"] = world.time + queue -= "\ref[A]" // Removing any previous references that were GC'd so that the current object will be at the end of the list. + queue["\ref[A]"] = world.time + +/datum/subsystem/garbage_collector/proc/HardQueue(datum/A, harddel = 0) + if (!istype(A) || !isnull(A.gc_destroyed)) + return + A.gc_destroyed = world.time + queue -= A // Removing any previous references that were GC'd so that the current object will be at the end of the list. + queue[A] = world.time // Should be treated as a replacement for the 'del' keyword. // Datums passed to this will be given a chance to clean up references to allow the GC to collect them. /proc/qdel(var/datum/A) - if(!A) + if (!A) return - if(!istype(A)) + if (!istype(A)) //warning("qdel() passed object of type [A.type]. qdel() can only handle /datum types.") del(A) - SSgarbage.dels++ - else if(isnull(A.gc_destroyed)) + else if (isnull(A.gc_destroyed)) // Let our friend know they're about to get fucked up. - . = !A.Destroy() - if(. && A) - if(!isturf(A)) - SSgarbage.AddTrash(A) - else + var/hint = A.Destroy() + if (!A) + return + switch (hint) + if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. + SSgarbage.Queue(A) + if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. + return + if (QDEL_HINT_IWILLGC) //functionally the same as the above. qdel should assume the object will gc on its own, and not check it. + return + if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete using a hard reference to save time from the locate() + SSgarbage.HardQueue(A) + if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. del(A) + if (QDEL_HINT_PUTINPOOL) //qdel will put this object in the pool. + PlaceInPool(A,0) + else + SSgarbage.Queue(A) // Default implementation of clean-up code. // This should be overridden to remove all references pointing to the object being destroyed. @@ -83,7 +126,7 @@ var/datum/subsystem/garbage_collector/SSgarbage /datum/proc/Destroy() //del(src) tag = null - return 0 + return QDEL_HINT_QUEUE /datum/var/gc_destroyed //Time when this object was destroyed. diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index a6ecefc1f02..9c99ca405a0 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -13,7 +13,9 @@ var/datum/subsystem/job/SSjob NEW_SS_GLOBAL(SSjob) -/datum/subsystem/job/Initialize() +/datum/subsystem/job/Initialize(timeofday, zlevel) + if (zlevel) + return ..() SetupOccupations() LoadJobs("config/jobs.txt") ..() diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 0aacf50f5b6..c2a0c3df334 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -6,6 +6,7 @@ var/datum/subsystem/lighting/SSlighting name = "Lighting" wait = 5 priority = 1 + dynamic_wait = 1 var/list/changed_lights = list() //list of all datum/light_source that need updating var/changed_lights_workload = 0 //stats on the largest number of lights (max changed_lights.len) @@ -20,7 +21,7 @@ var/datum/subsystem/lighting/SSlighting /datum/subsystem/lighting/stat_entry() - stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%) L:[round(changed_lights_workload,1)]/T:[round(changed_turfs_workload,1)]") + ..("L:[round(changed_lights_workload,1)]|T:[round(changed_turfs_workload,1)]") //Workhorse of lighting. It cycles through each light that needs updating. It updates their diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index 15976cf1b53..76e38207551 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -17,7 +17,7 @@ var/datum/subsystem/machines/SSmachine /datum/subsystem/machines/stat_entry() - stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%)\t[processing.len]") + ..("P:[processing.len]") /datum/subsystem/machines/fire() diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 064b8b2b5f5..9bae03b30a4 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -10,7 +10,7 @@ var/datum/subsystem/mobs/SSmob /datum/subsystem/mobs/stat_entry() - stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%) [mob_list.len]") + ..("P:[mob_list.len]") /datum/subsystem/mobs/fire() diff --git a/code/controllers/subsystem/nanoUI.dm b/code/controllers/subsystem/nanoUI.dm index e8452ce5054..017556248b5 100644 --- a/code/controllers/subsystem/nanoUI.dm +++ b/code/controllers/subsystem/nanoUI.dm @@ -30,11 +30,11 @@ var/datum/subsystem/nano/SSnano //Ignore directories if(copytext(filename, length(filename)) != "/") if(fexists(path + filename)) - asset_files.Add(fcopy_rsc(path + filename)) + asset_files.Add(fcopy_rsc(path + filename)) /datum/subsystem/nano/stat_entry() - stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%) [processing_uis.len]") + ..("P:[processing_uis.len]") /datum/subsystem/nano/fire() diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 92fbccae6b6..c9417029923 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -23,7 +23,7 @@ var/datum/subsystem/npcpool/SSbp /datum/subsystem/npcpool/stat_entry() - stat(name, "[round(cost,0.001)]ds (CPU:[round(cpu,1)]%) (T:[botPool_l.len + botPool_l_non.len] | D: [needsDelegate.len] | A: [needsAssistant.len + needsHelp_non.len] | U: [canBeUsed.len + canBeUsed_non.len])") + ..("T:[botPool_l.len + botPool_l_non.len]|D:[needsDelegate.len]|A:[needsAssistant.len + needsHelp_non.len]|U:[canBeUsed.len + canBeUsed_non.len]") /datum/subsystem/npcpool/fire() diff --git a/code/controllers/subsystem/objects.dm b/code/controllers/subsystem/objects.dm index 34104df2e0d..ccd49428120 100644 --- a/code/controllers/subsystem/objects.dm +++ b/code/controllers/subsystem/objects.dm @@ -13,16 +13,20 @@ var/datum/subsystem/objects/SSobj /datum/subsystem/objects/New() NEW_SS_GLOBAL(SSobj) -/datum/subsystem/objects/Initialize() +/datum/subsystem/objects/Initialize(timeofday, zlevel) for(var/atom/movable/AM in world) + if (zlevel && AM.z != zlevel) + continue AM.initialize() + if (zlevel) + return ..() for(var/turf/simulated/floor/F in world) F.MakeDirty() ..() /datum/subsystem/objects/stat_entry() - stat(name, "[round(cost,0.001)]ds\t(CPU:[round(cpu,1)]%)\t[processing.len]") + ..("P:[processing.len]") /datum/subsystem/objects/fire() @@ -35,12 +39,3 @@ var/datum/subsystem/objects/SSobj SSobj.processing.Cut(i, i+1) -/* This is FPSS13 code, has not yet been ported/implemented -/obj/New() - ..() - if(map_ready) - spawn(0) - if(garbage_collecting) - return - initialize() -*/ \ No newline at end of file diff --git a/code/controllers/subsystem/pipenets.dm b/code/controllers/subsystem/pipenets.dm deleted file mode 100644 index eb0c3fa5639..00000000000 --- a/code/controllers/subsystem/pipenets.dm +++ /dev/null @@ -1,36 +0,0 @@ -var/datum/subsystem/pipenets/SSpipe - -/datum/subsystem/pipenets - name = "Pipenets" - priority = 11 - - var/list/networks = list() - -/datum/subsystem/pipenets/New() - NEW_SS_GLOBAL(SSpipe) - -/datum/subsystem/pipenets/Initialize() - set background = BACKGROUND_ENABLED - - //is it possible to combine all these procs into initialize() ?? - for(var/obj/machinery/atmospherics/M in world) - M.build_network() - - for(var/obj/machinery/atmospherics/unary/U in world) - if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) - var/obj/machinery/atmospherics/unary/vent_pump/V = U - V.broadcast_status() - else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) - var/obj/machinery/atmospherics/unary/vent_scrubber/V = U - V.broadcast_status() - - ..() - -/datum/subsystem/pipenets/fire() - var/i=1 - for(var/thing in networks) - if(thing) - thing:process() - ++i - continue - networks.Cut(i, i+1) diff --git a/code/controllers/subsystem/power.dm b/code/controllers/subsystem/power.dm index e48a6f465e8..65f6fc16430 100644 --- a/code/controllers/subsystem/power.dm +++ b/code/controllers/subsystem/power.dm @@ -9,10 +9,25 @@ var/datum/subsystem/power/SSpower /datum/subsystem/power/New() NEW_SS_GLOBAL(SSpower) -/datum/subsystem/power/Initialize() - makepowernets() +/datum/subsystem/power/stat_entry(msg) + ..("P:[powernets.len]") + +/datum/subsystem/power/Initialize(timeofday, zlevel) + makepowernets(zlevel) ..() +// rebuild all power networks from scratch - only called at world creation or by the admin verb +/datum/subsystem/power/proc/makepowernets(zlevel) + for(var/datum/powernet/PN in powernets) + qdel(PN) + powernets.Cut() + + for(var/obj/structure/cable/PC in cable_list) + if(!PC.powernet) + var/datum/powernet/NewPN = new() + NewPN.add_cable(PC) + propagate_network(PC,PC.powernet) + /datum/subsystem/power/fire() for(var/datum/powernet/Powernet in powernets) Powernet.reset() \ No newline at end of file diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index 53c501c11ff..6d04a0f9c71 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -39,7 +39,9 @@ var/datum/subsystem/shuttle/SSshuttle NEW_SS_GLOBAL(SSshuttle) -/datum/subsystem/shuttle/Initialize() +/datum/subsystem/shuttle/Initialize(timeofday, zlevel) + if (zlevel) + return ..() if(!emergency) WARNING("No /obj/docking_port/mobile/emergency placed on the map!") if(!supply) diff --git a/code/controllers/subsystem/sun.dm b/code/controllers/subsystem/sun.dm index 8637aff5efd..d04b0369eed 100644 --- a/code/controllers/subsystem/sun.dm +++ b/code/controllers/subsystem/sun.dm @@ -19,6 +19,9 @@ var/datum/subsystem/sun/SSsun if(prob(50)) // same chance to rotate clockwise than counter-clockwise rate = -rate +/datum/subsystem/sun/stat_entry(msg) + ..("P:[solars.len]") + /datum/subsystem/sun/fire() angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c33ecb81ac9..815809cd9c6 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -37,6 +37,7 @@ var/datum/subsystem/ticker/ticker var/tipped = 0 //Did we broadcast the tip of the day yet? var/timeLeft = 1200 //pregame timer + var/delay_start = 0 //if set true, the pre-round countdown timer does not tick down. var/totalPlayers = 0 //used for pregame stats on statpanel var/totalPlayersReady = 0 //used for pregame stats on statpanel @@ -53,7 +54,9 @@ var/datum/subsystem/ticker/ticker round_end_sound = pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg','sound/misc/leavingtg.ogg') -/datum/subsystem/ticker/Initialize() +/datum/subsystem/ticker/Initialize(timeofday, zlevel) + if (zlevel) + return ..() if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() setupGenetics() @@ -78,7 +81,8 @@ var/datum/subsystem/ticker/ticker ++totalPlayersReady //countdown - timeLeft -= wait + if (!delay_end) + timeLeft -= wait if(timeLeft <= 30 && !tipped) send_random_tip() diff --git a/code/controllers/subsystems.dm b/code/controllers/subsystems.dm index 47eaadb43e5..4aac392f453 100644 --- a/code/controllers/subsystems.dm +++ b/code/controllers/subsystems.dm @@ -2,17 +2,20 @@ /datum/subsystem //things you will want to define - var/name //name of the subsystem - var/priority = 0 //priority affects order of initialization. Higher priorities are initialized first, lower priorities later. Can be decimal and negative values. - var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. + var/name //name of the subsystem + var/priority = 0 //priority affects order of initialization. Higher priorities are initialized first, lower priorities later. Can be decimal and negative values. + var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. + var/dynamic_wait = 0 //changes the wait based on the amount of time it took to process + var/dwait_upper = 20 //longest wait can be under dynamic_wait + var/dwait_lower = 5 //shortest wait can be under dynamic_wait + var/dwait_delta = 3 //How much should processing time effect dwait. or basically: wait = cost*dwait_delta //things you will probably want to leave alone - var/can_fire = 0 //prevent fire() calls - var/last_fire = 0 //last world.time we called fire() - var/next_fire = 0 //scheduled world.time for next fire() - var/cpu = 0 //cpu-usage stats (somewhat vague) - var/cost = 0 //average time to execute - var/times_fired = 0 //number of times we have called fire() + var/can_fire = 0 //prevent fire() calls + var/last_fire = 0 //last world.time we called fire() + var/next_fire = 0 //scheduled world.time for next fire() + var/cost = 0 //average time to execute + var/times_fired = 0 //number of times we have called fire() //used to initialize the subsystem BEFORE the map has loaded /datum/subsystem/New() @@ -25,15 +28,22 @@ can_fire = 0 //used to initialize the subsystem AFTER the map has loaded -/datum/subsystem/proc/Initialize(start_timeofday) +/datum/subsystem/proc/Initialize(start_timeofday, zlevel) var/time = (world.timeofday - start_timeofday) / 10 var/msg = "Initialized [name] SubSystem within [time] seconds" + if (zlevel) + testing(msg) + return world << "[msg]" world.log << msg //hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc. -/datum/subsystem/proc/stat_entry() - stat(name, "[round(cost,0.001)]ds\t(CPU:[round(cpu,1)]%)") +/datum/subsystem/proc/stat_entry(msg) + var/dwait = "" + if (dynamic_wait) + dwait = "DWait:[wait]ds " + + stat(name, "[round(cost,0.001)]ds\t[dwait][msg]") //could be used to postpone a costly subsystem for one cycle //for instance, during cpu intensive operations like explosions diff --git a/code/datums/debug.dm b/code/datums/debug.dm new file mode 100644 index 00000000000..28235903616 --- /dev/null +++ b/code/datums/debug.dm @@ -0,0 +1,2 @@ +/datum/debug + var/list/debuglist \ No newline at end of file diff --git a/code/datums/mixed.dm b/code/datums/mixed.dm deleted file mode 100644 index d54c5327ec5..00000000000 --- a/code/datums/mixed.dm +++ /dev/null @@ -1,30 +0,0 @@ -/datum/powernet - var/list/cables = list() // all cables & junctions - var/list/nodes = list() // all connected machines - - var/load = 0 // the current load on the powernet, increased by each machine at processing - var/newavail = 0 // what available power was gathered last tick, then becomes... - var/avail = 0 //...the current available power in the powernet - var/viewload = 0 // the load as it appears on the power console (gradually updated) - var/number = 0 // Unused //TODEL - var/netexcess = 0 // excess power on the powernet (typically avail-load) - -/*Powernet procs : - -In modules/power/power.dm : - -/datum/powernet/New() -/datum/powernet/Destroy() -/datum/powernet/proc/is_empty() -/datum/powernet/proc/remove_cable(var/obj/structure/cable/C) -/datum/powernet/proc/add_cable(var/obj/structure/cable/C) -/datum/powernet/proc/remove_machine(var/obj/machinery/power/M) -/datum/powernet/proc/add_machine(var/obj/machinery/power/M) -/datum/powernet/proc/reset() -/datum/powernet/proc/get_electrocute_damage() - - -*/ - -/datum/debug - var/list/debuglist \ No newline at end of file diff --git a/code/datums/spells/trigger.dm b/code/datums/spells/trigger.dm index 65205fc29f3..e8fbf90d805 100644 --- a/code/datums/spells/trigger.dm +++ b/code/datums/spells/trigger.dm @@ -12,10 +12,11 @@ var/spell_to_add = text2path(spell) new spell_to_add(src) //should result in adding to contents, needs testing -/obj/effect/proc_holder/spell/targeted/trigger/Destroy() //I think this entire proc is unnecessary but ok +/obj/effect/proc_holder/spell/targeted/trigger/Destroy() for(var/spell in contents) qdel(spell) - + linked_spells = null + starting_spells = null ..() /obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 86f153923a5..41ebb2b02b2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -82,6 +82,11 @@ qdel(AM) loc = null invisibility = 101 + if (pulledby) + if (pulledby.pulling == src) + pulledby.pulling = null + pulledby = null + // Previously known as HasEntered() // This is automatically called when something enters your square diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 04508a5e2d0..7dcd49f1821 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -113,6 +113,7 @@ /mob/living/simple_animal/hostile/blob/blobspore/Destroy() if(factory) factory.spores -= src + factory = null if(contents) for(var/mob/M in contents) M.loc = src.loc diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index b57568953fa..4988e1cedea 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -38,6 +38,7 @@ blob_cores -= src if(overmind) overmind.blob_core = null + overmind = null SSobj.processing.Remove(src) ..() diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index 872dafad212..3ab5874c176 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -17,6 +17,7 @@ for(var/mob/living/simple_animal/hostile/blob/blobspore/spore in spores) if(spore.factory == src) spore.factory = null + spores = null ..() /obj/effect/blob/factory/PulseAnimation(var/activate = 0) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index e9d0eb6217c..a9e9bb233ae 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -192,7 +192,7 @@ var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut (get_turf(B)) if(blobber) - B.Destroy() + qdel(B) blobber.color = blob_reagent_datum.color blobber.overmind = src blob_mobs.Add(blobber) @@ -243,7 +243,7 @@ src << "Unable to remove this blob." return - B.Destroy() + qdel(B) return diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 3364fe864a7..7c34125c02c 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -258,7 +258,7 @@ This is here to make the tiles around the station mininuke change when it's arme var/turf/disk_loc = get_turf(src) if(disk_loc.z > ZLEVEL_CENTCOM) get(src, /mob) << "You can't help but feel that you just lost something back there..." - Destroy() + qdel(src) /obj/item/weapon/disk/nuclear/Destroy() if(blobstart.len > 0) @@ -267,7 +267,7 @@ This is here to make the tiles around the station mininuke change when it's arme var/turf/diskturf = get_turf(src) message_admins("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z] - JMP). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - JMP).") log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).") - del(src) //Needed to clear all references to it + return QDEL_HINT_HARDDEL_NOW else ERROR("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.") - return 1 // Cancel destruction. + return QDEL_HINT_LETMELIVE // Cancel destruction. diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 12ee237aa0d..26ded6705f1 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -23,6 +23,7 @@ /obj/machinery/bluespace_beacon/Destroy() if(Beacon) qdel(Beacon) + Beacon = null ..() // update the invisibility and icon diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index c6c097368c8..66be318890e 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -113,6 +113,7 @@ ..() src.updateUsrDialog() + /obj/machinery/atmospherics/unary/cold_sink/freezer/power_change() ..() if(stat & NOPOWER) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 46230274a91..6020d4dad4d 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -29,7 +29,7 @@ obj/machinery/air_sensor obj/machinery/air_sensor/update_icon() icon_state = "gsensor[on]" -obj/machinery/air_sensor/process() +obj/machinery/air_sensor/process_atmos() if(on) var/datum/signal/signal = new signal.transmission_method = 1 //radio signal @@ -73,7 +73,7 @@ obj/machinery/air_sensor/initialize() obj/machinery/air_sensor/New() ..() - + SSair.atmos_machinery += src if(radio_controller) set_frequency(frequency) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 3004a7a4389..58e16afadee 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -18,6 +18,7 @@ var/release_log = "" var/update_flag = 0 + /obj/machinery/portable_atmospherics/canister/sleeping_agent name = "canister: \[N2O\]" icon_state = "redws" @@ -123,6 +124,7 @@ update_flag if (src.health <= 10) var/atom/location = src.loc location.assume_air(air_contents) + air_update_turf() src.destroyed = 1 playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3) @@ -138,9 +140,9 @@ update_flag else return 1 -/obj/machinery/portable_atmospherics/canister/process() +/obj/machinery/portable_atmospherics/canister/process_atmos() if (destroyed) - return + return PROCESS_KILL ..() @@ -174,9 +176,9 @@ update_flag can_label = 1 else can_label = 0 - +/obj/machinery/portable_atmospherics/canister/process() src.updateDialog() - return + return ..() /obj/machinery/portable_atmospherics/canister/return_air() return air_contents diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 059464d70e9..d8ba823694b 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -14,6 +14,7 @@ /obj/machinery/meter/New() ..() + SSair.atmos_machinery += src src.target = locate(/obj/machinery/atmospherics/pipe) in loc return 1 @@ -21,7 +22,7 @@ if (!target) src.target = locate(/obj/machinery/atmospherics/pipe) in loc -/obj/machinery/meter/process() +/obj/machinery/meter/process_atmos() if(!target) icon_state = "meterX" return 0 @@ -114,6 +115,7 @@ return 1 // TURF METER - REPORTS A TILE'S AIR CONTENTS +// why are you yelling? /obj/machinery/meter/turf/New() ..() diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index b2dac4a8317..25a2aa88a2d 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -10,25 +10,26 @@ var/destroyed = 0 var/maximum_pressure = 90*ONE_ATMOSPHERE + var/lastupdate = 0 /obj/machinery/portable_atmospherics/New() ..() - + SSair.atmos_machinery += src air_contents.volume = volume air_contents.temperature = T20C - return 1 -/obj/machinery/portable_atmospherics/process() - if(!connected_port) //only react when pipe_network will ont it do it for you +/obj/machinery/portable_atmospherics/process_atmos() + if(!connected_port) //only react when pipe_network will not it do it for you //Allow for reactions air_contents.react() else update_icon() - +/obj/machinery/portable_atmospherics/process() + return /obj/machinery/portable_atmospherics/Destroy() - del(air_contents) - + qdel(air_contents) + SSair.atmos_machinery -= src ..() /obj/machinery/portable_atmospherics/update_icon() diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 2b128e89f67..5f5519fa105 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -43,7 +43,7 @@ ..(severity) -/obj/machinery/portable_atmospherics/pump/process() +/obj/machinery/portable_atmospherics/pump/process_atmos() ..() if(on) var/datum/gas_mixture/environment @@ -85,7 +85,8 @@ air_contents.merge(removed) //src.update_icon() - +/obj/machinery/portable_atmospherics/pump/process() + ..() src.updateDialog() return diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index d3a59024b15..52cd6e636db 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -89,7 +89,7 @@ return -/obj/machinery/portable_atmospherics/scrubber/process() +/obj/machinery/portable_atmospherics/scrubber/process_atmos() ..() if(on) @@ -139,10 +139,15 @@ environment.merge(removed) else loc.assume_air(removed) - //src.update_icon() + +/obj/machinery/portable_atmospherics/scrubber/process_atmos() + ..() src.updateDialog() return + + + /obj/machinery/portable_atmospherics/scrubber/return_air() return air_contents diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm index 1ce8af7c88c..26bd2cff6c1 100644 --- a/code/game/machinery/atmoalter/zvent.dm +++ b/code/game/machinery/atmoalter/zvent.dm @@ -9,7 +9,7 @@ var/on = 0 var/volume_rate = 800 -/obj/machinery/zvent/process() +/obj/machinery/zvent/process_atmos() //all this object does, is make its turf share air with the ones above and below it, if they have a vent too. if (istype(loc,/turf/simulated)) //if we're not on a valid turf, forget it diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 9e33f0731db..cd6adb4f1e4 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -108,6 +108,8 @@ if(radio_controller) radio_controller.remove_object(src,beacon_freq) radio_controller.remove_object(src,control_freq) + qdel(Radio) + qdel(botcard) ..() /obj/machinery/bot/proc/add_to_beacons() //Master radio control for bots. Must be placed in the bot's local New() to support map spawned bots. diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 851bf6e643f..68cb12834c7 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -25,7 +25,7 @@ component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 1) - RefreshParts() + /obj/machinery/atmospherics/unary/cryo_cell/construction() ..(dir,dir) @@ -40,10 +40,19 @@ /obj/machinery/atmospherics/unary/cryo_cell/Destroy() var/turf/T = loc T.contents += contents - var/obj/item/weapon/reagent_containers/glass/B = beaker + if(beaker) - B.loc = get_step(loc, SOUTH) //Beaker is carefully ejected from the wreckage of the cryotube + beaker.loc = get_step(loc, SOUTH) //Beaker is carefully ejected from the wreckage of the cryotube + beaker = null ..() +/obj/machinery/atmospherics/unary/cryo_cell/process_atmos() + ..() + if(air_contents) + temperature_archived = air_contents.temperature + heat_gas_contents() + expel_gas() + if(abs(temperature_archived-air_contents.temperature) > 1) + parent.update = 1 /obj/machinery/atmospherics/unary/cryo_cell/process() ..() @@ -54,19 +63,13 @@ playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) if(!node || !is_operational()) return + if(!on) updateDialog() return - if(air_contents) - temperature_archived = air_contents.temperature - heat_gas_contents() - expel_gas() - - if(occupant) - process_occupant() - if(abs(temperature_archived-air_contents.temperature) > 1) - parent.update = 1 + if(air_contents && occupant) + process_occupant() updateDialog() return 1 diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 5db76850d2d..0264ae95312 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -17,6 +17,7 @@ /obj/machinery/door/airlock/alarmlock/Destroy() if(radio_controller) radio_controller.remove_object(src,air_frequency) + air_connection = null ..() /obj/machinery/door/airlock/alarmlock/initialize() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 93331e30e07..fc6dc1d20ab 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -22,9 +22,11 @@ density = 0 if(health == 0) playsound(src, "shatter", 70, 1) + electronics = null ..() + /obj/machinery/door/window/proc/open_and_close() open() if(src.check_access(null)) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 4949aa3024b..1755e4b2823 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -82,9 +82,12 @@ Class Procs: Called by machine to assign a value to the uid variable. process() 'game/machinery/machine.dm' - Called by the 'master_controller' once per game tick for each machine that is listed in the 'machines' list. + Called by the 'machinery subsystem' once per machinery tick for each machine that is listed in its 'machines' list. - is_operational() + process_atmos() + Called by the 'air subsystem' once per atmos tick for each machine that is listed in its 'atmos_machines' list. + + is_operational() Returns 0 if the machine is unpowered, broken or undergoing maintenance, something else if not Compiled by Aygar @@ -132,6 +135,9 @@ Class Procs: /obj/machinery/process()//If you dont use process or power why are you here return PROCESS_KILL +/obj/machinery/proc/process_atmos()//If you dont use process why are you here + return PROCESS_KILL + /obj/machinery/emp_act(severity) if(use_power && stat == 0) use_power(7500/severity) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 490280f4edc..41ebba50ddb 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -46,6 +46,7 @@ if(radio_controller) radio_controller.remove_object(src, freq) ..() + center = null // update the invisibility and icon /obj/machinery/magnetic_module/hide(var/intact) @@ -244,6 +245,8 @@ if(radio_controller) radio_controller.remove_object(src, frequency) ..() + magnets = null + rpath = null /obj/machinery/magnetic_controller/process() if(magnets.len == 0 && autolink) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index d374dfb6480..cd04b4d4a43 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -184,6 +184,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co /obj/machinery/newscaster/Destroy() allCasters -= src + viewing_channel = null + photo = null ..() /obj/machinery/newscaster/update_icon() diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 714d70e0907..188190756d7 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -143,6 +143,7 @@ /obj/machinery/porta_turret/Destroy() //deletes its own cover with it qdel(cover) + cover = null ..() diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 9692acc5ca6..2e8aeeecb69 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -142,6 +142,7 @@ /obj/machinery/shieldgen/Destroy() for(var/obj/machinery/shield/shield_tile in deployed_shields) qdel(shield_tile) + deployed_shields = null ..() diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 0c31ede202a..68d59a62423 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -20,6 +20,11 @@ /obj/machinery/computer/teleporter/initialize() link_power_station() +/obj/machinery/computer/teleporter/Destroy() + if (power_station) + power_station.teleporter_console = null + power_station = null + /obj/machinery/computer/teleporter/proc/link_power_station() if(power_station) return @@ -258,6 +263,11 @@ /obj/machinery/teleport/hub/initialize() link_power_station() +/obj/machinery/teleport/hub/Destroy() + if (power_station) + power_station.teleporter_hub = null + power_station = null + /obj/machinery/teleport/hub/RefreshParts() var/A = 0 for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) @@ -372,7 +382,12 @@ /obj/machinery/teleport/station/Destroy() if(teleporter_hub) + teleporter_hub.power_station = null teleporter_hub.update_icon() + teleporter_hub = null + if (teleporter_console) + teleporter_console.power_station = null + teleporter_console = null ..() /obj/machinery/teleport/station/attackby(var/obj/item/weapon/W, mob/user, params) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 705247d1ba8..5d3e4db3c85 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -82,6 +82,7 @@ coin = null ..() + /obj/machinery/vending/snack/Destroy() for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents) S.loc = get_turf(src) diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 52818f4c72a..15dadd6456d 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -23,6 +23,7 @@ /obj/mecha/combat/marauder/Destroy() qdel(smoke_system) + smoke_system = null ..() /obj/mecha/combat/marauder/seraph diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 6d62cbeebfb..9fdbd663d65 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -187,6 +187,7 @@ loc = null for (var/obj/structure/alien/weeds/W in range(1,T)) W.updateWeedOverlays() + linked_node = null ..() /obj/structure/alien/weeds/proc/Life() diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm index 4b51be4a825..5778ec117d5 100644 --- a/code/game/objects/effects/decals/Cleanable/aliens.dm +++ b/code/game/objects/effects/decals/Cleanable/aliens.dm @@ -16,6 +16,7 @@ /obj/effect/decal/cleanable/xenoblood/Destroy() for(var/datum/disease/D in viruses) D.cure(0) + viruses = null ..() /obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(var/list/directions) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index f7b073c5fc7..c2054cf07a0 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -14,6 +14,7 @@ /obj/effect/decal/cleanable/blood/Destroy() for(var/datum/disease/D in viruses) D.cure(0) + viruses = null ..() /obj/effect/decal/cleanable/blood/New() diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index c6bb4c6a737..71d209de6a6 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -106,6 +106,7 @@ /obj/effect/decal/cleanable/vomit/Destroy() for(var/datum/disease/D in viruses) D.cure(0) + viruses = null ..() /obj/effect/decal/cleanable/tomato_smudge diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 5f9eda868f6..d7710921b4e 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -58,6 +58,7 @@ /obj/effect/decal/cleanable/oil/Destroy() for(var/datum/disease/D in viruses) D.cure(0) + viruses = null ..() /obj/effect/decal/cleanable/oil/streak diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index e150828bc99..eb84812588f 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -15,8 +15,7 @@ would spawn and follow the beaker, even if it is carried or thrown. /obj/effect/effect/Destroy() ..() - PlaceInPool(src) - return 1 + return QDEL_HINT_PUTINPOOL /datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16) if(A.alpha == 0) //Handle already transparent case diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index d8a4a1804a6..2d7cba31150 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -227,9 +227,9 @@ R.my_atom = chemholder /datum/effect/effect/system/chem_smoke_spread/Destroy() - PlaceInPool(chemholder) chemholder = null ..() + return QDEL_HINT_PUTINPOOL /datum/effect/effect/system/chem_smoke_spread/set_up(var/datum/reagents/carry = null, n = 5, c = 0, loca, direct, silent = 0) if(n > 20) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index cf4b7fdab27..71c92fc3fe0 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -87,6 +87,9 @@ start_landmarks_list += src return 1 +/obj/effect/landmark/start/Destroy() + ..() + start_landmarks_list -= src //Costume spawner landmarks diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index ded891ee6cd..780c9a58ab8 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -33,6 +33,7 @@ else if(istype(creator, /obj/item/weapon/gun/energy/wormhole_projector)) var/obj/item/weapon/gun/energy/wormhole_projector/P = creator P.portal_destroyed(src) + creator = null return ..() /obj/effect/portal/proc/teleport(atom/movable/M as mob|obj) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 45efaba9b5e..5257103ec88 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -103,7 +103,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa if(T) if(flame_dist && prob(40) && !istype(T, /turf/space) && !T.density) - new/obj/effect/hotspot(T) //Mostly for ambience! + PoolOrNew(/obj/effect/hotspot, T) //Mostly for ambience! if(dist > 0) T.ex_act(dist) diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index b1ab40cb28b..2be31698d51 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -26,6 +26,7 @@ H.med_hud_set_status() spawn(0) RemoveInfectionImages(affected_mob) + affected_mob = null ..() /obj/item/body_egg/process() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index 64c7c3d270f..f4953c98812 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -49,7 +49,8 @@ qdel(expansion) expansion = null del(src) -/* Easier to just call del() than this nonsense +//Easier to just call del() than this nonsense +// ya no, del() takes 0.8ds to run on avg. this takes less than 0.01 get_cameras() for(var/cam_tag in bugged_cameras) var/obj/machinery/camera/camera = bugged_cameras[cam_tag] @@ -59,7 +60,7 @@ if(tracking) tracking = null ..() -*/ + /obj/item/device/camera_bug/interact(var/mob/user = usr) var/datum/browser/popup = new(user, "camerabug","Camera Bug",nref=src) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index f758904770d..f80ec37a5cf 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -25,8 +25,6 @@ return /obj/item/stack/Destroy() - if (is_cyborg) - return // Not supposed to be destroyed if (usr && usr.machine==src) usr << browse(null, "window=stack") src.loc = null diff --git a/code/game/pooling/atom_pool.dm b/code/game/pooling/atom_pool.dm index e35e80d4854..19bdbdf22b6 100644 --- a/code/game/pooling/atom_pool.dm +++ b/code/game/pooling/atom_pool.dm @@ -9,6 +9,17 @@ Creation/Deletion is laggy, so let's reduce reuse and recycle! Locked to /atom/movable and it's subtypes due to Loc being a const var on /atom but being read&write on /movable due to how they... move. +Usage: + +To get a object, just called PoolOrNew(type, list of args to pass to New) + +To put a object back in the pool, call place in pool. +This will call destroy on the object, set its loc to null, +and reset all of its vars to their default + +You can override your object's destroy to return QDEL_HINT_PLACEINPOOL +to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice) + */ var/global/list/GlobalPool = list() @@ -67,7 +78,7 @@ var/global/list/GlobalPool = list() -/proc/PlaceInPool(var/atom/movable/AM) +/proc/PlaceInPool(var/atom/movable/AM, destroy = 1) if(!istype(AM)) return @@ -79,7 +90,9 @@ var/global/list/GlobalPool = list() GlobalPool[AM.type] |= AM - AM.Destroy() + if (destroy) + AM.Destroy() + AM.ResetVars() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 7b5c0627eac..07f5ad2b6a9 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -18,6 +18,8 @@ if(config) if(config.starlight) update_starlight() +/turf/space/Destroy() + return QDEL_HINT_LETMELIVE /turf/space/proc/update_starlight() if(config) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 061a8db5665..424dcb2c80a 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -28,6 +28,8 @@ for(var/atom/movable/AM in src) Entered(AM) return +/turf/Destroy() + return QDEL_HINT_HARDDEL_NOW // Adds the adjacent turfs to the current atmos processing /turf/Del() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d9a4d08f85b..66c860357cb 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -581,6 +581,7 @@ var/global/floorIsLava = 0 set name="Start Now" if(ticker.current_state == GAME_STATE_PREGAME) ticker.can_fire = 1 + ticker.delay_start = 0 ticker.current_state = GAME_STATE_SETTING_UP log_admin("[usr.key] has started the game.") message_admins("[usr.key] has started the game.") @@ -637,8 +638,8 @@ var/global/floorIsLava = 0 set name="Delay" if(ticker.current_state > GAME_STATE_PREGAME) return alert("Too late... The game has already started!") - ticker.can_fire = !ticker.can_fire - if(!ticker.can_fire) + ticker.delay_start = !ticker.delay_start + if(!ticker.delay_start) world << "The game start has been delayed." log_admin("[key_name(usr)] delayed the game.") else diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index af5e35c3ff7..e5d19b4f1e7 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1099,8 +1099,8 @@ var/global/list/g_fancy_list_of_types = null var/dat = "List of things that failed to GC this round

" - for(var/path in SSgarbage.logging) - dat += "[path] - [SSgarbage.logging[path]] times
" + for(var/path in SSgarbage.didntgc) + dat += "[path] - [SSgarbage.didntgc[path]] times
" usr << browse(dat, "window=dellog") diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 803f7f5ab1a..9222cd16304 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -63,7 +63,7 @@ new_holder.mind.objectives += O new_holder.attack_log += "\[[time_stamp()]\] Won with greentext!!!" color_altered_mobs -= new_holder - Destroy() + qdel(src) if(last_holder && last_holder != new_holder) //Somehow it was swiped without ever getting dropped last_holder << "A sudden wave of failure washes over you..." diff --git a/code/modules/lighting/lighting_system.dm b/code/modules/lighting/lighting_system.dm index 7c7eb7264a5..0eaa7f94b23 100644 --- a/code/modules/lighting/lighting_system.dm +++ b/code/modules/lighting/lighting_system.dm @@ -224,7 +224,7 @@ anchored = 1 /atom/movable/light/Destroy() - return 1 + return QDEL_HINT_LETMELIVE /atom/movable/light/Move() return 0 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c1a0e21b364..e0269ea62f0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -49,6 +49,7 @@ /mob/living/carbon/human/Destroy() for(var/atom/movable/organelle in organs) qdel(organelle) + organs = list() return ..() /mob/living/carbon/human/Stat() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8c64cbf773e..5ef8323ec04 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -23,16 +23,16 @@ Sorry Giacom. Please don't be mad :( /mob/living/Destroy() - . = ..() + ..() for(var/mob/living/simple_animal/drone/D in player_list) for(var/image/I in staticOverlays) D.staticOverlays.Remove(I) D.client.images.Remove(I) - del(I) + qdel(I) staticOverlays.len = 0 - del(src) + return QDEL_HINT_HARDDEL_NOW /mob/living/proc/generateStaticOverlay() diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index d24c734f219..33ba6d1056f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -59,6 +59,7 @@ /mob/living/silicon/ai/Destroy() eyeobj.ai = null qdel(eyeobj) // No AI, no Eye + eyeobj = null ..() /atom/proc/move_camera_by_click() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index da4cfbc7225..6468170f288 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -216,17 +216,7 @@ return . -// rebuild all power networks from scratch - only called at world creation or by the admin verb -/datum/subsystem/power/proc/makepowernets() - for(var/datum/powernet/PN in powernets) - del(PN) - powernets.Cut() - for(var/obj/structure/cable/PC in cable_list) - if(!PC.powernet) - var/datum/powernet/NewPN = new() - NewPN.add_cable(PC) - propagate_network(PC,PC.powernet) //remove the old powernet and replace it with a new one throughout the network. /proc/propagate_network(var/obj/O, var/datum/powernet/PN) @@ -350,87 +340,6 @@ cell.use(drained_energy) return drained_energy -//////////////////////////////////////////// -// POWERNET DATUM PROCS -// each contiguous network of cables & nodes -//////////////////////////////////////////// - -/datum/powernet/New() - SSpower.powernets += src - -/datum/powernet/Destroy() - SSpower.powernets -= src - -/datum/powernet/proc/is_empty() - return !cables.len && !nodes.len - -//remove a cable from the current powernet -//if the powernet is then empty, delete it -//Warning : this proc DON'T check if the cable exists -/datum/powernet/proc/remove_cable(var/obj/structure/cable/C) - cables -= C - C.powernet = null - if(is_empty())//the powernet is now empty... - qdel(src)///... delete it - -//add a cable to the current powernet -//Warning : this proc DON'T check if the cable exists -/datum/powernet/proc/add_cable(var/obj/structure/cable/C) - if(C.powernet)// if C already has a powernet... - if(C.powernet == src) - return - else - C.powernet.remove_cable(C) //..remove it - C.powernet = src - cables +=C - -//remove a power machine from the current powernet -//if the powernet is then empty, delete it -//Warning : this proc DON'T check if the machine exists -/datum/powernet/proc/remove_machine(var/obj/machinery/power/M) - nodes -=M - M.powernet = null - if(is_empty())//the powernet is now empty... - qdel(src)///... delete it - - -//add a power machine to the current powernet -//Warning : this proc DON'T check if the machine exists -/datum/powernet/proc/add_machine(var/obj/machinery/power/M) - if(M.powernet)// if M already has a powernet... - if(M.powernet == src) - return - else - M.disconnect_from_network()//..remove it - M.powernet = src - nodes[M] = M - -//handles the power changes in the powernet -//called every ticks by the powernet controller -/datum/powernet/proc/reset() - - //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES - netexcess = avail - load - - if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle - for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network - S.restore() // and restore some of the power that was used - - //updates the viewed load (as seen on power computers) - viewload = 0.8*viewload + 0.2*load - viewload = round(viewload) - - //reset the powernet - load = 0 - avail = newavail - newavail = 0 - -/datum/powernet/proc/get_electrocute_damage() - if(avail >= 1000) - return Clamp(round(avail/10000), 10, 90) + rand(-5,5) - else - return 0 - //////////////////////////////////////////////// // Misc. /////////////////////////////////////////////// diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm new file mode 100644 index 00000000000..e811ffeafc8 --- /dev/null +++ b/code/modules/power/powernet.dm @@ -0,0 +1,80 @@ +//////////////////////////////////////////// +// POWERNET DATUM PROCS +// each contiguous network of cables & nodes +//////////////////////////////////////////// + +/datum/powernet/New() + SSpower.powernets += src + +/datum/powernet/Destroy() + SSpower.powernets -= src + +/datum/powernet/proc/is_empty() + return !cables.len && !nodes.len + +//remove a cable from the current powernet +//if the powernet is then empty, delete it +//Warning : this proc DON'T check if the cable exists +/datum/powernet/proc/remove_cable(var/obj/structure/cable/C) + cables -= C + C.powernet = null + if(is_empty())//the powernet is now empty... + qdel(src)///... delete it + +//add a cable to the current powernet +//Warning : this proc DON'T check if the cable exists +/datum/powernet/proc/add_cable(var/obj/structure/cable/C) + if(C.powernet)// if C already has a powernet... + if(C.powernet == src) + return + else + C.powernet.remove_cable(C) //..remove it + C.powernet = src + cables +=C + +//remove a power machine from the current powernet +//if the powernet is then empty, delete it +//Warning : this proc DON'T check if the machine exists +/datum/powernet/proc/remove_machine(var/obj/machinery/power/M) + nodes -=M + M.powernet = null + if(is_empty())//the powernet is now empty... + qdel(src)///... delete it + + +//add a power machine to the current powernet +//Warning : this proc DON'T check if the machine exists +/datum/powernet/proc/add_machine(var/obj/machinery/power/M) + if(M.powernet)// if M already has a powernet... + if(M.powernet == src) + return + else + M.disconnect_from_network()//..remove it + M.powernet = src + nodes[M] = M + +//handles the power changes in the powernet +//called every ticks by the powernet controller +/datum/powernet/proc/reset() + + //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES + netexcess = avail - load + + if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle + for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network + S.restore() // and restore some of the power that was used + + //updates the viewed load (as seen on power computers) + viewload = 0.8*viewload + 0.2*load + viewload = round(viewload) + + //reset the powernet + load = 0 + avail = newavail + newavail = 0 + +/datum/powernet/proc/get_electrocute_damage() + if(avail >= 1000) + return Clamp(round(avail/10000), 10, 90) + rand(-5,5) + else + return 0 \ No newline at end of file diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 88bacc76790..4618586611b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -63,8 +63,7 @@ return //don't want the emitters to miss obj/item/projectile/beam/emitter/Destroy() - PlaceInPool(src) - return 1 //cancels the GCing + return QDEL_HINT_PUTINPOOL /obj/item/projectile/lasertag name = "laser tag beam" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 09cae327199..647210069ac 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -72,7 +72,7 @@ ..() var/turf/location = get_turf(src) if(location) - new /obj/effect/hotspot(location) + PoolOrNew(/obj/effect/hotspot, location) location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/incendiary/shell/dragonsbreath diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index e10d2af11ec..11a8bdf76de 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -317,13 +317,13 @@ datum/reagent/consumable/cornoil/reaction_turf(var/turf/simulated/T, var/volume) src = null if(volume >= 3) T.MakeSlippery() - var/hotspot = (locate(/obj/effect/hotspot) in T) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot) var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) lowertemp.react() T.assume_air(lowertemp) - qdel(hotspot) + hotspot.Kill() datum/reagent/consumable/enzyme name = "Universal Enzyme" diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index 43650c72067..80502dd8bdf 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -129,13 +129,13 @@ datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume) for(var/mob/living/simple_animal/slime/M in T) M.apply_water() - var/hotspot = (locate(/obj/effect/hotspot) in T) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot && !istype(T, /turf/space)) if(T.air) var/datum/gas_mixture/G = T.air G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),0) G.react() - qdel(hotspot) + hotspot.Kill() return /* diff --git a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm index a5704d0b950..82327767644 100644 --- a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm @@ -59,7 +59,7 @@ datum/reagent/nitroglycerin else if(prob(volume)) F.burn_tile() if(istype(F, /turf/simulated/floor/)) - new /obj/effect/hotspot(F) + PoolOrNew(/obj/effect/hotspot, F) if(istype(T, /turf/simulated/wall/)) var/turf/simulated/wall/W = T if(prob(volume/10)) @@ -69,7 +69,7 @@ datum/reagent/nitroglycerin if(method == TOUCH && isliving(M)) M.adjust_fire_stacks(5) M.IgniteMob() - new /obj/effect/hotspot(M.loc) + PoolOrNew(/obj/effect/hotspot, M.loc) /datum/reagent/sorium name = "Sorium" diff --git a/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm b/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm index 737f9bb5e92..4a3983597f8 100644 --- a/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm +++ b/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm @@ -109,7 +109,7 @@ /datum/chemical_reaction/clf3/on_reaction(var/datum/reagents/holder, var/created_volume) var/turf/T = get_turf(holder.my_atom) for(var/turf/turf in range(1,T)) - new /obj/effect/hotspot(turf) + PoolOrNew(/obj/effect/hotspot, turf) holder.chem_temp = 1000 // hot as shit /datum/chemical_reaction/sorium diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 204b94477e7..7fb15f6e3f9 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -19,98 +19,98 @@ var/dheight = 0 //position relative to covered area, parallel to dir //these objects are indestructable - Destroy() - return 1 +/obj/docking_port/Destroy() + return QDEL_HINT_LETMELIVE - //returns a list(x0,y0, x1,y1) where points 0 and 1 are bounding corners of the projected rectangle - proc/return_coords(_x, _y, _dir) - if(!_dir) - _dir = dir - if(!_x) - _x = x - if(!_y) - _y = y +//returns a list(x0,y0, x1,y1) where points 0 and 1 are bounding corners of the projected rectangle +/obj/docking_port/proc/return_coords(_x, _y, _dir) + if(!_dir) + _dir = dir + if(!_x) + _x = x + if(!_y) + _y = y - //byond's sin and cos functions are inaccurate. This is faster and perfectly accurate - var/cos = 1 - var/sin = 0 - switch(_dir) - if(WEST) - cos = 0 - sin = 1 - if(SOUTH) - cos = -1 - sin = 0 - if(EAST) - cos = 0 - sin = -1 + //byond's sin and cos functions are inaccurate. This is faster and perfectly accurate + var/cos = 1 + var/sin = 0 + switch(_dir) + if(WEST) + cos = 0 + sin = 1 + if(SOUTH) + cos = -1 + sin = 0 + if(EAST) + cos = 0 + sin = -1 - return list( - _x + (-dwidth*cos) - (-dheight*sin), - _y + (-dwidth*sin) + (-dheight*cos), - _x + (-dwidth+width-1)*cos - (-dheight+height-1)*sin, - _y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos - ) + return list( + _x + (-dwidth*cos) - (-dheight*sin), + _y + (-dwidth*sin) + (-dheight*cos), + _x + (-dwidth+width-1)*cos - (-dheight+height-1)*sin, + _y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos + ) - //returns turfs within our projected rectangle in a specific order. - //this ensures that turfs are copied over in the same order, regardless of any rotation - proc/return_ordered_turfs(_x, _y, _z, _dir) - if(!_dir) - _dir = dir - if(!_x) - _x = x - if(!_y) - _y = y - if(!_z) - _z = z - var/cos = 1 - var/sin = 0 - switch(_dir) - if(WEST) - cos = 0 - sin = 1 - if(SOUTH) - cos = -1 - sin = 0 - if(EAST) - cos = 0 - sin = -1 +//returns turfs within our projected rectangle in a specific order. +//this ensures that turfs are copied over in the same order, regardless of any rotation +/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir) + if(!_dir) + _dir = dir + if(!_x) + _x = x + if(!_y) + _y = y + if(!_z) + _z = z + var/cos = 1 + var/sin = 0 + switch(_dir) + if(WEST) + cos = 0 + sin = 1 + if(SOUTH) + cos = -1 + sin = 0 + if(EAST) + cos = 0 + sin = -1 - . = list() + . = list() - var/xi - var/yi - for(var/dx=0, dx S.dwidth) - return 2 - if(width-dwidth > S.width-S.dwidth) - return 3 - if(dheight > S.dheight) - return 4 - if(height-dheight > S.height-S.dheight) - return 5 - //check the dock isn't occupied - if(S.get_docked()) - return 6 - return 0 //0 means we can dock +//this is to check if this shuttle can physically dock at dock S +/obj/docking_port/mobile/proc/canDock(obj/docking_port/stationary/S) + if(!istype(S)) + return 1 + if(istype(S, /obj/docking_port/stationary/transit)) + return 0 + //check dock is big enough to contain us + if(dwidth > S.dwidth) + return 2 + if(width-dwidth > S.width-S.dwidth) + return 3 + if(dheight > S.dheight) + return 4 + if(height-dheight > S.height-S.dheight) + return 5 + //check the dock isn't occupied + if(S.get_docked()) + return 6 + return 0 //0 means we can dock - //call the shuttle to destination S - proc/request(obj/docking_port/stationary/S) - if(canDock(S)) - ERROR("[type](\"[name]\") cannot dock at [S]\")") - return 1 //we can't dock at S +//call the shuttle to destination S +/obj/docking_port/mobile/proc/request(obj/docking_port/stationary/S) + if(canDock(S)) + ERROR("[type](\"[name]\") cannot dock at [S]\")") + return 1 //we can't dock at S - switch(mode) - if(SHUTTLE_CALL) - if(S == destination) - if(world.time <= timer) - timer = world.time - else - destination = S + switch(mode) + if(SHUTTLE_CALL) + if(S == destination) + if(world.time <= timer) timer = world.time - if(SHUTTLE_RECALL) - if(S == destination) - timer = world.time - timeLeft(1) - else - destination = S - timer = world.time - mode = SHUTTLE_CALL else destination = S - mode = SHUTTLE_CALL timer = world.time - enterTransit() //hyperspace + if(SHUTTLE_RECALL) + if(S == destination) + timer = world.time - timeLeft(1) + else + destination = S + timer = world.time + mode = SHUTTLE_CALL + else + destination = S + mode = SHUTTLE_CALL + timer = world.time + enterTransit() //hyperspace - //recall the shuttle to where it was previously - proc/cancel() - if(mode != SHUTTLE_CALL) - return +//recall the shuttle to where it was previously +/obj/docking_port/mobile/proc/cancel() + if(mode != SHUTTLE_CALL) + return - timer = world.time - timeLeft(1) - mode = SHUTTLE_RECALL + timer = world.time - timeLeft(1) + mode = SHUTTLE_RECALL - proc/enterTransit() - previous = null +/obj/docking_port/mobile/proc/enterTransit() + previous = null // if(!destination) // return - var/obj/docking_port/stationary/S0 = get_docked() - var/obj/docking_port/stationary/S1 = findTransitDock() - if(S1) - if(dock(S1)) - WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].") - else - previous = S0 + var/obj/docking_port/stationary/S0 = get_docked() + var/obj/docking_port/stationary/S1 = findTransitDock() + if(S1) + if(dock(S1)) + WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].") else - WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]") + previous = S0 + else + WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]") - //this is the main proc. It instantly moves our mobile port to stationary port S1 - //it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc - proc/dock(obj/docking_port/stationary/S1) - . = canDock(S1) - if(.) - ERROR("[type](\"[name]\") cannot dock at [S1]") - return . +//this is the main proc. It instantly moves our mobile port to stationary port S1 +//it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc +/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1) + . = canDock(S1) + if(.) + ERROR("[type](\"[name]\") cannot dock at [S1]") + return . - if(canMove()) - return -1 + if(canMove()) + return -1 - closePortDoors() + closePortDoors() // //rotate transit docking ports, so we don't need zillions of variants // if(istype(S1, /obj/docking_port/stationary/transit)) // S1.dir = turn(NORTH, -travelDir) - var/obj/docking_port/stationary/S0 = get_docked() - var/turf_type = /turf/space - var/area_type = /area/space - if(S0) - if(S0.turf_type) - turf_type = S0.turf_type - if(S0.area_type) - area_type = S0.area_type + var/obj/docking_port/stationary/S0 = get_docked() + var/turf_type = /turf/space + var/area_type = /area/space + if(S0) + if(S0.turf_type) + turf_type = S0.turf_type + if(S0.area_type) + area_type = S0.area_type - var/list/L0 = return_ordered_turfs() - var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir) - - //remove area surrounding docking port - if(areaInstance.contents.len) - var/area/A0 = locate("[area_type]") - if(!A0) - A0 = new area_type(null) - for(var/turf/T0 in L0) - A0.contents += T0 - - //move or squish anything in the way ship at destination - roadkill(L1, S1.dir) - - for(var/i=1, i<=L0.len, ++i) - var/turf/T0 = L0[i] - if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs! - continue - - var/turf/T1 = L1[i] - if(!T1) - continue - - T0.copyTurf(T1) - areaInstance.contents += T1 - - //copy over air - if(istype(T1, /turf/simulated)) - var/turf/simulated/Ts1 = T1 - Ts1.copy_air_with_tile(T0) - - //move mobile to new location - loc = S1.loc - dir = S1.dir - - //move all objects - for(var/obj/O in T0) - if(O.invisibility >= 101) - continue - if(O == T0.lighting_object) - continue - O.loc = T1 - - //close open doors - if(istype(O, /obj/machinery/door)) - var/obj/machinery/door/Door = O - spawn(-1) - if(Door) - Door.close() - - for(var/mob/M in T0) - if(!M.move_on_shuttle) - continue - M.loc = T1 - - //docking turbulence - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 2, 1) // turn it down a bit come on - else - shake_camera(M, 7, 1) - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(3) - - T0.ChangeTurf(turf_type) - - //air system updates - for(var/turf/T1 in L1) - T1.redraw_lighting() - SSair.remove_from_active(T1) - T1.CalculateAdjacentTurfs() - SSair.add_to_active(T1,1) + var/list/L0 = return_ordered_turfs() + var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir) + //remove area surrounding docking port + if(areaInstance.contents.len) + var/area/A0 = locate("[area_type]") + if(!A0) + A0 = new area_type(null) for(var/turf/T0 in L0) - T0.redraw_lighting() - SSair.remove_from_active(T0) - T0.CalculateAdjacentTurfs() - SSair.add_to_active(T0,1) + A0.contents += T0 -/* - if(istype(S1, /obj/docking_port/stationary/transit)) - var/d = turn(dir, 180 + travelDir) - for(var/turf/space/transit/T in S1.return_ordered_turfs()) - T.pushdirection = d - T.update_icon() -*/ + //move or squish anything in the way ship at destination + roadkill(L1, S1.dir) - proc/findTransitDock() - var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit") - if(T && !canDock(T)) - return T - /* commented out due to issues with rotation - for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit) - if(S.id) + for(var/i=1, i<=L0.len, ++i) + var/turf/T0 = L0[i] + if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs! + continue + + var/turf/T1 = L1[i] + if(!T1) + continue + + T0.copyTurf(T1) + areaInstance.contents += T1 + + //copy over air + if(istype(T1, /turf/simulated)) + var/turf/simulated/Ts1 = T1 + Ts1.copy_air_with_tile(T0) + + //move mobile to new location + loc = S1.loc + dir = S1.dir + + //move all objects + for(var/obj/O in T0) + if(O.invisibility >= 101) continue - if(!canDock(S)) - return S - */ + if(O == T0.lighting_object) + continue + O.loc = T1 - - //shuttle-door closing is handled in the dock() proc whilst looping through turfs - //this one closes the door where we are docked at, if there is one there. - proc/closePortDoors() - var/turf/T = get_step(loc, turn(dir,180)) - if(T) - var/obj/machinery/door/Door = locate() in T - if(Door) + //close open doors + if(istype(O, /obj/machinery/door)) + var/obj/machinery/door/Door = O spawn(-1) - Door.close() + if(Door) + Door.close() - proc/roadkill(list/L, dir, x, y) - for(var/turf/T in L) - for(var/atom/movable/AM in T) - if(ismob(AM)) - if(istype(AM, /mob/living)) - var/mob/living/M = AM - M.Paralyse(10) - M.take_organ_damage(80) - M.anchored = 0 + for(var/mob/M in T0) + if(!M.move_on_shuttle) + continue + M.loc = T1 + + //docking turbulence + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 2, 1) // turn it down a bit come on else - continue + shake_camera(M, 7, 1) + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(3) + + T0.ChangeTurf(turf_type) + + //air system updates + for(var/turf/T1 in L1) + T1.redraw_lighting() + SSair.remove_from_active(T1) + T1.CalculateAdjacentTurfs() + SSair.add_to_active(T1,1) + + for(var/turf/T0 in L0) + T0.redraw_lighting() + SSair.remove_from_active(T0) + T0.CalculateAdjacentTurfs() + SSair.add_to_active(T0,1) - if(!AM.anchored) - step(AM, dir) - else - qdel(AM) /* - //used to check if atom/A is within the shuttle's bounding box - proc/onShuttleCheck(atom/A) - var/turf/T = get_turf(A) - if(!T) - return 0 - - var/list/L = return_coords() - if(L[1] > L[3]) - L.Swap(1,3) - if(L[2] > L[4]) - L.Swap(2,4) - - if(L[1] <= T.x && T.x <= L[3]) - if(L[2] <= T.y && T.y <= L[4]) - return 1 - return 0 + if(istype(S1, /obj/docking_port/stationary/transit)) + var/d = turn(dir, 180 + travelDir) + for(var/turf/space/transit/T in S1.return_ordered_turfs()) + T.pushdirection = d + T.update_icon() +*/ + +/obj/docking_port/mobile/proc/findTransitDock() + var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit") + if(T && !canDock(T)) + return T +/* commented out due to issues with rotation + for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit) + if(S.id) + continue + if(!canDock(S)) + return S */ - //used by shuttle subsystem to check timers - proc/check() - var/timeLeft = timeLeft(1) - if(timeLeft <= 0) - switch(mode) - if(SHUTTLE_CALL) - if(dock(destination)) - setTimer(20) //can't dock for some reason, try again in 2 seconds - return - if(SHUTTLE_RECALL) - if(dock(previous)) - setTimer(20) //can't dock for some reason, try again in 2 seconds - return - mode = SHUTTLE_IDLE - timer = 0 - destination = null - proc/setTimer(wait) - if(timer <= 0) - timer = world.time - timer += wait - timeLeft(1) +//shuttle-door closing is handled in the dock() proc whilst looping through turfs +//this one closes the door where we are docked at, if there is one there. +/obj/docking_port/mobile/proc/closePortDoors() + var/turf/T = get_step(loc, turn(dir,180)) + if(T) + var/obj/machinery/door/Door = locate() in T + if(Door) + spawn(-1) + Door.close() - //returns timeLeft - proc/timeLeft(divisor) - if(divisor <= 0) - divisor = 10 - if(!timer) - return round(callTime/divisor, 1) - return max( round((timer+callTime-world.time)/divisor,1), 0 ) +/obj/docking_port/mobile/proc/roadkill(list/L, dir, x, y) + for(var/turf/T in L) + for(var/atom/movable/AM in T) + if(ismob(AM)) + if(istype(AM, /mob/living)) + var/mob/living/M = AM + M.Paralyse(10) + M.take_organ_damage(80) + M.anchored = 0 + else + continue - proc/getStatusText() - var/obj/docking_port/stationary/dockedAt = get_docked() - . = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown" - if(istype(dockedAt, /obj/docking_port/stationary/transit)) - var/obj/docking_port/stationary/dst - if(mode == SHUTTLE_RECALL) - dst = previous + if(!AM.anchored) + step(AM, dir) else - dst = destination - . += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)" + qdel(AM) +/* +//used to check if atom/A is within the shuttle's bounding box +/obj/docking_port/mobile/proc/onShuttleCheck(atom/A) + var/turf/T = get_turf(A) + if(!T) + return 0 + + var/list/L = return_coords() + if(L[1] > L[3]) + L.Swap(1,3) + if(L[2] > L[4]) + L.Swap(2,4) + + if(L[1] <= T.x && T.x <= L[3]) + if(L[2] <= T.y && T.y <= L[4]) + return 1 + return 0 +*/ +//used by shuttle subsystem to check timers +/obj/docking_port/mobile/proc/check() + var/timeLeft = timeLeft(1) + if(timeLeft <= 0) + switch(mode) + if(SHUTTLE_CALL) + if(dock(destination)) + setTimer(20) //can't dock for some reason, try again in 2 seconds + return + if(SHUTTLE_RECALL) + if(dock(previous)) + setTimer(20) //can't dock for some reason, try again in 2 seconds + return + mode = SHUTTLE_IDLE + timer = 0 + destination = null + + +/obj/docking_port/mobile/proc/setTimer(wait) + if(timer <= 0) + timer = world.time + timer += wait - timeLeft(1) + +//returns timeLeft +/obj/docking_port/mobile/proc/timeLeft(divisor) + if(divisor <= 0) + divisor = 10 + if(!timer) + return round(callTime/divisor, 1) + return max( round((timer+callTime-world.time)/divisor,1), 0 ) + +/obj/docking_port/mobile/proc/getStatusText() + var/obj/docking_port/stationary/dockedAt = get_docked() + . = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown" + if(istype(dockedAt, /obj/docking_port/stationary/transit)) + var/obj/docking_port/stationary/dst + if(mode == SHUTTLE_RECALL) + dst = previous + else + dst = destination + . += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)" /obj/machinery/computer/shuttle name = "Shuttle Console" diff --git a/tgstation.dme b/tgstation.dme index 33764a17413..7a35fa2dc48 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -28,6 +28,7 @@ #include "code\__DEFINES\math.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\preferences.dm" +#include "code\__DEFINES\qdel.dm" #include "code\__DEFINES\say.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\stat.dm" @@ -90,7 +91,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\ATMOSPHERICS\atmospherics.dm" -#include "code\ATMOSPHERICS\datum_pipe_network.dm" #include "code\ATMOSPHERICS\datum_pipeline.dm" #include "code\ATMOSPHERICS\he_pipes.dm" #include "code\ATMOSPHERICS\pipes.dm" @@ -118,7 +118,6 @@ #include "code\ATMOSPHERICS\pipes\manifold4w.dm" #include "code\ATMOSPHERICS\pipes\simple.dm" #include "code\ATMOSPHERICS\pipes\tank.dm" -#include "code\ATMOSPHERICS\pipes\vent.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\master_controller.dm" @@ -137,7 +136,6 @@ #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\objects.dm" #include "code\controllers\subsystem\pai.dm" -#include "code\controllers\subsystem\pipenets.dm" #include "code\controllers\subsystem\power.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\server_maintenance.dm" @@ -152,11 +150,11 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datumvars.dm" +#include "code\datums\debug.dm" #include "code\datums\gas_mixture.dm" #include "code\datums\hud.dm" #include "code\datums\martial.dm" #include "code\datums\mind.dm" -#include "code\datums\mixed.dm" #include "code\datums\modules.dm" #include "code\datums\mutations.dm" #include "code\datums\recipe.dm" @@ -1306,6 +1304,7 @@ #include "code\modules\power\lighting.dm" #include "code\modules\power\port_gen.dm" #include "code\modules\power\power.dm" +#include "code\modules\power\powernet.dm" #include "code\modules\power\smes.dm" #include "code\modules\power\solar.dm" #include "code\modules\power\switch.dm"