From bd6d51a0b566fea78b578a626951d431f2a61c0e Mon Sep 17 00:00:00 2001 From: MrStonedOne Date: Wed, 29 Apr 2015 02:00:25 -0700 Subject: [PATCH] Massive MC and subsystem rewrite MC: No longer tracks a subsystem's cpu usage. This was basically worthless and took up space on the stat panel Can calculate wait down to a tenth of a decisecond to make it fps/world.ticklag agnostic Now allows subsystems to have a dynamic wait, that is based on a ratio of how long that subsystem has been taking to process(cost). (This system allows for upper and lower bounds, and an changeable cost delta for each subsystem) MC can now be told to init a zlevel All Subsystems: Stats panel now allows child subsystems to pass it a message to add to its stats entry. All subsystems have been moved over to this system - This should cut down on subsystems having to copy and paste the stats proc in order to add to it All subsystems now properlly handle being given a zlevel in their init proc Subsystem changes: Air: Added air to the dynamic wait subsystem. upper bound: 50, lower bound: 5, cost delta: 3 times process cost Air now fires 4 times faster when it can do so without lagging things up Pipenet has been merged into air Atmos machinery now processes with process_atmos(), ticked by air, not machinery. Hotspots (the fire object) are now object pooled Pipenet: Deleted, added to air Machinery: Moved all atmos calcualtions in all objects's process() to process_atmos(). Lighting: Added Lighting to the dynamic wait subsystem. upper bound: 20, lower bound: 5, cost delta: 3 times process cost Ticker: Fixed ticker not updating the lobby panel when game start delayed Fixed the game start timer updating rapidly from queued fires when game start delay is removed Garbage/qdel: qdel will now limit its process time to 2ds a fire. qdel can now be given hints as a return to Destroy() as to what should be done with the object. the options are: queue: (default) this is the normal behavior. letmelive: old default to non-null/zero. does nothing with the object iwillgc: functionally the same as above, mainly to let people working with objects know that the object will not be queued for GC checking harddel: this will queue the object to be deleted without storing a soft reference, mainly to save locate() processing time. harddel_now: this will del() the object. To allow for a clean removal of every del() not in qdel All objects have been updated to the new system, harddel and iwillgc was not added to any new objects. Fixed some objects not GCing because they didn't properlly clear references in Destory() Fixed some objects getting qdel'ed preventing other objects from getting GCed because they did not null their reference to that object. --- code/ATMOSPHERICS/atmospherics.dm | 20 +- .../binary_devices/binary_atmos_base.dm | 3 +- .../components/binary_devices/circulator.dm | 2 +- .../components/binary_devices/dp_vent_pump.dm | 8 +- .../components/binary_devices/passive_gate.dm | 4 +- .../components/binary_devices/pump.dm | 4 +- .../components/binary_devices/volume_pump.dm | 4 +- .../components/portables_connector.dm | 2 +- .../components/trinary_devices/filter.dm | 4 +- .../components/trinary_devices/mixer.dm | 2 +- .../trinary_devices/trinary_base.dm | 3 +- .../components/unary/cold_sink.dm | 2 +- .../components/unary/heat_exchanger.dm | 4 +- .../components/unary/heat_source.dm | 2 +- .../components/unary/outlet_injector.dm | 12 +- .../components/unary/oxygen_generator.dm | 2 +- .../components/unary/unary_base.dm | 3 +- .../components/unary/vent_pump.dm | 10 +- .../components/unary/vent_scrubber.dm | 10 +- code/ATMOSPHERICS/components/valve.dm | 3 +- code/ATMOSPHERICS/datum_pipe_network.dm | 0 code/ATMOSPHERICS/datum_pipeline.dm | 7 +- code/ATMOSPHERICS/he_pipes.dm | 16 +- code/ATMOSPHERICS/pipes/manifold.dm | 3 +- code/ATMOSPHERICS/pipes/manifold4w.dm | 3 +- code/ATMOSPHERICS/pipes/simple.dm | 3 +- code/ATMOSPHERICS/pipes/vent.dm | 0 code/LINDA/LINDA_fire.dm | 9 +- code/LINDA/LINDA_turf_tile.dm | 6 +- code/__DEFINES/qdel.dm | 10 + code/_onclick/hud/alert.dm | 3 +- code/controllers/master_controller.dm | 35 +- code/controllers/subsystem/air.dm | 93 ++- code/controllers/subsystem/bots.dm | 3 + code/controllers/subsystem/diseases.dm | 2 + code/controllers/subsystem/events.dm | 4 +- code/controllers/subsystem/garbage.dm | 131 ++-- code/controllers/subsystem/jobs.dm | 4 +- code/controllers/subsystem/lighting.dm | 3 +- code/controllers/subsystem/machines.dm | 2 +- code/controllers/subsystem/mobs.dm | 2 +- code/controllers/subsystem/nanoUI.dm | 4 +- code/controllers/subsystem/npcpool.dm | 2 +- code/controllers/subsystem/objects.dm | 17 +- code/controllers/subsystem/pipenets.dm | 36 - code/controllers/subsystem/power.dm | 19 +- code/controllers/subsystem/shuttles.dm | 4 +- code/controllers/subsystem/sun.dm | 3 + code/controllers/subsystem/ticker.dm | 8 +- code/controllers/subsystems.dm | 34 +- code/datums/debug.dm | 2 + code/datums/mixed.dm | 30 - code/datums/spells/trigger.dm | 5 +- code/game/atoms_movable.dm | 5 + code/game/gamemodes/blob/blobs/blob_mobs.dm | 1 + code/game/gamemodes/blob/blobs/core.dm | 1 + code/game/gamemodes/blob/blobs/factory.dm | 1 + code/game/gamemodes/blob/powers.dm | 4 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 6 +- code/game/machinery/Beacon.dm | 1 + code/game/machinery/Freezer.dm | 1 + code/game/machinery/atmo_control.dm | 4 +- code/game/machinery/atmoalter/canister.dm | 10 +- code/game/machinery/atmoalter/meter.dm | 4 +- .../atmoalter/portable_atmospherics.dm | 15 +- code/game/machinery/atmoalter/pump.dm | 5 +- code/game/machinery/atmoalter/scrubber.dm | 9 +- code/game/machinery/atmoalter/zvent.dm | 2 +- code/game/machinery/bots/bots.dm | 2 + code/game/machinery/cryo.dm | 27 +- code/game/machinery/doors/alarmlock.dm | 1 + code/game/machinery/doors/windowdoor.dm | 2 + code/game/machinery/machinery.dm | 10 +- code/game/machinery/magnet.dm | 3 + code/game/machinery/newscaster.dm | 2 + code/game/machinery/portable_turret.dm | 1 + code/game/machinery/shieldgen.dm | 1 + code/game/machinery/teleporter.dm | 15 + code/game/machinery/vending.dm | 1 + code/game/mecha/combat/marauder.dm | 1 + code/game/objects/effects/aliens.dm | 1 + .../effects/decals/Cleanable/aliens.dm | 1 + .../effects/decals/Cleanable/humans.dm | 1 + .../objects/effects/decals/Cleanable/misc.dm | 1 + .../effects/decals/Cleanable/robots.dm | 1 + .../effects/effect_system/effect_system.dm | 3 +- .../effects/effect_system/effects_smoke.dm | 2 +- code/game/objects/effects/landmarks.dm | 3 + code/game/objects/effects/portals.dm | 1 + code/game/objects/explosion.dm | 2 +- code/game/objects/items/body_egg.dm | 1 + code/game/objects/items/devices/camera_bug.dm | 5 +- code/game/objects/items/stacks/stack.dm | 2 - code/game/pooling/atom_pool.dm | 17 +- code/game/turfs/space/space.dm | 2 + code/game/turfs/turf.dm | 2 + code/modules/admin/admin.dm | 5 +- code/modules/admin/verbs/debug.dm | 4 +- code/modules/events/wizard/greentext.dm | 2 +- code/modules/lighting/lighting_system.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 1 + code/modules/mob/living/living.dm | 6 +- .../mob/living/silicon/ai/freelook/eye.dm | 1 + code/modules/power/power.dm | 91 --- code/modules/power/powernet.dm | 80 ++ code/modules/projectiles/projectile/beams.dm | 3 +- .../modules/projectiles/projectile/bullets.dm | 2 +- .../Consumable-Reagents/Food-Reagents.dm | 4 +- .../Chemistry-Reagents/Other-Reagents.dm | 4 +- .../Pyrotechnic-Reagents.dm | 4 +- .../Chemistry-Recipes/Pyrotechnics.dm | 2 +- code/modules/shuttle/shuttle.dm | 724 +++++++++--------- tgstation.dme | 7 +- 113 files changed, 975 insertions(+), 754 deletions(-) delete mode 100644 code/ATMOSPHERICS/datum_pipe_network.dm delete mode 100644 code/ATMOSPHERICS/pipes/vent.dm create mode 100644 code/__DEFINES/qdel.dm delete mode 100644 code/controllers/subsystem/pipenets.dm create mode 100644 code/datums/debug.dm delete mode 100644 code/datums/mixed.dm create mode 100644 code/modules/power/powernet.dm 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"