diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm
index 816c1468663..38d0b748355 100644
--- a/_maps/map_files/generic/z2.dmm
+++ b/_maps/map_files/generic/z2.dmm
@@ -313,7 +313,7 @@
"ga" = (/turf/simulated/shuttle/wall{icon_state = "swallc4"; dir = 2},/area/space)
"gb" = (/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry)
"gc" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/centcom/ferry)
-"gd" = (/obj/effect/landmark{name = "Deathsquad"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"gd" = (/obj/structure/flora/kirbyplants,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"ge" = (/obj/structure/rack,/obj/item/weapon/storage/fancy/crayons,/obj/item/toy/sword,/turf/unsimulated/floor{tag = "icon-red (NORTH)"; icon_state = "red"; dir = 1},/area/centcom/evac)
"gf" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control)
"gg" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control)
@@ -325,11 +325,11 @@
"gm" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/shuttle/floor,/area/space)
"gn" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark{name = "Emergencyresponseteam"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"go" = (/obj/machinery/door/airlock/shuttle,/turf/simulated/shuttle/floor,/area/space)
-"gp" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/emps,/obj/item/weapon/gun/energy/ionrifle{pin = /obj/item/device/firing_pin},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"gp" = (/obj/structure/extinguisher_cabinet{pixel_x = 28},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"gq" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/space)
"gr" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/space)
"gs" = (/turf/unsimulated/floor{name = "plating"},/area/space)
-"gt" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/ferry)
+"gt" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{dir = 8; icon_state = "vault"},/area/centcom/ferry)
"gu" = (/obj/machinery/door/airlock/external{name = "Supply Shuttle"; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/suppy)
"gv" = (/turf/unsimulated/wall/fakeglass,/area/centcom/control)
"gw" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space)
@@ -409,9 +409,9 @@
"hS" = (/obj/machinery/door/poddoor/shutters/preopen{id = "adminshut"; name = "Administrative Shutters"},/turf/unsimulated/wall/fakeglass,/area/centcom/ferry)
"hT" = (/obj/machinery/door/poddoor/preopen{id = "CentComPort"; name = "security door"},/turf/unsimulated/floor{tag = "icon-loadingarea (WEST)"; icon_state = "loadingarea"; dir = 8},/area/centcom/control)
"hU" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
-"hV" = (/obj/structure/dresser,/obj/structure/mirror{pixel_x = 0; pixel_y = 30},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
-"hW" = (/obj/structure/closet/secure_closet/ertCom,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
-"hX" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"hV" = (/obj/structure/stool/bed/chair/office/dark,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
+"hW" = (/obj/structure/closet/secure_closet/ertCom,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
+"hX" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/gun/syringe/rapidsyringe,/obj/structure/extinguisher_cabinet{pixel_y = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"hY" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 5},/obj/item/weapon/pen/blue,/turf/unsimulated/floor{dir = 8; icon_state = "vault"},/area/centcom/ferry)
"hZ" = (/turf/unsimulated/wall,/area/tdome/tdomeobserve)
"ia" = (/obj/structure/reagent_dispensers/water_cooler,/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/centcom/ferry)
@@ -432,7 +432,7 @@
"ip" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/grass/both,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership)
"iq" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/tree/pine,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership)
"ir" = (/turf/unsimulated/floor{dir = 8; heat_capacity = 1; icon_state = "warning"},/area/centcom/evac)
-"is" = (/obj/structure/closet/secure_closet/ertMed,/turf/unsimulated/floor{tag = "icon-darkblue (EAST)"; icon_state = "darkblue"; dir = 4},/area/centcom/ferry)
+"is" = (/obj/structure/table/reinforced,/obj/item/weapon/c4,/obj/item/weapon/c4{pixel_x = 7},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"it" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "floor"},/area/tdome/tdomeobserve)
"iu" = (/turf/unsimulated/floor{icon_state = "floor"},/area/tdome/tdomeobserve)
"iv" = (/obj/machinery/door/airlock/centcom{name = "Transport Shuttle"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{tag = "icon-darkgreen"; icon_state = "darkgreen"; dir = 2},/area/centcom/ferry)
@@ -451,15 +451,15 @@
"iI" = (/obj/machinery/washing_machine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership)
"iJ" = (/obj/structure/reagent_dispensers/water_cooler,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"iK" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 8; icon_state = "vault"},/area/centcom/ferry)
-"iL" = (/obj/structure/closet/secure_closet/ertEngi,/obj/structure/extinguisher_cabinet{pixel_x = 28},/turf/unsimulated/floor{tag = "icon-darkbrown (EAST)"; icon_state = "darkbrown"; dir = 4},/area/centcom/ferry)
+"iL" = (/obj/structure/closet/secure_closet/ertEngi,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"iM" = (/obj/machinery/vending/cigarette{products = list(/obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate = 7, /obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 3, /obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 2, /obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 3, /obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 1, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/lighter/random = 4, /obj/item/weapon/storage/fancy/rollingpapers = 5)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"iN" = (/obj/structure/sign/map/left,/turf/unsimulated/floor{tag = "icon-light_on"; icon_state = "light_on"},/area/centcom/ferry)
"iO" = (/obj/structure/sign/map/right,/turf/unsimulated/floor{tag = "icon-light_on"; icon_state = "light_on"},/area/centcom/ferry)
-"iP" = (/obj/structure/closet/secure_closet/ertSec,/turf/unsimulated/floor{tag = "icon-darkred (EAST)"; icon_state = "darkred"; dir = 4},/area/centcom/ferry)
+"iP" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"iQ" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
-"iR" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"iR" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 9},/area/centcom/ferry)
"iS" = (/obj/structure/table/wood,/obj/item/weapon/storage/box/drinkingglasses,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
-"iT" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/gun/syringe/rapidsyringe,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"iT" = (/obj/machinery/door/poddoor/ert,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"iU" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry)
"iV" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/ferry)
"iW" = (/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/centcom/ferry)
@@ -499,11 +499,11 @@
"jE" = (/mob/living/simple_animal/hostile/retaliate/bat{desc = "A Syndicate experiment in weaponized space carp technology. Its fangs seem to have been intentionally dulled down to prevent accidents."; faction = list("syndicate"); harm_intent_damage = 5; health = 50; icon_dead = "carp_dead"; icon_gib = "carp_gib"; icon_living = "carp"; icon_state = "carp"; name = "Cayenne"; real_name = "Cayenne"; response_disarm = "lightly brushes aside"; response_help = "pets"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"jF" = (/obj/machinery/door/airlock/centcom{name = "Study"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"jG" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership)
-"jH" = (/obj/structure/closet/secure_closet/ertMed,/turf/unsimulated/floor{tag = "icon-darkblue"; icon_state = "darkblue"; dir = 2},/area/centcom/ferry)
-"jI" = (/obj/structure/closet/secure_closet/ertSec,/turf/unsimulated/floor{tag = "icon-darkred"; icon_state = "darkred"; dir = 2},/area/centcom/ferry)
+"jH" = (/obj/structure/closet/secure_closet/ertSec,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
+"jI" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/gun/syringe/rapidsyringe,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"jJ" = (/obj/machinery/door/poddoor/shutters/preopen{id = "adminshut"; name = "Administrative Shutters"},/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/centcom/ferry)
"jK" = (/turf/unsimulated/floor{tag = "icon-yellowcornersiding (WEST)"; icon_state = "yellowcornersiding"; dir = 8},/area/centcom/evac)
-"jL" = (/obj/structure/table/reinforced,/obj/item/weapon/c4,/obj/item/weapon/c4{pixel_x = 7},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"jL" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/emps,/obj/item/weapon/gun/energy/ionrifle{pin = /obj/item/device/firing_pin},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"jM" = (/turf/unsimulated/floor{tag = "icon-yellowsiding"; icon_state = "yellowsiding"},/area/centcom/evac)
"jN" = (/turf/unsimulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/centcom/evac)
"jO" = (/turf/unsimulated/floor{tag = "icon-darkgreencorners"; icon_state = "darkgreencorners"},/area/centcom/ferry)
@@ -545,13 +545,13 @@
"ky" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/snacks/pizzaslice/mushroom,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"kz" = (/obj/structure/table/wood,/obj/item/weapon/reagent_containers/food/drinks/beer{pixel_x = 5; pixel_y = -2; step_x = 0},/obj/item/toy/cards/deck/syndicate{icon_state = "deck_syndicate_full"; pixel_x = -6; pixel_y = 6},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership)
"kA" = (/obj/machinery/computer/telecrystals/uplinker,/turf/unsimulated/floor{tag = "icon-podhatch (WEST)"; icon_state = "podhatch"; dir = 8},/area/syndicate_mothership)
-"kB" = (/obj/machinery/door/airlock/centcom{name = "briefing room"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"kB" = (/obj/structure/closet/secure_closet/ertMed,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/ferry)
"kC" = (/obj/structure/table/wood,/obj/item/weapon/paper_bin,/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/ferry)
"kD" = (/turf/unsimulated/floor{tag = "icon-yellowcornersiding (NORTH)"; icon_state = "yellowcornersiding"; dir = 1},/area/centcom/evac)
"kE" = (/turf/unsimulated/floor{tag = "icon-yellowsiding (NORTH)"; icon_state = "yellowsiding"; dir = 1},/area/centcom/evac)
"kF" = (/turf/unsimulated/floor{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/centcom/evac)
-"kG" = (/turf/unsimulated/floor{tag = "icon-warndark (EAST)"; icon_state = "warndark"; dir = 4},/area/centcom/ferry)
-"kH" = (/obj/machinery/door/airlock/external{name = "Ferry Airlock"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
+"kG" = (/obj/machinery/computer/shuttle/ferry,/turf/unsimulated/floor{tag = "icon-warndark (WEST)"; icon_state = "warndark"; dir = 8},/area/centcom/ferry)
+"kH" = (/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/ferry)
"kI" = (/turf/unsimulated/wall/fakeglass{color = "#008000"; dir = 6; icon_state = "fakewindows2"},/area/wizard_station)
"kJ" = (/obj/effect/forcefield,/obj/structure/door_assembly{anchored = 1; icon_state = "door_as_uranium1"; name = "Bridge"},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
"kK" = (/turf/unsimulated/wall/normal{tag = "icon-uranium6"; icon_state = "uranium6"},/area/wizard_station)
@@ -654,7 +654,7 @@
"mD" = (/turf/simulated/floor/plasteel,/area/tdome/arena)
"mE" = (/turf/unsimulated/wall/normal{tag = "icon-uranium1"; icon_state = "uranium1"},/area/wizard_station)
"mF" = (/obj/structure/stool/bed/chair/wood/wings,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
-"mG" = (/obj/structure/table/wood,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/ointment,/obj/item/device/radio/intercom{desc = "Talk through this. Magically."; freerange = 1; frequency = 1213; name = "Wizard Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
+"mG" = (/obj/structure/table/wood,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/ointment,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
"mH" = (/obj/structure/table/wood,/obj/item/weapon/retractor,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
"mI" = (/obj/structure/stool/bed/chair/office/dark,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry)
"mJ" = (/obj/structure/table/wood,/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station)
@@ -672,7 +672,7 @@
"mV" = (/obj/structure/table,/obj/item/weapon/weldingtool/largetank{pixel_y = 3},/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/space)
"mW" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
"mX" = (/obj/machinery/door/poddoor/shutters/preopen{id = "adminshut"; name = "Administrative Shutters"},/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 6},/area/centcom/ferry)
-"mY" = (/obj/structure/closet/secure_closet/ertEngi,/obj/structure/extinguisher_cabinet{pixel_y = 28},/turf/unsimulated/floor{tag = "icon-darkbrown"; icon_state = "darkbrown"; dir = 2},/area/centcom/ferry)
+"mY" = (/obj/machinery/door/airlock/centcom{name = "briefing room"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry)
"mZ" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/sneakers/brown,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/saber/red,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena)
"na" = (/obj/machinery/door/poddoor{id = "thunderdomegen"; name = "General Supply"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena)
"nb" = (/obj/effect/landmark{name = "tdome2"},/turf/unsimulated/floor{name = "plating"},/area/tdome/tdome2)
@@ -909,7 +909,9 @@
"ry" = (/obj/effect/landmark/abductor/agent{team = 2},/turf/unsimulated/floor/abductor,/area/abductor_ship)
"rz" = (/obj/effect/landmark/abductor/scientist{team = 3},/turf/unsimulated/floor/abductor,/area/abductor_ship)
"rA" = (/obj/effect/landmark/abductor/agent{team = 3},/turf/unsimulated/floor/abductor,/area/abductor_ship)
-
+"rB" = (/obj/machinery/door/airlock/external{name = "Ferry Airlock"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/ferry)
+"rC" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (SOUTHWEST)"; icon_state = "fakewindows"; dir = 10},/area/centcom/ferry)
+
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababadaeaeaeaeaeafaeaeaeaeaeafaeaeaeaeaeafaeaeaeaeaeag
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababahaiaiaiaiaiajakakakakakajalalalalalajamanananaoap
@@ -1043,23 +1045,23 @@ abababababababababababababababababababababababababababababababababababababababab
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcBdOdPdQdRdScBabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdsdsdsdsdscXabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhgBfhfhfhfhfhfhfhfhfhfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhUhVhUhUhUhUhUhUjHmYjIgpiTjLfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhUhUhUhUfDhUfDhUhUhUhUhUhUiRfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiJhUhUiKiKiKiKfRhUhUhUhUhUiTfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiMhUfTiKiNiOiKhUhUhUhUhUhUiPfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiQhUhUiKiKiKiKfRhUhUhUhUhUiLfhfhfhfhfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiShUhUgnhUgnhUhUhUhUhUhUhUismXfFfFfFfhepeuepeuepeuepeuepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhjqhUhUhUhUhUhUhUhWhYhXhUhUeKmAfFmIfFfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhfhfhhzhAhAhBfhfhfhfhfhkBfhfhkCkjkkfhepeuepeuepeuepeuepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbgcfahUeKjJjQiViWfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbhHdBdBgqdBdBdBezdBdBgrgsgtfagdeKhShRieiafhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhHhIeNgDgEgEgEgEgEgEgEgqgFgGfagdeKfhfhfhfhfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgodHdHdHdHdHdHdHdHdHdHgTkHkGfagdkPfhfWfFfIfhepeuepeuepeuepeuepabababababababababababdAezezezezezdCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhQeBgMgMeDeDeDeDeDeDeDgqgFhafagdhUfUfFfFelfhepepepepepepepepepabekekekekekekabababdAdZeCeDeEeDeFdYdCababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbhQdBdBgqdBdBdBezdBdBhigsgtfagdjOfhfFfFftfhepeuepeuepeuepeuepabeklflglglCekabababdGeLeMdHdHdHeNeOdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
-abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbhmfahUeKfhfFiUfYfhepepepepepepepepepabeAeJeJeJeJekabababdGeSeTeUeVdHeNeWdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhgBfhfhfhfhfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiQiMiJhUhUhUhUhUgdfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhUhUhUfDhUfDhUhUhUfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhUhUiKiKiKiKfRhUhUfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhfhfhfhhUfTiKiNiOiKhUhUgpfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhWhVishXiLiLfhhUhUiKiKiKiKfRhUjqfhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiPiPiPiPiPiPiThUhUgnhUgnhUhUhUiSfhfhfhfhfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhiPiPiPiPiPiPiThUhUhUhUhUhUhUhUeKmXfFfFfFfhepeuepeuepeuepeuepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhjHjHjLjIkBkBfhgthYhUhUhUhUhUhUeKmAfFmIfFfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhhzhAhAhBfhfhhzhAhAhBfhfhfhmYfhfhkCkjkkfhepeuepeuepeuepeuepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbgchUhUeKjJjQiViWfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhhHdBdBgqdBdBdBezdBdBgrgsiRgGhUhUeKhShRieiafhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhHhIeNgDgEgEgEgEgEgEgEgqgFgGkGhUhUeKfhfhfhfhfhepepepepepepepepepabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgodHdHdHdHdHdHdHdHdHdHgTrBkHfahUhUkPfhfWfFfIfhepeuepeuepeuepeuepabababababababababababdAezezezezezdCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhhQeBgMgMeDeDeDeDeDeDeDgqgFhafahUhUhUfUfFfFelfhepepepepepepepepepabekekekekekekabababdAdZeCeDeEeDeFdYdCababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhhQdBdBgqdBdBdBezdBdBhigsrChahUhUjOfhfFfFftfhepeuepeuepeuepeuepabeklflglglCekabababdGeLeMdHdHdHeNeOdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
+abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhgbgbgbgbgbgbgbgbgbgbgbgbgbhmhUhUeKfhfFiUfYfhepepepepepepepepepabeAeJeJeJeJekabababdGeSeTeUeVdHeNeWdGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhfhivfhfhfhfhfhfhababababababababababekeJkTfbfcekababdAfddBdBfedBfffgdBfddCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeifXhpfXfHhlfHfXhpfXeiabababekekekekekekekekekfklelcldekababdGfofofoezfpdHfqfrfsezabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababeifXfXfXgvemgvfXfXfXeiabababekfufnfnfnfSfGgegWeJeJeJhjfxfyfzdGfAfBfBfCdHdHdHdHfqdGabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index 77f195b9c79..55acfd5c3d3 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 ba6c6e60bfd..c9429803684 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
@@ -108,7 +108,7 @@ Passive gate is similar to the regular pump except:
else
ui.push_data(data)
-/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 e1069c9f1ae..85c5f1cf903 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
@@ -116,7 +116,7 @@ Thus, the two variables affect pump operation are set in New():
else
ui.push_data(data)
-/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 9d66f6c88bd..be8fbdc6ab0 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
@@ -112,7 +112,7 @@ Thus, the two variables affect pump operation are set in New():
else
ui.push_data(data)
-/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 985904f3bcd..7efeee86379 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -69,7 +69,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
@@ -143,7 +143,7 @@ Filter types:
return 1
-/obj/machinery/atmospherics/trinary/filter/initialize()
+/obj/machinery/atmospherics/trinary/filter/atmosinit()
set_frequency(frequency)
return ..()
@@ -216,4 +216,4 @@ Filter types:
if ((M.client && M.machine == src))
src.attack_hand(M)
*/
- return
\ No newline at end of file
+ return
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 8726dac92da..e80c0c7654b 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/preferences.dm b/code/__DEFINES/preferences.dm
index bc0dd8fc2b4..9c2e1ccb84a 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -34,7 +34,7 @@
#define BE_MALF 16
#define BE_REV 32
#define BE_ALIEN 64
-#define BE_PAI 128
+#define BE_PAI 128 //Includes Positronic brains, but the flag is already maxed.
#define BE_CULTIST 256
#define BE_BLOB 512
#define BE_NINJA 1024
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/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index 0db83ac6adb..d42d812db7a 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -41,7 +41,7 @@ var/list/be_special_flags = list(
"Malf AI" = BE_MALF,
"Revolutionary" = BE_REV,
"Alien Lifeform" = BE_ALIEN,
- "pAI" = BE_PAI,
+ "pAI/Positronic Brain" = BE_PAI,
"Cultist" = BE_CULTIST,
"Blob" = BE_BLOB,
"Ninja" = BE_NINJA,
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index fbde37f1d94..30350b2e9c2 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!
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index ec38e7265bb..137c1625a10 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -562,7 +562,7 @@
datum/configuration/proc/get_runnable_midround_modes(crew)
var/list/datum/game_mode/runnable_modes = new
- for(var/T in (typesof(/datum/game_mode) - /datum/game_mode))
+ for(var/T in (typesof(/datum/game_mode) - /datum/game_mode - ticker.mode.type))
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
qdel(M)
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index cd9aced630c..5cff548b620 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, 0.1),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..5c74da6d84d 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_machinery = 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_machinery,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_machinery()
+ cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, (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_machinery()
+ 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..55a11252c35 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()
@@ -40,7 +40,7 @@ var/datum/subsystem/npcpool/SSbp
for(var/obj/machinery/bot/check in botPool_l_non)
if(!check)
botPool_l_non.Cut(npcCount,npcCount+1)
-
+ continue
if(check.hacked)
needsHelp_non |= check
else if(check.frustration > 5) //average for most bots
@@ -53,9 +53,10 @@ var/datum/subsystem/npcpool/SSbp
//SNPC handling
for(var/mob/living/carbon/human/interactive/check in botPool_l)
- var/checkInRange = view(MAX_RANGE_FIND,check)
if(!check)
botPool_l.Cut(npcCount,npcCount+1)
+ continue
+ var/checkInRange = view(MAX_RANGE_FIND,check)
if(!(locate(check.TARGET) in checkInRange))
needsDelegate |= check
@@ -70,7 +71,11 @@ var/datum/subsystem/npcpool/SSbp
npcCount++
if(needsDelegate.len)
+ npcCount = 1 //reset the count
for(var/mob/living/carbon/human/interactive/check in needsDelegate)
+ if(!check)
+ needsDelegate.Cut(npcCount,npcCount+1)
+ continue
if(canBeUsed.len)
var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed)
var/facCount = 0
@@ -87,9 +92,14 @@ var/datum/subsystem/npcpool/SSbp
needsDelegate -= check
canBeUsed -= candidate
candidate.eye_color = "red"
+ npcCount++
if(needsAssistant.len)
+ npcCount = 1 //reset the count
for(var/mob/living/carbon/human/interactive/check in needsAssistant)
+ if(!check)
+ needsAssistant.Cut(npcCount,npcCount+1)
+ continue
if(canBeUsed.len)
var/mob/living/carbon/human/interactive/candidate = pick(canBeUsed)
var/facCount = 0
@@ -106,11 +116,18 @@ var/datum/subsystem/npcpool/SSbp
needsAssistant -= check
canBeUsed -= candidate
candidate.eye_color = "yellow"
+ npcCount++
if(needsHelp_non.len)
+ npcCount = 1 //reset the count
for(var/obj/machinery/bot/B in needsHelp_non)
+ if (!B)
+ needsHelp_non.Cut(npcCount,npcCount+1)
+ continue
if(canBeUsed_non.len)
var/obj/machinery/bot/candidate = pick(canBeUsed_non)
candidate.call_bot(B,get_turf(B),FALSE)
canBeUsed_non -= B
needsHelp_non -= candidate
+ npcCount++
+
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/shuttles/emergency.dm b/code/controllers/subsystem/shuttles/emergency.dm
index 4b9d061cd8a..157e199b2ad 100644
--- a/code/controllers/subsystem/shuttles/emergency.dm
+++ b/code/controllers/subsystem/shuttles/emergency.dm
@@ -43,7 +43,10 @@
else
return
- SSshuttle.emergencyLastCallLoc = signalOrigin
+ if(prob(70))
+ SSshuttle.emergencyLastCallLoc = signalOrigin
+ else
+ SSshuttle.emergencyLastCallLoc = null
priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlecalled.ogg', "Priority")
@@ -56,6 +59,8 @@
if(prob(70))
SSshuttle.emergencyLastCallLoc = signalOrigin
+ else
+ SSshuttle.emergencyLastCallLoc = null
priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
/*
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..842837fbee7 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -51,9 +51,9 @@ var/datum/subsystem/ticker/ticker
if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS])
login_music = 'sound/ambience/clown.ogg'
- 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,6 +78,8 @@ var/datum/subsystem/ticker/ticker
++totalPlayersReady
//countdown
+ if(timeLeft < 0)
+ return
timeLeft -= wait
if(timeLeft <= 30 && !tipped)
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/datumvars.dm b/code/datums/datumvars.dm
index d115d54b80d..c4e3856e295 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -790,7 +790,7 @@ body
if(result)
var/newtype = species_list[result]
- H.dna.species = new newtype()
+ hardset_dna(H, null, null, null, null, newtype)
H.regenerate_icons()
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
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/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 4eac92f16b9..f8ab83fe5b0 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -202,7 +202,7 @@
if(ishuman(affected_mob))
var/mob/living/carbon/human/human = affected_mob
if(human.dna && human.dna.species.id != "slime")
- human.dna.species = new /datum/species/slime()
+ hardset_dna(human, null, null, null, null, /datum/species/slime)
human.regenerate_icons()
/datum/disease/transformation/corgi
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 91826c2d749..8aaafde67b2 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -39,4 +39,6 @@ client/verb/showrevinfo()
src << "Enforce Human Authority: [config.enforce_human_authority]"
src << "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]"
src << "Protect Assistant From Antagonist: [config.protect_assistant_from_antagonist]"
+ src << "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes"
+ src << "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes"
return
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 97d113d445f..f7cf43e325e 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -455,6 +455,25 @@
sections["shadowling"] = text
+ /** Abductors **/
+
+ text = "Abductor"
+ if(ticker.mode.config_tag == "abductor")
+ text = uppertext(text)
+ text = "[text]: "
+ if(src in ticker.mode.abductors)
+ text += "Abductor|human"
+ text += "|undress|equip"
+ else
+ text += "Abductor|human"
+
+ if(current && current.client && current.client.prefs.be_special & BE_ABDUCTOR)
+ text += "|Enabled in Prefs"
+ else
+ text += "|Disabled in Prefs"
+
+ sections["abductor"] = text
+
/** MONKEY ***/
if (istype(current, /mob/living/carbon))
text = "monkey"
@@ -1074,6 +1093,26 @@
message_admins("[key_name_admin(usr)] has thrall'ed [current].")
log_admin("[key_name(usr)] has thrall'ed [current].")
+ else if(href_list["abductor"])
+ switch(href_list["abductor"])
+ if("clear")
+ usr << "Not implemented yet. Sorry!"
+ if("abductor")
+ if(!ishuman(current))
+ usr << "This only works on humans!"
+ return
+ make_Abductor()
+ log_admin("[key_name(usr)] turned [current] into abductor.")
+ if("equip")
+ var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
+ if(gear)
+ var/datum/game_mode/abduction/temp = new
+ temp.equip_common(current)
+ if(gear=="Agent")
+ temp.equip_agent(current)
+ else
+ temp.equip_scientist(current)
+
else if (href_list["monkey"])
var/mob/living/L = current
if (L.notransform)
@@ -1349,6 +1388,57 @@
ticker.mode.greet_gang(src)
ticker.mode.equip_gang(current)
+/datum/mind/proc/make_Abductor()
+ var/role = alert("Abductor Role ?","Role","Agent","Scientist")
+ var/team = input("Abductor Team ?","Team ?") in list(1,2,3,4)
+ var/teleport = alert("Teleport to ship ?","Teleport","Yes","No")
+
+ if(!role || !team || !teleport)
+ return
+
+ if(!ishuman(current))
+ return
+
+ ticker.mode.abductors |= src
+
+ var/datum/objective/experiment/O = new
+ O.owner = src
+ objectives += O
+
+ var/mob/living/carbon/human/H = current
+
+ hardset_dna(H,null,null,null,null,/datum/species/abductor,null)
+ var/datum/species/abductor/S = H.dna.species
+
+ switch(role)
+ if("Agent")
+ S.agent = 1
+ if("Scientist")
+ S.scientist = 1
+ S.team = team
+
+ var/list/obj/effect/landmark/abductor/agent_landmarks = new
+ var/list/obj/effect/landmark/abductor/scientist_landmarks = new
+ agent_landmarks.len = 4
+ scientist_landmarks.len = 4
+ for(var/obj/effect/landmark/abductor/A in landmarks_list)
+ if(istype(A,/obj/effect/landmark/abductor/agent))
+ agent_landmarks[text2num(A.team)] = A
+ else if(istype(A,/obj/effect/landmark/abductor/scientist))
+ scientist_landmarks[text2num(A.team)] = A
+
+ var/obj/effect/landmark/L
+ if(teleport=="Yes")
+ switch(role)
+ if("Agent")
+ S.agent = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+ if("Scientist")
+ S.scientist = 1
+ L = agent_landmarks[team]
+ H.loc = L.loc
+
/datum/mind/proc/AddSpell(var/obj/effect/proc_holder/spell/spell)
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/dna.dm b/code/game/dna.dm
index 58f5ac12a95..4a1bed49239 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -35,7 +35,7 @@
destination.dna.unique_enzymes = unique_enzymes
destination.dna.uni_identity = uni_identity
destination.dna.blood_type = blood_type
- destination.dna.species = species
+ hardset_dna(destination, null, null, null, null, species)
destination.dna.mutant_color = mutant_color
destination.dna.real_name = real_name
destination.dna.mutations = mutations
@@ -78,7 +78,7 @@
if(istype(character, /mob/living/carbon/human))
var/mob/living/carbon/human/H = character
if(!H.dna.species)
- H.dna.species = new /datum/species/human()
+ hardset_dna(H, null, null, null, null, /datum/species/human)
if(!hair_styles_list.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, hair_styles_list, hair_styles_male_list, hair_styles_female_list)
L[DNA_HAIR_STYLE_BLOCK] = construct_block(hair_styles_list.Find(H.hair_style), hair_styles_list.len)
@@ -138,6 +138,9 @@
create_dna(owner, mrace)
if(mrace)
+ if(owner.dna.species.exotic_blood)
+ var/datum/reagent/exotic_blood = owner.dna.species.exotic_blood
+ owner.reagents.del_reagent(exotic_blood.id)
owner.dna.species = new mrace()
if(mcolor)
diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm
index f3a73b5a032..f4d2c8efb47 100644
--- a/code/game/gamemodes/abduction/abduction.dm
+++ b/code/game/gamemodes/abduction/abduction.dm
@@ -102,7 +102,7 @@
H = agent.current
L = agent_landmarks[team_number]
H.loc = L.loc
- H.dna.species = new /datum/species/abductor()
+ hardset_dna(H, null, null, null, null, /datum/species/abductor)
S = H.dna.species
S.agent = 1
S.team = team_number
@@ -116,7 +116,7 @@
H = scientist.current
L = scientist_landmarks[team_number]
H.loc = L.loc
- H.dna.species = new /datum/species/abductor()
+ hardset_dna(H, null, null, null, null, /datum/species/abductor)
S = H.dna.species
S.scientist = 1
S.team = team_number
@@ -151,7 +151,7 @@
H = agent.current
L = agent_landmarks[team_number]
H.loc = L.loc
- H.dna.species = new /datum/species/abductor()
+ hardset_dna(H, null, null, null, null, /datum/species/abductor)
S = H.dna.species
S.agent = 1
S.team = team_number
@@ -165,7 +165,7 @@
H = scientist.current
L = scientist_landmarks[team_number]
H.loc = L.loc
- H.dna.species = new /datum/species/abductor()
+ hardset_dna(H, null, null, null, null, /datum/species/abductor)
S = H.dna.species
S.scientist = 1
S.team = team_number
@@ -223,6 +223,10 @@
return console
/datum/game_mode/abduction/proc/equip_agent(var/mob/living/carbon/human/agent,var/team_number)
+ if(!team_number)
+ var/datum/species/abductor/S = agent.dna.species
+ team_number = S.team
+
var/obj/machinery/abductor/console/console = get_team_console(team_number)
var/obj/item/clothing/suit/armor/abductor/vest/V = new /obj/item/clothing/suit/armor/abductor/vest(agent)
if(console!=null)
@@ -236,6 +240,10 @@
/datum/game_mode/abduction/proc/equip_scientist(var/mob/living/carbon/human/scientist,var/team_number)
+ if(!team_number)
+ var/datum/species/abductor/S = scientist.dna.species
+ team_number = S.team
+
var/obj/machinery/abductor/console/console = get_team_console(team_number)
var/obj/item/device/abductor/gizmo/G = new /obj/item/device/abductor/gizmo(scientist)
if(console!=null)
@@ -259,6 +267,7 @@
return ..()
/datum/game_mode/abduction/declare_completion()
+ world << "
The Abductors were:"
for(var/team_number=1,team_number<=teams,team_number++)
var/obj/machinery/abductor/console/console = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
@@ -274,7 +283,7 @@
world << "[team_name] team failed its mission! "
world << "Team Members: [agent.name]([agent.ckey])
[scientist.name]([scientist.ckey])"
- world << "Abductees:"
+ world << "
The Abductees were:"
display_abductees(console)
..()
@@ -285,20 +294,24 @@
for(var/mob/living/abductee in abductees)
if(!abductee.mind)
continue
- world << "[abductee.name]([abductee.ckey]))"
- var/count = 1
- for(var/datum/objective/objective in abductee.mind.objectives)
- if(objective.check_completion())
- world << "
Objective #[count]: [objective.explanation_text] Success!"
- else
- world << "
Objective #[count]: [objective.explanation_text] Fail."
- count++
+ world << printplayer(abductee.mind)
+ world << printobjectives(abductee.mind)
/datum/game_mode/proc/auto_declare_completion_abduction()
if(abductors.len)
- world << "Abductors:"
+ world << "
The Abductors were:"
for(var/datum/mind/M in abductors)
world << "Abductor [M.current ? M.current.name : "Abductor"]([M.key])"
+ world << printobjectives(M)
+ world << "
The Abductees were:"
+ var/list/full_history = list()
+ for(var/obj/machinery/abductor/console/C in machines)
+ full_history |= C.experiment.history
+ for(var/mob/living/abductee in full_history)
+ if(!abductee.mind)
+ continue
+ world << printplayer(abductee.mind)
+ world << printobjectives(abductee.mind)
return
//Landmarks
@@ -329,6 +342,19 @@ datum/objective/experiment/New()
explanation_text = "Experiment on [target_amount] humans"
datum/objective/experiment/check_completion()
+ if(!owner.current || !ishuman(owner.current))
+ return 0
+ var/mob/living/carbon/human/H = owner.current
+ if(!H.dna || !H.dna.species || !(H.dna.species.id == "abductor"))
+ return 0
+ var/datum/species/abductor/S = H.dna.species
+ var/ab_team = S.team
+ for(var/obj/machinery/abductor/experiment/E in machines)
+ if(E.team == ab_team)
+ if(E.points >= target_amount)
+ return 1
+ else
+ return 0
return 0
datum/objective/abductee
diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm
index 0b8b72cb227..a13b347907c 100644
--- a/code/game/gamemodes/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/abduction/abduction_gear.dm
@@ -11,6 +11,7 @@
icon_state = "vest_stealth"
item_state = "armor"
blood_overlay_type = "armor"
+ origin_tech = "materials=5;biotech=4;powerstorage=5"
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15)
action_button_name = "Activate"
action_button_is_hands_free = 1
@@ -147,6 +148,7 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "gizmo_scan"
item_state = "silencer"
+ origin_tech = "materials=5;magnets=5;bluespace=6"
var/mode = GIZMO_SCAN
var/mob/living/marked = null
var/obj/machinery/abductor/console/console
@@ -208,6 +210,8 @@
user << "You mark the target for future retrieval."
else
prepare(target,user)
+ else
+ prepare(target,user)
/obj/item/device/abductor/gizmo/proc/prepare(var/atom/target, var/mob/living/user)
if(get_dist(target,user)>1)
@@ -225,6 +229,7 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "silencer"
item_state = "gizmo"
+ origin_tech = "materials=5;magnets=5"
/obj/item/device/abductor/silencer/attack(mob/living/M, mob/user)
if(!AbductorCheck(user))
@@ -246,6 +251,8 @@
var/mob/living/carbon/human/M
for(M in view(2,targloc))
+ if(M == user)
+ continue
user << "You silence [M.name] radio devices."
radio_off_mob(M)
@@ -327,7 +334,8 @@ Congratulations! You are now trained for xenobiology research!"}
#define BATON_STUN 0
#define BATON_SLEEP 1
#define BATON_CUFF 2
-#define BATON_MODES 3
+#define BATON_PROBE 3
+#define BATON_MODES 4
/obj/item/weapon/abductor_baton
name = "Advanced Baton"
@@ -336,6 +344,7 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "wonderprod"
item_state = "wonderprod"
slot_flags = SLOT_BELT
+ origin_tech = "materials=6;combat=5;biotech=7"
force = 7
w_class = 3
action_button_name = "Toggle Mode"
@@ -350,6 +359,8 @@ Congratulations! You are now trained for xenobiology research!"}
txt = "sleep inducment"
if(BATON_CUFF)
txt = "restraining"
+ if(BATON_PROBE)
+ txt = "probing"
usr << "You switch the baton to [txt] mode"
update_icon()
@@ -362,6 +373,8 @@ Congratulations! You are now trained for xenobiology research!"}
icon_state = "wonderprod"
if(BATON_CUFF)
icon_state = "wonderprod"
+ if(BATON_PROBE)
+ icon_state = "wonderprod"
/obj/item/weapon/abductor_baton/proc/IsAbductor(var/mob/living/user)
if(!ishuman(user))
@@ -384,11 +397,6 @@ Congratulations! You are now trained for xenobiology research!"}
if(!isliving(target))
return
- if(user.a_intent == "help")
- target.visible_message("[user] probes [target] with [src]!", \
- "[user] probed [target]!")
- return
-
var/mob/living/L = target
user.do_attack_animation(L)
@@ -399,6 +407,8 @@ Congratulations! You are now trained for xenobiology research!"}
SleepAttack(L,user)
if(BATON_CUFF)
CuffAttack(L,user)
+ if(BATON_PROBE)
+ ProbeAttack(L,user)
/obj/item/weapon/abductor_baton/attack_self(mob/living/user)
toggle(user)
@@ -450,6 +460,19 @@ Congratulations! You are now trained for xenobiology research!"}
user << "You fail to handcuff [C]."
return
+/obj/item/weapon/abductor_baton/proc/ProbeAttack(mob/living/L,mob/living/user)
+ L.visible_message("[user] probes [L] with [src]!", \
+ "[user] probed [L]!")
+
+ var/species = "Unknown Species"
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.dna && H.dna.species)
+ species = "[H.dna.species.name]"
+ if(L.mind && L.mind.changeling)
+ species = "Changeling Lifeform"
+ user << "Probing Result:[species]"
+
/obj/item/weapon/restraints/handcuffs/energy
name = "energy cuffs"
desc = "Energy field restraining the hands."
@@ -505,10 +528,11 @@ Congratulations! You are now trained for xenobiology research!"}
/obj/item/clothing/head/helmet/abductor
name = "Agent Headgear"
- desc = "Abducting with style. Spiky style."
+ desc = "Abducting with style. Spiky style. Prevents digital tracking."
icon_state = "alienhelmet"
item_state = "alienhelmet"
blockTracking = 1
+ origin_tech = "materials=6;magnets=5"
// Operating Table / Beds / Lockers
diff --git a/code/game/gamemodes/abduction/gland.dm b/code/game/gamemodes/abduction/gland.dm
index b20e7c98b85..17f7416f268 100644
--- a/code/game/gamemodes/abduction/gland.dm
+++ b/code/game/gamemodes/abduction/gland.dm
@@ -104,7 +104,7 @@ obj/item/gland/slime/activate()
/obj/item/gland/pop/activate()
host << "You feel weird."
var/species = pick(list(/datum/species/lizard,/datum/species/slime,/datum/species/plant/pod,/datum/species/fly))
- host.dna.species = new species()
+ hardset_dna(host, null, null, null, null, species)
host.regenerate_icons()
return
@@ -252,4 +252,4 @@ obj/item/gland/slime/activate()
if(istype(T))
T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C,300)
host.gib()
- return
\ No newline at end of file
+ return
diff --git a/code/game/gamemodes/abduction/machinery/console.dm b/code/game/gamemodes/abduction/machinery/console.dm
index bfaeefa3e2c..89f37c05ccf 100644
--- a/code/game/gamemodes/abduction/machinery/console.dm
+++ b/code/game/gamemodes/abduction/machinery/console.dm
@@ -51,6 +51,11 @@
if(experiment != null)
var/points = experiment.points
dat += "Collected Samples : [points]
"
+ dat += "Transfer data in exchange for supplies:
"
+ dat += "Advanced Baton
"
+ dat += "Agent Helmet
"
+ dat += "Radio Silencer
"
+ dat += "Science Tool
"
else
dat += "NO EXPERIMENT MACHINE DETECTED
"
@@ -101,6 +106,16 @@
FlipVest()
else if(href_list["select_disguise"])
SelectDisguise()
+ else if(href_list["dispense"])
+ switch(href_list["dispense"])
+ if("baton")
+ Dispense(/obj/item/weapon/abductor_baton,cost=2)
+ if("helmet")
+ Dispense(/obj/item/clothing/head/helmet/abductor)
+ if("silencer")
+ Dispense(/obj/item/device/abductor/silencer)
+ if("tool")
+ Dispense(/obj/item/device/abductor/gizmo)
src.updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterSet()
@@ -181,4 +196,17 @@
user << "You link the vest to the console."
vest = V
else
- ..()
\ No newline at end of file
+ ..()
+
+/obj/machinery/abductor/console/proc/Dispense(var/item,var/cost=1)
+ if(experiment && experiment.points >= cost)
+ experiment.points-=cost
+ say("Incoming supply!")
+ if(pad)
+ flick("alien-pad", pad)
+ new item(pad.loc)
+ else
+ new item(src.loc)
+ else
+ say("Insufficent data!")
+ return
\ No newline at end of file
diff --git a/code/game/gamemodes/abduction/machinery/pad.dm b/code/game/gamemodes/abduction/machinery/pad.dm
index 081f746a085..b586874397d 100644
--- a/code/game/gamemodes/abduction/machinery/pad.dm
+++ b/code/game/gamemodes/abduction/machinery/pad.dm
@@ -49,7 +49,7 @@
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
-/obj/machinery/abductor/pad/proc/Retrieve(var/mob/living/carbon/human/target)
+/obj/machinery/abductor/pad/proc/Retrieve(var/mob/living/target)
flick("alien-pad", src)
spawn(0)
anim(target.loc,target,'icons/mob/mob.dmi',,"uncloak",,target.dir)
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/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index c8d581d08e9..3ea33223508 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -82,9 +82,9 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
/datum/game_mode/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(joined_player_list.len/config.changeling_scaling_coeff) )
- if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
+ if(ticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
return
- if(changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
+ if(ticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
if(character.client.prefs.be_special & BE_CHANGELING)
if(!jobban_isbanned(character.client, "changeling") && !jobban_isbanned(character.client, "Syndicate"))
if(age_check(character.client))
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index e567eaac5bf..7b13ecf03da 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -17,7 +17,7 @@
user.dna = chosen_dna
user.real_name = chosen_dna.real_name
- user.dna.species = new chosen_dna.species.type(user)
+ hardset_dna(user, null, null, null, null, chosen_dna.species.type)
user.dna.mutant_color = chosen_dna.mutant_color
updateappearance(user)
domutcheck(user)
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 25960b275f3..1a228ff3c4d 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -66,10 +66,10 @@
/datum/game_mode/traitor/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(joined_player_list.len/(config.changeling_scaling_coeff*2)) )
- if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
+ if(ticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
..()
return
- if(changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
+ if(ticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4)))
if(character.client.prefs.be_special & BE_CHANGELING)
if(!jobban_isbanned(character.client, "changeling") && !jobban_isbanned(character.client, "Syndicate"))
if(age_check(character.client))
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 738c4852782..83c10f02e99 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -34,6 +34,7 @@
var/list/datum/game_mode/replacementmode = null
var/round_converted = 0 //0: round not converted, 1: round going to convert, 2: round converted
var/reroll_friendly //During mode conversion only these are in the running
+ var/continuous_sanity_checked //Catches some cases where config options could be used to suggest that modes without antagonists should end when all antagonists die
var/enemy_minimum_age = 7 //How many days must players have been playing before they can play this antagonist
var/const/waittime_l = 600
@@ -174,6 +175,19 @@
if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || station_was_nuked)
return 1
if(!round_converted && (!config.continuous[config_tag] || (config.continuous[config_tag] && config.midround_antag[config_tag]))) //Non-continuous or continous with replacement antags
+ if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place
+ for(var/mob/living/Player in mob_list)
+ if(Player.mind)
+ if(Player.mind.special_role)
+ continuous_sanity_checked = 1
+ return 0
+ if(!continuous_sanity_checked)
+ message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.")
+ config.continuous[config_tag] = 1
+ config.midround_antag[config_tag] = 0
+ return 0
+
+
if(living_antag_player && living_antag_player.mind && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player))
return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark.
@@ -473,6 +487,17 @@ proc/display_roundstart_logout_report()
return text
+/datum/game_mode/proc/printobjectives(var/datum/mind/ply)
+ var/text = ""
+ var/count = 1
+ for(var/datum/objective/objective in ply.objectives)
+ if(objective.check_completion())
+ text += "
Objective #[count]: [objective.explanation_text] Success!"
+ else
+ text += "
Objective #[count]: [objective.explanation_text] Fail."
+ count++
+ return text
+
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
/datum/game_mode/proc/age_check(client/C)
if(get_remaining_days(C) == 0)
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/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
index 6ce9c6a44cf..7e4fb0e05fd 100644
--- a/code/game/gamemodes/traitor/double_agents.dm
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -5,7 +5,6 @@
required_players = 25
required_enemies = 5
recommended_enemies = 8
- reroll_friendly = 1
traitor_name = "double agent"
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 37e40099e0b..eab9be0c79d 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -75,9 +75,9 @@
/datum/game_mode/traitor/make_antag_chance(var/mob/living/carbon/human/character) //Assigns traitor to latejoiners
var/traitorcap = min(round(joined_player_list.len / (config.traitor_scaling_coeff * 2)) + 2 + num_modifier, round(joined_player_list.len/config.traitor_scaling_coeff) + num_modifier )
- if(traitors.len >= traitorcap) //Upper cap for number of latejoin antagonists
+ if(ticker.mode.traitors.len >= traitorcap) //Upper cap for number of latejoin antagonists
return
- if(traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2)))
+ if(ticker.mode.traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2)))
if(character.client.prefs.be_special & BE_TRAITOR)
if(!jobban_isbanned(character.client, "traitor") && !jobban_isbanned(character.client, "Syndicate"))
if(age_check(character.client))
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 eea599dd0f0..1ee28a02cbf 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 77c7bc33a6c..e50fbf9bae4 100644
--- a/code/game/machinery/bots/bots.dm
+++ b/code/game/machinery/bots/bots.dm
@@ -113,6 +113,8 @@
Radio.listening = 0 //Makes bot radios transmit only so no one hears things while adjacent to one.
/obj/machinery/bot/Destroy()
+ qdel(Radio)
+ qdel(botcard)
..()
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 3e0dac86a35..dd7eb081ded 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -73,11 +73,10 @@
//Cameras can't track people wearing an agent card or a ninja hood.
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
continue
- //Generic variable who's existance is to blame on shitty old ninja code
- if(istype(H.head, /obj/item/clothing/head))
- var/obj/item/clothing/head/hat = H.head
- if(hat.blockTracking)
- continue
+ if(istype(H.head, /obj/item/clothing/head))
+ var/obj/item/clothing/head/hat = H.head
+ if(hat.blockTracking)
+ continue
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
if(!near_camera(M))
@@ -130,10 +129,10 @@
U << "Follow camera mode terminated."
U.cameraFollow = null
return
- if(istype(H.head, /obj/item/clothing/head))
- var/obj/item/clothing/head/hat = H.head
- if(hat.blockTracking)
- U << "Follow camera mode terminated."
+ if(istype(H.head, /obj/item/clothing/head))
+ var/obj/item/clothing/head/hat = H.head
+ if(hat.blockTracking)
+ U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(H.digitalcamo)
@@ -194,4 +193,4 @@
else
if (sorttext(a.c_tag, b.c_tag) < 0)
L.Swap(j, j + 1)
- return L
\ No newline at end of file
+ return L
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 2be45dacd4c..801e2f82332 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -130,10 +130,14 @@
if(!M.brainmob)
user << "Sticking an empty MMI into the frame would sort of defeat the purpose!"
return
- if(M.brainmob.stat == 2)
+ if(M.brainmob.stat == DEAD)
user << "Sticking a dead brain into the frame would sort of defeat the purpose!"
return
+ if(!M.brainmob.client)
+ user << "Sticking an inactive brain into the frame would sort of defeat the purpose."
+ return
+
if((config) && (!config.allow_ai))
user << "This MMI does not seem to fit!"
return
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 851bf6e643f..ec2b1ff5362 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
@@ -80,7 +83,6 @@
return 0
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(var/mob/user)
- ..()
open_machine()
/obj/machinery/atmospherics/unary/cryo_cell/container_resist()
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/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index ac30218b651..9498dbb81c9 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -12,6 +12,8 @@
density = 0
opacity = 0
+/obj/machinery/door/poddoor/ert
+ desc = "A heavy duty blast door that only opens for dire emergencies."
/obj/machinery/door/poddoor/Bumped(atom/AM)
if(density)
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..1ec4c229900 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)
@@ -302,7 +312,7 @@
var/mob/living/carbon/human/human = M
if(human.dna && human.dna.species.id == "human")
M << "You hear a buzzing in your ears."
- human.dna.species = new /datum/species/fly()
+ hardset_dna(human, null, null, null, null, /datum/species/fly)
human.regenerate_icons()
human.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), IRRADIATE, 0)
calibrated = 0
@@ -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 75f81e40bb8..a2d76e96a5a 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/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 42d25b93a92..8061b162c74 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -666,9 +666,9 @@ obj/mecha/proc/can_use(mob/user)
if(istype(W, /obj/item/device/mmi))
if(mmi_move_inside(W,user))
- user << "[src]-MMI interface initialized successfuly"
+ user << "[src]-[W] interface initialized successfuly"
else
- user << "[src]-MMI interface initialization failed."
+ user << "[src]-[W] interface initialization failed."
return
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
@@ -1137,6 +1137,7 @@ obj/mecha/proc/can_use(mob/user)
if(mmi.brainmob)
occupant.loc = mmi
mmi.mecha = null
+ mmi.update_icon()
src.occupant.canmove = 0
src.verbs += /obj/mecha/verb/eject
src.occupant = null
@@ -1518,7 +1519,7 @@ var/year_integer = text2num(year) // = 2013???
return
if(href_list["dna_lock"])
if(usr != src.occupant) return
- if(src.occupant)
+ if(src.occupant && occupant.dna)
src.dna = src.occupant.dna.unique_enzymes
src.occupant_message("You feel a prick as the needle takes your DNA sample.")
return
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..ae8595b7e96 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -55,10 +55,6 @@
secequipment += loc
qdel(src)
return
- if("Deathsquad")
- deathsquadspawn += loc
- qdel(src)
- return
if("Emergencyresponseteam")
emergencyresponseteamspawn += loc
qdel(src)
@@ -87,6 +83,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.dm b/code/game/objects/items.dm
index 167d325c099..e586ab90a8b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -318,28 +318,32 @@
/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
+ var/is_human_victim = 0
+ if(ishuman(M))
+ is_human_victim = 1
+ var/mob/living/carbon/human/H = M
+ if((H.head && H.head.flags & HEADCOVERSEYES) || \
(H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- // you can't stab someone in the eyes wearing a mask!
- user << "You're going to need to remove that mask/helmet/glasses first!"
- return
+ (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))
+ // you can't stab someone in the eyes wearing a mask!
+ user << "You're going to need to remove that mask/helmet/glasses first!"
+ return
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- // you can't stab someone in the eyes wearing a mask!
- user << "You're going to need to remove that mask/helmet/glasses first!"
- return
+ if(ismonkey(M))
+ var/mob/living/carbon/monkey/Mo = M
+ if(Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES)
+ // you can't stab someone in the eyes wearing a mask!
+ user << "You're going to need to remove that mask/helmet/glasses first!"
+ return
if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes!
user << "You cannot locate any eyes on this creature!"
return
+ if(isbrain(M))
+ user << "You cannot locate any organic eyes on this brain!"
+ return
+
add_logs(user, M, "attacked", object="[src.name]", addition="(INTENT: [uppertext(user.a_intent)])")
src.add_fingerprint(user)
@@ -352,7 +356,7 @@
"[user] has stabbed themself in the eyes with [src]!", \
"You stab yourself in the eyes with [src]!" \
)
- if(istype(M, /mob/living/carbon/human))
+ if(is_human_victim)
var/mob/living/carbon/human/U = M
var/obj/item/organ/limb/affecting = U.get_organ("head")
if(affecting.take_damage(7))
@@ -360,6 +364,7 @@
else
M.take_organ_damage(7)
+
M.eye_blurry += rand(3,4)
M.eye_stat += rand(2,4)
if (M.eye_stat >= 10)
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/crayons.dm b/code/game/objects/items/crayons.dm
index 958edb93f01..731a7324b81 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -38,7 +38,7 @@
desc = "A very sad-looking crayon."
colour = "#FFFFFF"
colourName = "mime"
- uses = 0
+ uses = -1
/obj/item/toy/crayon/mime/attack_self(mob/living/user as mob)
update_window(user)
@@ -63,7 +63,7 @@
icon_state = "crayonrainbow"
colour = "#FFF000"
colourName = "rainbow"
- uses = 0
+ uses = -1
/obj/item/toy/crayon/rainbow/attack_self(mob/living/user as mob)
update_window(user)
@@ -111,7 +111,7 @@
user << "It is empty."
/obj/item/toy/crayon/spraycan/attack_self(mob/living/user as mob)
- var/choice = input(user,"Spraycan options") in list("Toggle Cap","Change Drawing","Change Color","Cancel")
+ var/choice = input(user,"Spraycan options") as null|anything in list("Toggle Cap","Change Drawing","Change Color")
switch(choice)
if("Toggle Cap")
user << "You [capped ? "Remove" : "Replace"] the cap of the [src]"
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/devices/recaller.dm b/code/game/objects/items/devices/recaller.dm
index 1fdf9794b96..08cb37b0837 100644
--- a/code/game/objects/items/devices/recaller.dm
+++ b/code/game/objects/items/devices/recaller.dm
@@ -31,15 +31,16 @@
if(user.mind in (ticker.mode.A_bosses | ticker.mode.B_bosses))
dat += "Give this device to another member of your organization to use.
"
else
- dat += "Register Device
"
+ dat += "Register Device
"
else
var/gang_size = ((gang == "A")? (ticker.mode.A_gang.len + ticker.mode.A_bosses.len) : (ticker.mode.B_gang.len + ticker.mode.B_bosses.len))
var/gang_territory = ((gang == "A")? ticker.mode.A_territory.len : ticker.mode.B_territory.len)
var/points = ((gang == "A") ? ticker.mode.gang_points.A : ticker.mode.gang_points.B)
- dat += "Registration: [(gang == "A")? gang_name("A") : gang_name("B")] Gang [boss ? "Administrator" : "Member"]
"
+ dat += "Registration: [(gang == "A")? gang_name("A") : gang_name("B")] Gang [boss ? "Administrator" : "Lieutenant"]
"
dat += "Organization Size: [gang_size]
"
dat += "Station Control: [round((gang_territory/start_state.num_territories)*100, 1)]%
"
+ dat += "Rally Your Gang
"
dat += "Recall Emergency Shuttle
"
dat += "
"
dat += "Influence: [points]
"
@@ -70,8 +71,8 @@
else
dat += "10mm Ammo
"
- dat += "(50 Influence) "
- if(points >= 50)
+ dat += "(40 Influence) "
+ if(points >= 40)
dat += "Recruitment Pen
"
else
dat += "Recruitment Pen
"
@@ -99,6 +100,12 @@
add_fingerprint(usr)
+ if(href_list["register"])
+ register_device(usr)
+
+ else if(!gang) //Gangtool must be registered before you can use the functions below
+ return
+
if(href_list["purchase"])
var/points = ((gang == "A") ? ticker.mode.gang_points.A : ticker.mode.gang_points.B)
var/item_type
@@ -120,9 +127,9 @@
item_type = /obj/item/ammo_box/magazine/m10mm
points = 10
if("pen")
- if(points >= 50)
+ if(points >= 40)
item_type = /obj/item/weapon/pen/gang
- points = 50
+ points = 40
if("gangtool")
if((promotions < 3) && (points >= (promotions*20)+10))
item_type = /obj/item/device/gangtool/lt
@@ -144,12 +151,34 @@
switch(href_list["choice"])
if("recall")
recall(usr)
- if("register")
- register_device(usr)
-
+ if("ping")
+ ping_gang(usr)
attack_self(usr)
+
+/obj/item/device/gangtool/proc/ping_gang(var/mob/user)
+ if(!user)
+ return
+ var/area/location = get_area(user)
+ if(location && location.z != 1)
+ user << "\icon[src]Error: Signal out of range of station."
+ return
+ var/list/members = list()
+ if(gang == "A")
+ members += ticker.mode.A_bosses | ticker.mode.A_gang
+ else if(gang == "B")
+ members += ticker.mode.B_bosses | ticker.mode.B_gang
+ if(members.len)
+ for(var/datum/mind/ganger in members)
+ ganger.current << "A powerful thought invades your mind... The gang is rallying at [location]!"
+ log_game("[key_name(user)] summoned the [gang_name(gang)] Gang ([gang]) to [location].")
+
+
/obj/item/device/gangtool/proc/register_device(var/mob/user)
+ if(jobban_isbanned(user, "gangster") || jobban_isbanned(user, "Syndicate"))
+ user << "\icon[src] ACCESS DENIED: Blacklisted user."
+ return 0
+
var/promoted
if(user.mind in (ticker.mode.A_gang | ticker.mode.A_bosses))
ticker.mode.A_tools += src
@@ -185,26 +214,39 @@
if(recalling || !can_use(user))
return
- var/turf/userturf = get_turf(user)
- if(userturf.z != 1)
- user << "\icon[src]Error: Device out of range of station communication arrays."
- return
+ recalling = 1
+ loc << "\icon[src]Generating shuttle recall order with codes retrieved from last call signal..."
- if(SSshuttle.emergency.mode == SHUTTLE_CALL)
- recalling = 1
- loc << "\icon[src]Generating shuttle recall order with codes retrieved from last call signal..."
- sleep(rand(10,30))
- loc << "\icon[src]Shuttle recall order generated. Accessing station long-range communication arrays..."
- sleep(rand(10,30))
- loc << "\icon[src]Comm arrays accessed. Broadcasting recall signal..."
- sleep(rand(10,30))
+ sleep(rand(10,30))
+
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station
+ user << "\icon[src]Emergency shuttle cannot be recalled at this time."
recalling = 0
- log_game("[key_name(user)] has recalled the shuttle with a gangtool.")
- message_admins("[key_name_admin(user)] has recalled the shuttle with a gangtool.", 1)
- if(!SSshuttle.cancelEvac(user))
- loc << "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time."
return
- user << "\icon[src]Emergency shuttle cannot be recalled at this time."
+ loc << "\icon[src]Shuttle recall order generated. Accessing station long-range communication arrays..."
+
+ sleep(rand(10,30))
+
+ var/turf/userturf = get_turf(user)
+ if(userturf.z != 1) //Shuttle can only be recalled while on station
+ user << "\icon[src]Error: Device out of range of station communication arrays."
+ recalling = 0
+ return
+ var/datum/station_state/end_state = new /datum/station_state()
+ end_state.count()
+ if((100 * start_state.score(end_state)) < 70) //Shuttle cannot be recalled if the station is too damaged
+ user << "\icon[src]Error: Station communication systems compromised. Unable to establish connection."
+ recalling = 0
+ return
+ loc << "\icon[src]Comm arrays accessed. Broadcasting recall signal..."
+
+ sleep(rand(10,30))
+
+ recalling = 0
+ log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.")
+ message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1)
+ if(!SSshuttle.cancelEvac(user))
+ loc << "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time."
/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user)
if(!istype(user))
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 2ea78ce58f9..3b9868babac 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -165,26 +165,25 @@
if(!M.brainmob)
user << "Sticking an empty MMI into the frame would sort of defeat the purpose!"
return
- if(!M.brainmob.key)
- var/ghost_can_reenter = 0
- if(M.brainmob.mind)
- for(var/mob/dead/observer/G in player_list)
- if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
- ghost_can_reenter = 1
- break
- if(!ghost_can_reenter)
- user << "The MMI indicates that their mind is completely unresponsive; there's no point!"
- return
- if(M.brainmob.stat == DEAD)
+ var/mob/living/carbon/brain/BM = M.brainmob
+ if(!BM.key || !BM.mind)
+ user << "The mmi indicates that their mind is completely unresponsive; there's no point!"
+ return
+
+ if(!BM.client) //braindead
+ user << "The mmi indicates that their mind is currently inactive; it might change!"
+ return
+
+ if(BM.stat == DEAD)
user << "Sticking a dead brain into the frame would sort of defeat the purpose!"
return
- if((M.brainmob.mind in ticker.mode.head_revolutionaries) || (M.brainmob.mind in ticker.mode.A_bosses) || (M.brainmob.mind in ticker.mode.B_bosses))
+ if((BM.mind in ticker.mode.head_revolutionaries) || (BM.mind in ticker.mode.A_bosses) || (BM.mind in ticker.mode.B_bosses))
user << "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the MMI!"
return
- if(jobban_isbanned(M.brainmob, "Cyborg"))
+ if(jobban_isbanned(BM, "Cyborg"))
user << "This MMI does not seem to fit!"
return
@@ -211,7 +210,7 @@
if(ticker.mode.config_tag == "malfunction") //Don't let humans get a cyborg on their side during malf, for balance reasons.
O.set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*�&110010")
- M.brainmob.mind.transfer_to(O)
+ BM.mind.transfer_to(O)
if(O.mind && O.mind.special_role)
O.mind.store_memory("As a cyborg, any objectives listed here are null and void, and will be marked as failed. They are simply here for memory purposes.")
@@ -223,6 +222,7 @@
chest.cell = null
W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
O.mmi = W
+ O.updatename()
feedback_inc("cyborg_birth",1)
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/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 07fe7a7defc..3621e21d852 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -427,21 +427,22 @@
//Check area validity. Reject space, player-created areas, and non-station z-levels.
if (gangID)
- var/area/user_area = get_area(user.loc)
territory = get_area(target)
if(territory && (territory.z == ZLEVEL_STATION) && territory.valid_territory)
//Check if this area is already tagged by a gang
if(!(locate(/obj/effect/decal/cleanable/crayon/gang) in target)) //Ignore the check if the tile being sprayed has a gang tag
if(territory_claimed(territory, user))
return
+ /*
//Prevent people spraying from outside of the territory (ie. Maint walls)
- if(istype(user_area) && (user_area.type == territory.type))
- if(locate(/obj/machinery/power/apc) in (user.loc.contents | target.contents))
- user << "You cannot tag here."
- return
- else
+ var/area/user_area = get_area(user.loc)
+ if(istype(user_area) && (user_area.type != territory.type))
user << "You cannot tag [territory] from the outside."
return
+ */
+ if(locate(/obj/machinery/power/apc) in (user.loc.contents | target.contents))
+ user << "You cannot tag here."
+ return
else
user << "[territory] is unsuitable for tagging."
return
@@ -481,6 +482,8 @@
user << "You finish [instant ? "spraying" : "drawing"] [temp]."
if(instant<0)
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
+ if(uses < 0)
+ return
uses = max(0,uses-1)
if(!uses)
user << "There is no more of [src.name] left!"
@@ -492,6 +495,8 @@
if(edible && (M == user))
user << "You take a bite of the [src.name]. Delicious!"
user.nutrition += 5
+ if(uses < 0)
+ return
uses = max(0,uses-5)
if(!uses)
user << "There is no more of [src.name] left!"
diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm
index 360e473ab26..019f94a0761 100644
--- a/code/game/objects/items/weapons/RPD.dm
+++ b/code/game/objects/items/weapons/RPD.dm
@@ -211,7 +211,7 @@ var/global/list/RPD_recipes=list(
if(found)
preview=new /icon(I.icon,I.icon_state)
if(screen == I.categoryId)
- if(I.id == p_type)
+ if(I.id == p_type && p_class >= 0)
datbuild += "[label]"
else
datbuild += I.Render(src,label)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 00f3fbfd3b2..dcc041016ee 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -196,22 +196,22 @@ update_label("John Doe", "Clowny")
icon_state = "centcom"
registered_name = "Emergency Response Team Commander"
assignment = "Emergency Response Team Commander"
- New() access = get_all_accesses()+get_ert_access("commander")
+ New() access = get_all_accesses()+get_ert_access("commander")-access_change_ids
/obj/item/weapon/card/id/ert/Security
registered_name = "Security Response Officer"
assignment = "Security Response Officer"
- New() access = get_all_accesses()+get_ert_access("sec")
+ New() access = get_all_accesses()+get_ert_access("sec")-access_change_ids
/obj/item/weapon/card/id/ert/Engineer
registered_name = "Engineer Response Officer"
assignment = "Engineer Response Officer"
- New() access = get_all_accesses()+get_ert_access("eng")
+ New() access = get_all_accesses()+get_ert_access("eng")-access_change_ids
/obj/item/weapon/card/id/ert/Medical
registered_name = "Medical Response Officer"
assignment = "Medical Response Officer"
- New() access = get_all_accesses()+get_ert_access("med")
+ New() access = get_all_accesses()+get_ert_access("med")-access_change_ids
/obj/item/weapon/card/id/prisoner
name = "prisoner ID card"
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 091dc25d6d0..b39486a9742 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -221,8 +221,8 @@
if(world.time > last_event+15)
active = 1
for(var/mob/living/L in range(3,src))
- L.irradiate(12)
- for(var/turf/simulated/wall/mineral/uranium/T in range(3,src))
+ L.irradiate(4)
+ for(var/turf/simulated/wall/mineral/uranium/T in orange(1,src))
T.radiate()
last_event = world.time
active = null
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 3776b5306e2..6eb5f7b9317 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -136,7 +136,7 @@
if(!newrace || !H.dna)
return
- H.dna.species = new newrace
+ hardset_dna(H, null, null, null, null, newrace)
if(H.dna.species.use_skintones)
var/new_s_tone = input(user, "What are we again?", "Race change") as null|anything in skin_tones
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/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index fd1e0824295..cd75b4ac155 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -3,7 +3,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
"damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2",
"platingdmg3","plating","light_on","light_on_flicker1","light_on_flicker2",
"light_on_clicker3","light_on_clicker4","light_on_clicker5","light_broken",
- "light_on_broken","light_off","wall_thermite","grass1","grass2","grass3","grass4",
+ "light_on_broken","light_off","wall_thermite","grass", "sand",
"asteroid","asteroid_dug",
"asteroid0","asteroid1","asteroid2","asteroid3","asteroid4",
"asteroid5","asteroid6","asteroid7","asteroid8","asteroid9","asteroid10","asteroid11","asteroid12",
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index b2e008e7df3..e7d3d075d78 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -38,14 +38,13 @@
/turf/simulated/floor/fancy/grass
name = "Grass patch"
- icon_state = "grass1"
+ icon_state = "grass"
floor_tile = /obj/item/stack/tile/grass
- broken_states = list("sand1", "sand2", "sand3")
+ broken_states = list("sand")
ignoredirt = 1
/turf/simulated/floor/fancy/grass/New()
..()
- icon_state = "grass[pick("1","2","3","4")]"
spawn(1)
update_icon()
fancy_update(type)
diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm
index be064079ef9..ca8716d2d82 100644
--- a/code/game/turfs/simulated/floor/mineral_floor.dm
+++ b/code/game/turfs/simulated/floor/mineral_floor.dm
@@ -165,7 +165,7 @@
active = 1
for(var/mob/living/L in range(3,src))
L.irradiate(1)
- for(var/turf/simulated/floor/mineral/uranium/T in range(3,src))
+ for(var/turf/simulated/floor/mineral/uranium/T in orange(1,src))
T.radiate()
last_event = world.time
active = 0
diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm
index ffa184a2a66..c61a20cb100 100644
--- a/code/game/turfs/simulated/walls_mineral.dm
+++ b/code/game/turfs/simulated/walls_mineral.dm
@@ -64,8 +64,8 @@
if(world.time > last_event+15)
active = 1
for(var/mob/living/L in range(3,src))
- L.irradiate(12)
- for(var/turf/simulated/wall/mineral/uranium/T in range(3,src))
+ L.irradiate(4)
+ for(var/turf/simulated/wall/mineral/uranium/T in orange(1,src))
T.radiate()
last_event = world.time
active = null
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/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm
index ca6b69118a5..e6d3be6adfe 100644
--- a/code/game/turfs/unsimulated/floor.dm
+++ b/code/game/turfs/unsimulated/floor.dm
@@ -20,12 +20,12 @@
/turf/unsimulated/floor/grass
- icon_state = "grass1"
-
-/turf/unsimulated/floor/grass/New()
- ..()
- icon_state = "grass[rand(1,4)]"
+ icon_state = "grass"
/turf/unsimulated/floor/abductor
name = "alien floor"
icon_state = "alienpod1"
+
+/turf/unsimulated/floor/abductor/New()
+ ..()
+ icon_state = "alienpod[rand(1,9)]"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index d9a4d08f85b..6524d509250 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -581,7 +581,7 @@ var/global/floorIsLava = 0
set name="Start Now"
if(ticker.current_state == GAME_STATE_PREGAME)
ticker.can_fire = 1
- ticker.current_state = GAME_STATE_SETTING_UP
+ ticker.timeLeft = 0
log_admin("[usr.key] has started the game.")
message_admins("[usr.key] has started the game.")
feedback_add_details("admin_verb","SN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -634,17 +634,21 @@ var/global/floorIsLava = 0
/datum/admins/proc/delay()
set category = "Server"
set desc="Delay the game start"
- set name="Delay"
+ set name="Delay pre-game"
+
+ var/newtime = input("Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(ticker.timeLeft/10)) as num|null
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)
- world << "The game start has been delayed."
- log_admin("[key_name(usr)] delayed the game.")
- else
- world << "The game will start soon."
- log_admin("[key_name(usr)] removed the delay.")
- feedback_add_details("admin_verb","DELAY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(newtime)
+ ticker.timeLeft = newtime * 10
+ if(newtime < 0)
+ world << "The game start has been delayed."
+ log_admin("[key_name(usr)] delayed the round start.")
+ else
+ world << "The game will start in [newtime] seconds."
+ world << 'sound/ai/attention.ogg'
+ log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.")
+ feedback_add_details("admin_verb","DELAY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/immreboot()
set category = "Server"
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 1154a8591e1..01bf8b06c6f 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -307,9 +307,11 @@
/datum/admins/proc/check_antagonists()
if (ticker && ticker.current_state >= GAME_STATE_PLAYING)
var/dat = "
| Ghost Roles | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| pAI | " + jobs += "[replacetext("pAI", " ", " ")] | " else - jobs += "pAI | " + jobs += "[replacetext("pAI", " ", " ")] | " + + + //Drones + if(jobban_isbanned(M, "drone")) + jobs += "[replacetext("Drone", " ", " ")] | " + else + jobs += "[replacetext("Drone", " ", " ")] | " + + + //Positronic Brains + if(jobban_isbanned(M, "posibrain")) + jobs += "[replacetext("Posibrain", " ", " ")] | " + else + jobs += "[replacetext("Posibrain", " ", " ")] | " + + + //Deathsquad + if(jobban_isbanned(M, "deathsquad")) + jobs += "[replacetext("Deathsquad", " ", " ")] | " + else + jobs += "[replacetext("Deathsquad", " ", " ")] | " jobs += "