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 = "Round Status

Round Status

" - dat += "Current Game Mode: [ticker.mode.name]
" if(ticker.mode.replacementmode) + dat += "Former Game Mode: [ticker.mode.name]
" dat += "Replacement Game Mode: [ticker.mode.replacementmode.name]
" + else + dat += "Current Game Mode: [ticker.mode.name]
" dat += "Round Duration: [round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]
" dat += "Emergency shuttle
" if(SSshuttle.emergency.mode < SHUTTLE_CALL) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7dbb6838046..d6399ed88d6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -107,7 +107,6 @@ message_admins("[key_name_admin(usr)] tried to create an abductor team. Unfortunatly there were not enough candidates available.") log_admin("[key_name(usr)] failed to create an abductor team.") if("15") - message_admins("[key_name(usr)] is creating a revenant...") if(src.makeRevenant()) message_admins("[key_name(usr)] created a revenant.") log_admin("[key_name(usr)] created a revenant.") @@ -650,11 +649,38 @@ jobs += "" counter = 0 - //pAI isn't technically a job, but it goes in here. + jobs += "" + + //Ghost Roles (light light gray) + jobs += "" + jobs += "" + + //pAI if(jobban_isbanned(M, "pAI")) - jobs += "" + jobs += "" else - jobs += "" + jobs += "" + + + //Drones + if(jobban_isbanned(M, "drone")) + jobs += "" + else + jobs += "" + + + //Positronic Brains + if(jobban_isbanned(M, "posibrain")) + jobs += "" + else + jobs += "" + + + //Deathsquad + if(jobban_isbanned(M, "deathsquad")) + jobs += "" + else + jobs += "" jobs += "
Ghost Roles
pAI[replacetext("pAI", " ", " ")]pAI[replacetext("pAI", " ", " ")][replacetext("Drone", " ", " ")][replacetext("Drone", " ", " ")][replacetext("Posibrain", " ", " ")][replacetext("Posibrain", " ", " ")][replacetext("Deathsquad", " ", " ")][replacetext("Deathsquad", " ", " ")]
" @@ -713,12 +739,6 @@ else jobs += "[replacetext("Abductor", " ", " ")]" - //Deathsquad - if(jobban_isbanned(M, "deathsquad") || isbanned_dept) - jobs += "[replacetext("Deathsquad", " ", " ")]" - else - jobs += "[replacetext("Deathsquad", " ", " ")]" - /* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment if(jobban_isbanned(M, "malf AI") || isbanned_dept) jobs += "[replacetext("Malf AI", " ", " ")]" @@ -808,6 +828,8 @@ var/datum/job/temp = SSjob.GetJob(jobPos) if(!temp) continue joblist += temp.title + if("ghostroles") + joblist += list("pAI", "posibrain", "drone", "deathsquad") else joblist += href_list["jobban3"] @@ -1806,7 +1828,7 @@ message_admins("\blue [key_name_admin(usr)] turned all humans into [result]") var/newtype = species_list[result] for(var/mob/living/carbon/human/H in mob_list) - H.dna.species = new newtype() + hardset_dna(H, null, null, null, null, newtype) H.regenerate_icons() if("corgi") feedback_inc("admin_secrets_fun_used",1) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 58882c03e99..89fea828905 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -856,43 +856,23 @@ var/global/list/g_fancy_list_of_types = null equip_deathsquad(M) if("emergency response officer") + var/alert + if(alert("Code Red ERT?","Select Response Level","Yes","No")=="Yes") + alert = 1 + else + alert = 0 switch(input("Which class?") in list("Commander","Security","Engineer","Medic")) if("Commander") - equip_emergencyresponsesquad(M, "commander") + equip_emergencyresponsesquad(M, "commander",alert) if("Security") - equip_emergencyresponsesquad(M, "sec") + equip_emergencyresponsesquad(M, "sec",alert) if("Engineer") - equip_emergencyresponsesquad(M, "eng") + equip_emergencyresponsesquad(M, "eng",alert) if("Medic") - equip_emergencyresponsesquad(M, "med") + equip_emergencyresponsesquad(M, "med",alert) if("centcom official") - M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) - M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(M), slot_shoes) - M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves) - M.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_cent(M), slot_ears) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) - M.equip_to_slot_or_del(new /obj/item/weapon/pen(M), slot_l_store) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(M), slot_back) - - var/obj/item/device/pda/heads/pda = new(M) - pda.owner = M.real_name - pda.ownjob = "Centcom Official" - pda.update_label() - - M.equip_to_slot_or_del(pda, slot_r_store) - - M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_l_hand) - - var/obj/item/weapon/card/id/W = new(M) - W.icon_state = "centcom" - W.access = get_centcom_access("Centcom Official") - W.access += access_weapons - W.assignment = "Centcom Official" - W.registered_name = M.real_name - W.update_label() - M.equip_to_slot_or_del(W, slot_wear_id) + equip_centcomofficial(M) if("centcom commander") M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_commander(M), slot_w_uniform) @@ -1099,8 +1079,8 @@ var/global/list/g_fancy_list_of_types = null var/dat = "List of things that failed to GC this round

" - for(var/path in SSgarbage.logging) - dat += "[path] - [SSgarbage.logging[path]] times
" + for(var/path in SSgarbage.didntgc) + dat += "[path] - [SSgarbage.didntgc[path]] times
" usr << browse(dat, "window=dellog") @@ -1156,7 +1136,7 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(W, slot_wear_id) //Emergency Response Team -/proc/equip_emergencyresponsesquad(var/mob/living/carbon/human/M, var/ertrole) +/proc/equip_emergencyresponsesquad(var/mob/living/carbon/human/M, var/ertrole, var/alert) var/obj/item/weapon/card/id/W = null var/obj/item/device/radio/R = new /obj/item/device/radio/headset/headset_cent/alt(M) R.set_frequency(CENTCOM_FREQ) @@ -1170,19 +1150,23 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/hardsuit/ert(M), slot_wear_suit) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(W, slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(M), slot_back) - M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/full(M), slot_belt) - M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store) R.keyslot = new /obj/item/device/encryptionkey/heads/captain + if(alert) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(M), slot_l_store) + else + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/switchblade(M), slot_l_store) + if("sec") W = new /obj/item/weapon/card/id/ert/Security(M) M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) @@ -1192,16 +1176,20 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(W, slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/handcuffs(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/carbine/loyalpin(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/full(M), slot_belt) R.keyslot = new /obj/item/device/encryptionkey/heads/hos + if(alert) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/carbine/loyalpin(M), slot_in_backpack) + else + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(M), slot_in_backpack) + if("med") W = new /obj/item/weapon/card/id/ert/Medical(M) M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) @@ -1211,18 +1199,21 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(W, slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical(M), slot_belt) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(M), slot_r_hand) R.keyslot = new /obj/item/device/encryptionkey/heads/cmo + if(alert) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(M), slot_in_backpack) + else + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat(M), slot_in_backpack) + if("eng") W = new /obj/item/weapon/card/id/ert/Engineer(M) M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) @@ -1232,17 +1223,21 @@ var/global/list/g_fancy_list_of_types = null M.equip_to_slot_or_del(W, slot_wear_id) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/meson/engine(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/rcd/combat(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_l_store) R.keyslot = new /obj/item/device/encryptionkey/heads/ce + if(alert) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/loyalpin(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/rcd/combat(M), slot_in_backpack) + else + M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/rcd/loaded(M), slot_in_backpack) + R.recalculateChannels() var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M) @@ -1252,4 +1247,33 @@ var/global/list/g_fancy_list_of_types = null if (W) W.registered_name = M.real_name - W.update_label(W.registered_name, W.assignment) \ No newline at end of file + W.update_label(W.registered_name, W.assignment) + + +/proc/equip_centcomofficial(var/mob/living/carbon/human/M) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_cent(M), slot_ears) + M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/pen(M), slot_l_store) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(M), slot_back) + + var/obj/item/device/pda/heads/pda = new(M) + pda.owner = M.real_name + pda.ownjob = "Centcom Official" + pda.update_label() + + M.equip_to_slot_or_del(pda, slot_r_store) + + M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_l_hand) + + var/obj/item/weapon/card/id/W = new(M) + W.icon_state = "centcom" + W.access = get_centcom_access("Centcom Official") + W.access += access_weapons + W.assignment = "Centcom Official" + W.registered_name = M.real_name + W.update_label() + M.equip_to_slot_or_del(W, slot_wear_id) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index d4cd11aad0d..fb2f3bff40f 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -20,8 +20,7 @@ client/proc/one_click_antag() Make Gangsters
Make Wizard (Requires Ghosts)
Make Nuke Team (Requires Ghosts)
- Make Deathsquad (Requires Ghosts)
- Make Emergency Response Team (Requires Ghosts)
+ Make Centcom Response Team (Requires Ghosts)
Make Abductor Team (Requires Ghosts)
Make Revenant (Requires Ghost)
"} @@ -320,7 +319,7 @@ client/proc/one_click_antag() if(candidates.len >= 2) //Minimum 2 to be considered a squad //Pick the lucky players var/numagents = min(5,candidates.len) //How many commandos to spawn - var/list/spawnpoints = deathsquadspawn + var/list/spawnpoints = emergencyresponseteamspawn while(numagents && candidates.len) if (numagents > spawnpoints.len) numagents-- @@ -343,6 +342,9 @@ client/proc/one_click_antag() equip_deathsquad(Commando) Commando.key = chosen_candidate.key Commando.mind.assigned_role = "Death Commando" + for(var/obj/machinery/door/poddoor/ert/door in airlocks) + spawn(0) + door.open() //Assign antag status and the mission ticker.mode.traitors += Commando.mind @@ -410,15 +412,73 @@ client/proc/one_click_antag() return 0 -// EMERGENCY RESPONSE TEAM +/datum/admins/proc/makeOfficial() + var/mission = input("Assign a task for the official", "Assign Task", "Conduct a routine preformance review of [station_name()] and its Captain.") + var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered to be a Centcom Official?", "pAI") + + if(candidates.len) + var/mob/dead/observer/chosen_candidate = pick(candidates) + + //Create the official + var/mob/living/carbon/human/newmob = new (pick(emergencyresponseteamspawn)) + chosen_candidate.client.prefs.copy_to(newmob) + ready_dna(newmob) + newmob.real_name = random_name(newmob.gender) + newmob.key = chosen_candidate.key + newmob.mind.assigned_role = "Centcom Official" + equip_centcomofficial(newmob) + + //Assign antag status and the mission + ticker.mode.traitors += newmob.mind + newmob.mind.special_role = "centcom" + var/datum/objective/missionobj = new + missionobj.owner = newmob.mind + missionobj.explanation_text = mission + missionobj.completed = 1 + newmob.mind.objectives += missionobj + + //Greet the official + newmob << "You are a Centcom Official." + newmob << "
Central Command is sending you to [station_name()] with the task: [mission]" + + //Logging and cleanup + message_admins("A [key_name_admin(newmob)] has spawned with the task: [mission]") + log_game("[key_name(newmob)] has been selected as a Centcom Official") + + return 1 + + return 0 + +// CENTCOM RESPONSE TEAM /datum/admins/proc/makeEmergencyresponseteam() + var/alert = input("Which team should we send?", "Select Response Level") as null|anything in list("Green: Centcom Official", "Blue: Light ERT", "Amber: Full ERT", "Red: Elite ERT", "Delta: Deathsquad") + if(!alert) + return + switch(alert) + if("Delta: Deathsquad") + makeDeathsquad() + return + if("Red: Elite ERT") + alert = "Red" + if("Amber: Full ERT") + alert = "Amber" + if("Blue: Light ERT") + alert = "Blue" + if("Green: Centcom Official") + makeOfficial() + return + var/teamsize = min(7,input("Maximum size of team? (7 max)", "Select Team Size",4) as null|num) var/mission = input("Assign a mission to the Emergency Response Team", "Assign Mission", "Assist the station.") - var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for an elite Nanotrasen Emergency Response Team?", "deathsquad", null) + var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for a Code [alert] Nanotrasen Emergency Response Team?", "deathsquad", null) var/teamSpawned = 0 - if(candidates.len >= 4) //Minimum 4 to be considered a squad + if(candidates.len > 0) //Pick the (un)lucky players - var/numagents = min(7,candidates.len) //How many officers to spawn + var/numagents = min(teamsize,candidates.len) //How many officers to spawn + var/redalert //If the ert gets super weapons + if (alert == "Red") + numagents = min(teamsize,candidates.len) + redalert = 1 var/list/spawnpoints = emergencyresponseteamspawn while(numagents && candidates.len) if (numagents > spawnpoints.len) @@ -438,28 +498,34 @@ client/proc/one_click_antag() switch(numagents) if(1) ERTOperative.real_name = "Commander [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "commander") + equip_emergencyresponsesquad(ERTOperative, "commander",redalert) if(2) ERTOperative.real_name = "Security Officer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "sec") + equip_emergencyresponsesquad(ERTOperative, "sec",redalert) if(3) ERTOperative.real_name = "Medical Officer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "med") + equip_emergencyresponsesquad(ERTOperative, "med",redalert) if(4) ERTOperative.real_name = "Engineer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "eng") + equip_emergencyresponsesquad(ERTOperative, "eng",redalert) if(5) ERTOperative.real_name = "Security Officer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "sec") + equip_emergencyresponsesquad(ERTOperative, "sec",redalert) if(6) ERTOperative.real_name = "Medical Officer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "med") + equip_emergencyresponsesquad(ERTOperative, "med",redalert) if(7) ERTOperative.real_name = "Engineer [pick(lastname)]" - equip_emergencyresponsesquad(ERTOperative, "eng") + equip_emergencyresponsesquad(ERTOperative, "eng",redalert) ERTOperative.key = chosen_candidate.key ERTOperative.mind.assigned_role = "ERT" + //Open the Armory doors + if(alert != "Blue") + for(var/obj/machinery/door/poddoor/ert/door in airlocks) + spawn(0) + door.open() + //Assign antag status and the mission ticker.mode.traitors += ERTOperative.mind ERTOperative.mind.special_role = "ert" @@ -471,7 +537,7 @@ client/proc/one_click_antag() //Greet the commando ERTOperative << "You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"]." - var/missiondesc = "Your squad is being sent on a mission to [station_name()] by Nanotrasen's Security Division." + var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division." if(numagents == 1) //If Squad Leader missiondesc += " Lead your squad to ensure the completion of the mission. Avoid civilian casualites when possible. Board the shuttle when your team is ready." else @@ -481,7 +547,7 @@ client/proc/one_click_antag() //Logging and cleanup if(numagents == 1) - message_admins("The emergency response team has spawned with the mission: [mission].") + message_admins("A Code [alert] emergency response team has spawned with the mission: [mission]") log_game("[key_name(ERTOperative)] has been selected as an Emergency Response Officer") numagents-- teamSpawned++ @@ -576,7 +642,6 @@ client/proc/one_click_antag() G << 'sound/misc/notice2.ogg' //Alerting them to their consideration switch(alert(G,Question,"Please answer in 30 seconds!","Yes","No")) if("Yes") - G << 'sound/machines/ping.ogg' G << "Choice registered: Yes." if((world.time-time_passed)>300)//If more than 30 game seconds passed. G << "Sorry, you were too late for the consideration!" @@ -585,7 +650,6 @@ client/proc/one_click_antag() candidates += G if("No") G << "Choice registered: No." - G << 'sound/machines/buzz-sigh.ogg' return else return diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 82e183bf91f..04df14ff933 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -42,7 +42,7 @@ var/sound/admin_sound if(!check_rights(R_SOUNDS)) return if(ticker) - ticker.round_end_sound = S + ticker.round_end_sound = fcopy_rsc(S) else return diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 2fa4f53b808..c17e1f6d7e0 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -80,19 +80,19 @@ user.dna.add_mutation(LASEREYES) user.dna.add_mutation(COLDRES) user.dna.add_mutation(XRAY) - user.dna.species = new /datum/species/shadow() + hardset_dna(user, null, null, null, null, /datum/species/shadow) user.regenerate_icons() if("Wealth") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart." new /obj/structure/closet/syndicate/resources/everything(loc) - user.dna.species = new /datum/species/shadow() + hardset_dna(user, null, null, null, null, /datum/species/shadow) user.regenerate_icons() if("Immortality") user << "Your wish is granted, but at a terrible cost..." user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart." user.verbs += /mob/living/carbon/proc/immortality - user.dna.species = new /datum/species/shadow() + hardset_dna(user, null, null, null, null, /datum/species/shadow) user.regenerate_icons() if("To Kill") user << "Your wish is granted, but at a terrible cost..." @@ -107,7 +107,7 @@ for(var/datum/objective/OBJ in user.mind.objectives) user << "Objective #[obj_count]: [OBJ.explanation_text]" obj_count++ - user.dna.species = new /datum/species/shadow() + hardset_dna(user, null, null, null, null, /datum/species/shadow) user.regenerate_icons() if("Peace") user << "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence." diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 201dde00b62..9d5fa2ec38b 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -11,7 +11,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "malf AI" = /datum/game_mode/malfunction, //4 "revolutionary" = /datum/game_mode/revolution, //5 "alien", //6 - "pAI", //7 + "pAI/posibrain", //7 "cultist" = /datum/game_mode/cult, //8 "blob" = /datum/game_mode/blob, //9 "ninja", //10 @@ -920,9 +920,9 @@ datum/preferences if(character.dna) character.dna.real_name = character.real_name if(pref_species != /datum/species/human && config.mutant_races) - character.dna.species = new pref_species.type() + hardset_dna(character, null, null, null, null, pref_species.type) else - character.dna.species = new /datum/species/human() + hardset_dna(character, null, null, null, null, /datum/species/human) character.dna.mutant_color = mutant_color character.update_mutcolor() diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 803f7f5ab1a..9222cd16304 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -63,7 +63,7 @@ new_holder.mind.objectives += O new_holder.attack_log += "\[[time_stamp()]\] Won with greentext!!!" color_altered_mobs -= new_holder - Destroy() + qdel(src) if(last_holder && last_holder != new_holder) //Somehow it was swiped without ever getting dropped last_holder << "A sudden wave of failure washes over you..." diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm index 96d8c5ea8ff..37d67c8815d 100644 --- a/code/modules/events/wizard/race.dm +++ b/code/modules/events/wizard/race.dm @@ -16,7 +16,7 @@ for(var/mob/living/carbon/human/H in mob_list) //yes, even the dead if(H.dna) - H.dna.species = new new_species + hardset_dna(H, null, null, null, null, new_species) H.regenerate_icons() H << "You feel somehow... different?" if(!all_the_same) diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index 36c20650400..66569eae964 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -44,10 +44,9 @@ speak_emote = list("sniffles","twitches") emote_hear = list("hops.") emote_see = list("hops around","bounces up and down") - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1) egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg/loaded food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot - meat_amount = 1 eggsleft = 10 eggsFertile = FALSE icon_prefix = "rabbit" diff --git a/code/modules/lighting/lighting_system.dm b/code/modules/lighting/lighting_system.dm index 7c7eb7264a5..0eaa7f94b23 100644 --- a/code/modules/lighting/lighting_system.dm +++ b/code/modules/lighting/lighting_system.dm @@ -224,7 +224,7 @@ anchored = 1 /atom/movable/light/Destroy() - return 1 + return QDEL_HINT_LETMELIVE /atom/movable/light/Move() return 0 diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 0b649aec99d..95838e1b90d 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -7,6 +7,7 @@ icon_state = "mmi_empty" w_class = 3 origin_tech = "biotech=3" + var/braintype = "Cyborg" req_access = list(access_robotics) @@ -18,7 +19,19 @@ var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm. var/obj/item/organ/brain/brain = null //The actual brain +/obj/item/device/mmi/update_icon() + if(brain) + if(istype(brain,/obj/item/organ/brain/alien)) + icon_state = "mmi_alien" + braintype = "Xenoborg" //HISS....Beep. + else + icon_state = "mmi_full" + braintype = "Cyborg" + else + icon_state = "mmi_empty" + /obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) if(istype(O,/obj/item/organ/brain)) //Time to stick a brain in it --NEO var/obj/item/organ/brain/newbrain = O if(brain) @@ -27,6 +40,14 @@ if(!newbrain.brainmob) user << "You aren't sure where this brain came from, but you're pretty sure it's a useless brain!" return + + var/mob/living/carbon/brain/B = newbrain.brainmob + if(!B.key) + var/mob/dead/observer/ghost = B.get_ghost() + if(ghost) + if(ghost.client) + ghost << "Someone has put your brain in a MMI. Return to your body! (Verbs -> Ghost -> Re-enter corpse)" + ghost << sound('sound/effects/genetics.ogg') visible_message("[user] sticks \a [newbrain] into \the [src].") brainmob = newbrain.brainmob @@ -42,10 +63,7 @@ brain = newbrain name = "Man-Machine Interface: [brainmob.real_name]" - if(istype(newbrain,/obj/item/organ/brain/alien)) - icon_state = "mmi_alien" - else - icon_state = "mmi_full" + update_icon() locked = 1 @@ -82,7 +100,7 @@ brain.loc = usr.loc brain = null //No more brain in here - icon_state = "mmi_empty" + update_icon() name = "Man-Machine Interface" /obj/item/device/mmi/proc/transfer_identity(var/mob/living/carbon/human/H) //Same deal as the regular brain proc. Used for human-->robot people. @@ -99,7 +117,7 @@ brain = newbrain name = "Man-Machine Interface: [brainmob.real_name]" - icon_state = "mmi_full" + update_icon() locked = 1 return @@ -149,3 +167,17 @@ qdel(brainmob) brainmob = null ..() + +/obj/item/device/mmi/examine(mob/user) + ..() + if(brainmob) + var/mob/living/carbon/brain/B = brainmob + if(!B.key || !B.mind || B.stat == DEAD) + user << "The MMI indicates the brain is completely unresponsive." + + else if(!B.client) + user << "The MMI indicates the brain is currently inactive; it might change." + + else + user << "The MMI indicates the brain is active." + diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index be2b01d8732..fff5bebcdeb 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -124,16 +124,27 @@ return 1 /mob/living/carbon/brain/handle_disabilities() - return + //Eyes + if(disabilities & BLIND || stat) + eye_blind = max(eye_blind, 1) + else + if(eye_blind) + eye_blind = 0 + if(eye_blurry) + eye_blurry = 0 + if(eye_stat) + eye_stat = 0 + + //Ears + if(disabilities & DEAF) + setEarDamage(-1, max(ear_deaf, 1)) + else if(ear_damage < 100) + setEarDamage(0, 0) /mob/living/carbon/brain/handle_status_effects() return /mob/living/carbon/brain/handle_regular_hud_updates() - handle_vision() - handle_hud_icons_health() - return 1 - diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm new file mode 100644 index 00000000000..9a788562cdb --- /dev/null +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -0,0 +1,146 @@ +/obj/item/device/mmi/posibrain + name = "positronic brain" + desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." + icon = 'icons/obj/assemblies.dmi' + icon_state = "posibrain" + w_class = 3 + origin_tech = "biotech=3;programming=2" + var/searching = 0 + var/askDelay = 10 * 60 * 1 + brainmob = null + req_access = list(access_robotics) + locked = 0 + mecha = null//This does not appear to be used outside of reference in mecha.dm. + braintype = "Android" + + +/obj/item/device/mmi/posibrain/attack_self(mob/user as mob) + if(brainmob && !brainmob.key && searching == 0) + //Start the process of searching for a new user. + user << "You carefully locate the manual activation switch and start the positronic brain's boot process." + searching = 1 + update_icon() + request_player() + spawn(600) + reset_search() + +/obj/item/device/mmi/posibrain/proc/request_player() + for(var/mob/dead/observer/O in player_list) + if(jobban_isbanned(O, "posibrain")) + continue + if(O.client) + if(O.client.prefs.be_special & BE_PAI) + question(O.client) + +/obj/item/device/mmi/posibrain/proc/question(var/client/C) + spawn(0) + if(!C) return + var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") + if(!C || brainmob.key || 0 == searching) + return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(response == "Yes") + transfer_personality(C.mob) + else if (response == "Never for this round") + C.prefs.be_special ^= BE_PAI + + +/obj/item/device/mmi/posibrain/transfer_identity(var/mob/living/carbon/H) + name = "positronic brain ([H])" + brainmob.name = H.real_name + brainmob.real_name = H.real_name + brainmob.dna = H.dna + brainmob.timeofhostdeath = H.timeofdeath + brainmob.stat = 0 + if(brainmob.mind) + brainmob.mind.assigned_role = "Positronic Brain" + if(H.mind) + H.mind.transfer_to(brainmob) + + brainmob.mind.remove_all_antag() + brainmob.mind.wipe_memory() + + brainmob << "ALL PAST LIVES ARE FORGOTTEN." + + brainmob << "Hello World!" + update_icon() + return + +/obj/item/device/mmi/posibrain/proc/transfer_personality(var/mob/candidate) + + searching = 0 + brainmob.mind = candidate.mind + brainmob.ckey = candidate.ckey + name = "positronic brain ([brainmob.name])" + + brainmob.mind.remove_all_antag() + brainmob.mind.wipe_memory() + + brainmob << "ALL PAST LIVES ARE FORGOTTEN." + + brainmob << "You are a positronic brain, brought into existence on [station_name()]." + brainmob << "As a synthetic intelligence, you answer to all crewmembers, as well as the AI." + brainmob << "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm." + brainmob.mind.assigned_role = "Positronic Brain" + + visible_message("The positronic brain chimes quietly.") + update_icon() + +/obj/item/device/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. + + if(brainmob && brainmob.key) return + + searching = 0 + update_icon() + + visible_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") + +/obj/item/device/mmi/posibrain/examine() + + set src in oview() + + if(!usr || !src) return + if( (usr.disabilities & BLIND || usr.stat) && !istype(usr,/mob/dead/observer) ) + usr << "Something is there but you can't see it." + return + + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n" + msg += "" + + if(brainmob && brainmob.key) + switch(brainmob.stat) + if(CONSCIOUS) + if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk + if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" + if(DEAD) msg += "It appears to be completely inactive.\n" + else + msg += "It appears to be completely inactive.\n" + msg += "*---------*" + usr << msg + return + +/obj/item/device/mmi/posibrain/New() + + brainmob = new(src) + brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR"))]-[rand(100, 999)]" + brainmob.real_name = brainmob.name + brainmob.loc = src + brainmob.container = src + brainmob.stat = 0 + brainmob.silent = 0 + dead_mob_list -= brainmob + + ..() + + +/obj/item/device/mmi/posibrain/attackby(var/obj/item/O as obj, var/mob/user as mob) + return + + +/obj/item/device/mmi/posibrain/update_icon() + if(searching) + icon_state = "posibrain-searching" + return + if(brainmob && brainmob.key) + icon_state = "posibrain-occupied" + else + icon_state = "posibrain" diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 85c96398045..4326f45dad2 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -48,7 +48,7 @@ /mob/living/carbon/human/proc/makeSkeleton() if(!check_dna_integrity(src)) return status_flags |= DISFIGURED - dna.species = new /datum/species/skeleton(src) + hardset_dna(src, null, null, null, null, /datum/species/skeleton) return 1 /mob/living/carbon/proc/ChangeToHusk() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c1a0e21b364..e0269ea62f0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -49,6 +49,7 @@ /mob/living/carbon/human/Destroy() for(var/atom/movable/organelle in organs) qdel(organelle) + organs = list() return ..() /mob/living/carbon/human/Stat() diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index f87374ee822..6d52c0ea386 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -12,7 +12,7 @@ /datum/species/human/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) if(chem.id == "mutationtoxin") H << "Your flesh rapidly mutates!" - H.dna.species = new /datum/species/slime() + hardset_dna(H, null, null, null, null, /datum/species/slime) H.regenerate_icons() H.reagents.del_reagent(chem.type) H.faction |= "slime" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8c64cbf773e..5ef8323ec04 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -23,16 +23,16 @@ Sorry Giacom. Please don't be mad :( /mob/living/Destroy() - . = ..() + ..() for(var/mob/living/simple_animal/drone/D in player_list) for(var/image/I in staticOverlays) D.staticOverlays.Remove(I) D.client.images.Remove(I) - del(I) + qdel(I) staticOverlays.len = 0 - del(src) + return QDEL_HINT_HARDDEL_NOW /mob/living/proc/generateStaticOverlay() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 089dda47e20..c3269390c52 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -218,9 +218,14 @@ var/list/ai_list = list() var/area/borg_area for(var/mob/living/silicon/robot/R in connected_robots) borg_area = get_area(R) + var/robot_status = "Nominal" + if(R.stat || !R.client) + robot_status = "OFFLINE" + else if(!R.cell || R.cell.charge <= 0) + robot_status = "DEPOWERED" //Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies! stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "Empty"] | \ - Module: [R.designation] | Loc: [borg_area.name] | Status: [R.stat || !R.client ? "OFFLINE" : "Normal"]")) + Module: [R.designation] | Loc: [borg_area.name] | Status: [robot_status]")) else stat(null, text("Systems nonfunctional")) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index d24c734f219..33ba6d1056f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -59,6 +59,7 @@ /mob/living/silicon/ai/Destroy() eyeobj.ai = null qdel(eyeobj) // No AI, no Eye + eyeobj = null ..() /atom/proc/move_camera_by_click() diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 3e12bfe9639..3cdc1c7008b 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -225,7 +225,7 @@ else src << "Unusable emote '[act]'. Say *help for a list." - if ((message && src.stat == 0)) + if (message && src.stat == CONSCIOUS) log_emote("[name]/[key] : [message]") if (m_type & 1) visible_message(message) diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 15457054fbc..ca469d59ec4 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -27,6 +27,9 @@ else msg += "Its cover is closed[locked ? "" : ", and looks unlocked"].\n" + if(cell && cell.charge <= 0) + msg += "Its battery indicator is blinking red!\n" + switch(src.stat) if(CONSCIOUS) if(!src.client) msg += "It appears to be in stand-by mode.\n" //afk diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index df8ebcfd28d..1842c6f157f 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -59,6 +59,7 @@ var/toner = 0 var/tonermax = 40 var/jetpackoverlay = 0 + var/braintype = "Cyborg" /mob/living/silicon/robot/New(loc) spark_system = new /datum/effect/effect/system/spark_spread() @@ -72,7 +73,6 @@ robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it. ident = rand(1, 999) - updatename() update_icons() if(!cell) @@ -100,17 +100,20 @@ ..() //MMI stuff. Held togheter by magic. ~Miauw - mmi = new(src) - mmi.brain = new /obj/item/organ/brain(mmi) - mmi.brain.name = "[real_name]'s brain" - mmi.locked = 1 - mmi.icon_state = "mmi_full" - mmi.name = "Man-Machine Interface: [real_name]" - mmi.brainmob = new(src) - mmi.brainmob.name = src.real_name - mmi.brainmob.real_name = src.real_name - mmi.brainmob.container = mmi - mmi.contents += mmi.brainmob + if(!mmi || !mmi.brainmob) + mmi = new(src) + mmi.brain = new /obj/item/organ/brain(mmi) + mmi.brain.name = "[real_name]'s brain" + mmi.locked = 1 + mmi.icon_state = "mmi_full" + mmi.name = "Man-Machine Interface: [real_name]" + mmi.brainmob = new(src) + mmi.brainmob.name = src.real_name + mmi.brainmob.real_name = src.real_name + mmi.brainmob.container = mmi + mmi.contents += mmi.brainmob + + updatename() playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) aicamera = new/obj/item/device/camera/siliconcam/robot_camera(src) @@ -123,6 +126,7 @@ if(T) mmi.loc = T if(mmi.brainmob) mind.transfer_to(mmi.brainmob) + mmi.update_icon() else src << "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug." ghostize() @@ -236,7 +240,7 @@ if(custom_name) changed_name = custom_name else - changed_name = "[(designation ? "[designation] " : "")]Cyborg-[num2text(ident)]" + changed_name = "[(designation ? "[designation] " : "")][mmi.braintype]-[num2text(ident)]" real_name = changed_name name = real_name if(camera) @@ -401,28 +405,31 @@ var/obj/item/weapon/weldingtool/WT = W if (src == user) user << "You lack the reach to be able to repair yourself!" - return 1 + return if (src.health >= src.maxHealth) user << "[src] is already in good condition!" - return 1 - if (WT.remove_fuel(0, user)) + return + if (WT.remove_fuel(0, user)) //The welder has 1u of fuel consumed by it's afterattack, so we don't need to worry about taking any away. adjustBruteLoss(-30) updatehealth() add_fingerprint(user) visible_message("[user] has fixed some of the dents on [src].") - return 0 + return else user << "The welder must be on for this task!" - return 1 + return else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed) var/obj/item/stack/cable_coil/coil = W - if (coil.use(1)) - adjustFireLoss(-30) - updatehealth() - user.visible_message("[user] has fixed some of the burnt wires on [src].", "You fix some of the burnt wires on [src].") + if (fireloss > 0) + if (coil.use(1)) + adjustFireLoss(-30) + updatehealth() + user.visible_message("[user] has fixed some of the burnt wires on [src].", "You fix some of the burnt wires on [src].") + else + user << "You need more cable to repair [src]!" else - user << "You need one length of cable to repair [src]!" + user << "The wires seem fine, there's no need to fix them." else if (istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover if(opened) @@ -447,7 +454,6 @@ W.loc = src cell = W user << "You insert the power cell." -// chargecount = 0 update_icons() else if (istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/multitool) || istype(W, /obj/item/device/assembly/signaler)) @@ -720,7 +726,7 @@ /mob/living/silicon/robot/update_icons() overlays.Cut() - if(stat == 0) + if(stat == CONSCIOUS) switch(icon_state) if("robot") overlays += "eyes-standard" @@ -1039,4 +1045,4 @@ if(2) //New Module connected_ai << "

NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
" if(3) //New Name - connected_ai << "

NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
" \ No newline at end of file + connected_ai << "

NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
" diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 4af47db2a9f..f33e642029e 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -16,8 +16,7 @@ see_in_dark = 6 species = /mob/living/simple_animal/pet/cat childtype = /mob/living/simple_animal/pet/cat/kitten - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 3 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 29fbf497b7d..c4cddea7909 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -54,8 +54,7 @@ emote_see = list("shakes its head.", "shivers.") speak_chance = 1 turns_per_move = 10 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi - meat_amount = 3 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi = 3) response_help = "pets" response_disarm = "bops" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 752b939055a..96d5f3a193b 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -10,8 +10,7 @@ emote_see = list("clacks") speak_chance = 1 turns_per_move = 5 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 2 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "stomps" diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index cd4c33c7ee1..930dff33f2e 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -16,7 +16,7 @@ var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned /obj/item/drone_shell/attack_ghost(mob/user) - if(jobban_isbanned(user,"pAI")) + if(jobban_isbanned(user,"drone")) return var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No") diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 22a7e584ac6..9aa8c5a0177 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -12,8 +12,7 @@ speak_chance = 1 turns_per_move = 5 see_in_dark = 6 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 4 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 4) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" @@ -98,8 +97,7 @@ speak_chance = 1 turns_per_move = 5 see_in_dark = 6 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 6 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 6) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" @@ -161,8 +159,7 @@ density = 0 speak_chance = 2 turns_per_move = 2 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 1 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" @@ -204,10 +201,9 @@ var/global/chicken_count = 0 density = 0 speak_chance = 2 turns_per_move = 3 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) var/egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg var/food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat - meat_amount = 2 response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index b02ff8415f5..35d9568fbbf 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -13,7 +13,7 @@ speak_chance = 1 turns_per_move = 5 see_in_dark = 6 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 3) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index d2de3523fdd..2fd0214615e 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -13,8 +13,7 @@ see_in_dark = 6 maxHealth = 5 health = 5 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab - meat_amount = 1 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "splats" diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm index 1086486142d..f5bc620bd20 100644 --- a/code/modules/mob/living/simple_animal/friendly/pug.dm +++ b/code/modules/mob/living/simple_animal/friendly/pug.dm @@ -12,8 +12,7 @@ emote_see = list("shakes its head.", "chases its tail.","shivers.") speak_chance = 1 turns_per_move = 10 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/pug - meat_amount = 3 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/pug = 3) response_help = "pets" response_disarm = "bops" response_harm = "kicks" diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 49ac9d74de1..cfafe5093b8 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -10,9 +10,8 @@ response_disarm = "shoves" response_harm = "hits" speed = 0 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno - skin_type = /obj/item/stack/sheet/animalhide/xeno - meat_amount = 3 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 4, + /obj/item/stack/sheet/animalhide/xeno = 1) maxHealth = 100 health = 100 harm_intent_damage = 5 @@ -78,6 +77,8 @@ retreat_distance = 5 minimum_distance = 5 move_to_delay = 4 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 4, + /obj/item/stack/sheet/animalhide/xeno = 1) projectiletype = /obj/item/projectile/neurotox projectilesound = 'sound/weapons/pierce.ogg' status_flags = 0 @@ -124,6 +125,8 @@ move_to_delay = 4 maxHealth = 400 health = 400 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 10, + /obj/item/stack/sheet/animalhide/xeno = 2) mob_size = MOB_SIZE_LARGE /obj/item/projectile/neurotox diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 47e4f317b8d..eb1c60d6566 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -13,8 +13,7 @@ speak_chance = 1 turns_per_move = 5 see_in_dark = 6 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear - meat_amount = 3 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "hits" diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 243159ff767..2a90d81a77e 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -7,8 +7,7 @@ icon_gib = "carp_gib" speak_chance = 0 turns_per_move = 5 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat - meat_amount = 2 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/carpmeat = 2) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "hits" @@ -41,11 +40,9 @@ /mob/living/simple_animal/hostile/carp/AttackingTarget() ..() - if(isliving(target)) - var/mob/living/L = target - if(prob(15)) - L.Weaken(3) - L.visible_message("\the [src] knocks down \the [L]!") + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.adjustStaminaLoss(8) /mob/living/simple_animal/hostile/carp/holocarp icon_state = "holocarp" diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index 3ca8816a3b1..190bfdcb873 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -6,8 +6,6 @@ icon_state = "eyeball" icon_living = "eyeball" icon_gib = "" - meat_type = null - meat_amount = 0 response_help = "pets" response_disarm = "gently pushes aside" response_harm = "hits" diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 3eced450fed..066d484506d 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -32,8 +32,7 @@ speak_chance = 5 turns_per_move = 5 see_in_dark = 10 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider - meat_amount = 2 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "hits" @@ -55,8 +54,7 @@ icon_state = "nurse" icon_living = "nurse" icon_dead = "nurse_dead" - meat_type = /obj/item/weapon/reagent_containers/food/snacks/spidereggs - meat_amount = 4 + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/weapon/reagent_containers/food/snacks/spiderleg = 8, /obj/item/weapon/reagent_containers/food/snacks/spidereggs = 4) maxHealth = 40 health = 40 melee_damage_lower = 5 @@ -94,12 +92,6 @@ stop_automated_movement = 0 walk(src,0) -/mob/living/simple_animal/hostile/poison/giant_spider/harvest(mob/living/user) - var/leg_amount = rand(4,8) - for(var/i=0, i [src] is dead, medical items won't bring it back to life.
" return - if((meat_type || skin_type) && (stat == DEAD)) //if the animal has a meat, and if it is dead. + if((butcher_results) && (stat == DEAD)) user.changeNext_move(CLICK_CD_MELEE) var/sharpness = is_sharp(O) if(sharpness) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 70a8b157f64..2c0451396e9 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -69,7 +69,7 @@ stat("Game Mode:", (ticker.hide_mode) ? "Secret" : "[master_mode]") if(ticker.current_state == GAME_STATE_PREGAME) - stat("Time To Start:", (ticker.can_fire) ? "[round(ticker.timeLeft / 10)]s" : "DELAYED") + stat("Time To Start:", (ticker.timeLeft >= 0) ? "[round(ticker.timeLeft / 10)]s" : "DELAYED") stat("Players:", "[ticker.totalPlayers]") if(client.holder) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 3b8a4401cbd..6554869df2e 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -147,9 +147,9 @@ domutcheck(O) if(!dna.species) - O.dna.species = new /datum/species/human() + hardset_dna(O, null, null, null, null, /datum/species/human) else - O.dna.species = new dna.species.type() + hardset_dna(O, null, null, null, null, dna.species.type) dna = null if(newname) //if there's a name as an argument, always take that one over the current name diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index da4cfbc7225..6468170f288 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -216,17 +216,7 @@ return . -// rebuild all power networks from scratch - only called at world creation or by the admin verb -/datum/subsystem/power/proc/makepowernets() - for(var/datum/powernet/PN in powernets) - del(PN) - powernets.Cut() - for(var/obj/structure/cable/PC in cable_list) - if(!PC.powernet) - var/datum/powernet/NewPN = new() - NewPN.add_cable(PC) - propagate_network(PC,PC.powernet) //remove the old powernet and replace it with a new one throughout the network. /proc/propagate_network(var/obj/O, var/datum/powernet/PN) @@ -350,87 +340,6 @@ cell.use(drained_energy) return drained_energy -//////////////////////////////////////////// -// POWERNET DATUM PROCS -// each contiguous network of cables & nodes -//////////////////////////////////////////// - -/datum/powernet/New() - SSpower.powernets += src - -/datum/powernet/Destroy() - SSpower.powernets -= src - -/datum/powernet/proc/is_empty() - return !cables.len && !nodes.len - -//remove a cable from the current powernet -//if the powernet is then empty, delete it -//Warning : this proc DON'T check if the cable exists -/datum/powernet/proc/remove_cable(var/obj/structure/cable/C) - cables -= C - C.powernet = null - if(is_empty())//the powernet is now empty... - qdel(src)///... delete it - -//add a cable to the current powernet -//Warning : this proc DON'T check if the cable exists -/datum/powernet/proc/add_cable(var/obj/structure/cable/C) - if(C.powernet)// if C already has a powernet... - if(C.powernet == src) - return - else - C.powernet.remove_cable(C) //..remove it - C.powernet = src - cables +=C - -//remove a power machine from the current powernet -//if the powernet is then empty, delete it -//Warning : this proc DON'T check if the machine exists -/datum/powernet/proc/remove_machine(var/obj/machinery/power/M) - nodes -=M - M.powernet = null - if(is_empty())//the powernet is now empty... - qdel(src)///... delete it - - -//add a power machine to the current powernet -//Warning : this proc DON'T check if the machine exists -/datum/powernet/proc/add_machine(var/obj/machinery/power/M) - if(M.powernet)// if M already has a powernet... - if(M.powernet == src) - return - else - M.disconnect_from_network()//..remove it - M.powernet = src - nodes[M] = M - -//handles the power changes in the powernet -//called every ticks by the powernet controller -/datum/powernet/proc/reset() - - //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES - netexcess = avail - load - - if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle - for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network - S.restore() // and restore some of the power that was used - - //updates the viewed load (as seen on power computers) - viewload = 0.8*viewload + 0.2*load - viewload = round(viewload) - - //reset the powernet - load = 0 - avail = newavail - newavail = 0 - -/datum/powernet/proc/get_electrocute_damage() - if(avail >= 1000) - return Clamp(round(avail/10000), 10, 90) + rand(-5,5) - else - return 0 - //////////////////////////////////////////////// // Misc. /////////////////////////////////////////////// diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm new file mode 100644 index 00000000000..ac2b5ea3985 --- /dev/null +++ b/code/modules/power/powernet.dm @@ -0,0 +1,90 @@ +//////////////////////////////////////////// +// POWERNET DATUM +// each contiguous network of cables & nodes +///////////////////////////////////// +/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)/////// + +/datum/powernet/New() + SSpower.powernets += src + +/datum/powernet/Destroy() + SSpower.powernets -= src + +/datum/powernet/proc/is_empty() + return !cables.len && !nodes.len + +//remove a cable from the current powernet +//if the powernet is then empty, delete it +//Warning : this proc DON'T check if the cable exists +/datum/powernet/proc/remove_cable(var/obj/structure/cable/C) + cables -= C + C.powernet = null + if(is_empty())//the powernet is now empty... + qdel(src)///... delete it + +//add a cable to the current powernet +//Warning : this proc DON'T check if the cable exists +/datum/powernet/proc/add_cable(var/obj/structure/cable/C) + if(C.powernet)// if C already has a powernet... + if(C.powernet == src) + return + else + C.powernet.remove_cable(C) //..remove it + C.powernet = src + cables +=C + +//remove a power machine from the current powernet +//if the powernet is then empty, delete it +//Warning : this proc DON'T check if the machine exists +/datum/powernet/proc/remove_machine(var/obj/machinery/power/M) + nodes -=M + M.powernet = null + if(is_empty())//the powernet is now empty... + qdel(src)///... delete it + + +//add a power machine to the current powernet +//Warning : this proc DON'T check if the machine exists +/datum/powernet/proc/add_machine(var/obj/machinery/power/M) + if(M.powernet)// if M already has a powernet... + if(M.powernet == src) + return + else + M.disconnect_from_network()//..remove it + M.powernet = src + nodes[M] = M + +//handles the power changes in the powernet +//called every ticks by the powernet controller +/datum/powernet/proc/reset() + + //see if there's a surplus of power remaining in the powernet and stores unused power in the SMES + netexcess = avail - load + + if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle + for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network + S.restore() // and restore some of the power that was used + + //updates the viewed load (as seen on power computers) + viewload = 0.8*viewload + 0.2*load + viewload = round(viewload) + + //reset the powernet + load = 0 + avail = newavail + newavail = 0 + +/datum/powernet/proc/get_electrocute_damage() + if(avail >= 1000) + return Clamp(round(avail/10000), 10, 90) + rand(-5,5) + else + return 0 \ No newline at end of file diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm index 7e4071a78a9..9ae8b1e8c6f 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -14,7 +14,7 @@ /obj/item/weapon/gun/grenadelauncher/examine(mob/user) ..() - user << "[grenades] / [max_grenades] grenades loaded." + user << "[grenades.len] / [max_grenades] grenades loaded." /obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 88bacc76790..4618586611b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -63,8 +63,7 @@ return //don't want the emitters to miss obj/item/projectile/beam/emitter/Destroy() - PlaceInPool(src) - return 1 //cancels the GCing + return QDEL_HINT_PUTINPOOL /obj/item/projectile/lasertag name = "laser tag beam" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 09cae327199..647210069ac 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -72,7 +72,7 @@ ..() var/turf/location = get_turf(src) if(location) - new /obj/effect/hotspot(location) + PoolOrNew(/obj/effect/hotspot, location) location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/incendiary/shell/dragonsbreath diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 1dd1129f74f..fc5a2c29298 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -230,7 +230,7 @@ proc/wabbajack(mob/living/M) ready_dna(H) if(H.dna && prob(50)) var/new_species = pick(typesof(/datum/species) - /datum/species) - H.dna.species = new new_species() + hardset_dna(H, null, null, null, null, new_species) H.update_icons() else return diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index e10d2af11ec..11a8bdf76de 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -317,13 +317,13 @@ datum/reagent/consumable/cornoil/reaction_turf(var/turf/simulated/T, var/volume) src = null if(volume >= 3) T.MakeSlippery() - var/hotspot = (locate(/obj/effect/hotspot) in T) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot) var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() ) lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0) lowertemp.react() T.assume_air(lowertemp) - qdel(hotspot) + hotspot.Kill() datum/reagent/consumable/enzyme name = "Universal Enzyme" diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index 43650c72067..c4919676d61 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -129,13 +129,13 @@ datum/reagent/water/reaction_turf(var/turf/simulated/T, var/volume) for(var/mob/living/simple_animal/slime/M in T) M.apply_water() - var/hotspot = (locate(/obj/effect/hotspot) in T) + var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot && !istype(T, /turf/space)) if(T.air) var/datum/gas_mixture/G = T.air G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),0) G.react() - qdel(hotspot) + hotspot.Kill() return /* @@ -270,12 +270,12 @@ datum/reagent/unstableslimetoxin/on_mob_life(var/mob/living/carbon/human/H as mo H.visible_message("[H] falls to the ground and screams as their skin bubbles and froths!") //'froths' sounds painful when used with SKIN. H.Weaken(3) sleep(30) - var/list/blacklisted_species = list(/datum/species/zombie, /datum/species/skeleton, /datum/species/human, /datum/species/golem, /datum/species/golem/adamantine, /datum/species/shadow) + var/list/blacklisted_species = list(/datum/species/zombie, /datum/species/skeleton, /datum/species/human, /datum/species/golem, /datum/species/golem/adamantine, /datum/species/shadow, /datum/species/shadow/ling, /datum/species) var/list/possible_morphs = typesof(/datum/species/) - blacklisted_species var/datum/species/mutation = pick(possible_morphs) if(prob(90) && mutation && H.dna.species != /datum/species/golem && H.dna.species != /datum/species/golem/adamantine) H << "The pain subsides. You feel... different." - H.dna.species = new mutation() + hardset_dna(H, null, null, null, null, mutation) H.regenerate_icons() if(mutation == /datum/species/slime) H.faction |= "slime" diff --git a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm index a5704d0b950..82327767644 100644 --- a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm @@ -59,7 +59,7 @@ datum/reagent/nitroglycerin else if(prob(volume)) F.burn_tile() if(istype(F, /turf/simulated/floor/)) - new /obj/effect/hotspot(F) + PoolOrNew(/obj/effect/hotspot, F) if(istype(T, /turf/simulated/wall/)) var/turf/simulated/wall/W = T if(prob(volume/10)) @@ -69,7 +69,7 @@ datum/reagent/nitroglycerin if(method == TOUCH && isliving(M)) M.adjust_fire_stacks(5) M.IgniteMob() - new /obj/effect/hotspot(M.loc) + PoolOrNew(/obj/effect/hotspot, M.loc) /datum/reagent/sorium name = "Sorium" diff --git a/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm b/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm index 737f9bb5e92..4a3983597f8 100644 --- a/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm +++ b/code/modules/reagents/Chemistry-Recipes/Pyrotechnics.dm @@ -109,7 +109,7 @@ /datum/chemical_reaction/clf3/on_reaction(var/datum/reagents/holder, var/created_volume) var/turf/T = get_turf(holder.my_atom) for(var/turf/turf in range(1,T)) - new /obj/effect/hotspot(turf) + PoolOrNew(/obj/effect/hotspot, turf) holder.chem_temp = 1000 // hot as shit /datum/chemical_reaction/sorium diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 0cbd54f514f..f9896199225 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -75,13 +75,6 @@ if(stat & BROKEN || !I || !user) return - if(isrobot(user)) - if(!istype(I, /obj/item/weapon/storage/bag/trash)) - return - else - if(I.flags & NODROP) - return - src.add_fingerprint(user) if(mode<=0) // It's off if(istype(I, /obj/item/weapon/screwdriver)) @@ -130,7 +123,7 @@ stuff_mob_in(G.affecting, user) return - if(!I) return + if(!I || I.flags & NODROP) return user.drop_item() I.loc = src diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 14f20655f4b..22bf227cd59 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -48,6 +48,19 @@ datum/design/mmi_radio build_path = /obj/item/device/mmi/radio_enabled category = list("Misc","Medical Designs") +datum/design/posibrain + name = "Positronic Brain" + desc = "The latest in Artificial Intelligences." + id = "mmi_posi" + req_tech = list("programming" = 5, "biotech" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 1700, "$glass" = 1350, "$gold" = 500) //Gold, because SWAG. + reliability = 74 + construction_time = 75 + build_path = /obj/item/device/mmi/posibrain + category = list("Misc", "Medical Designs") + + datum/design/synthetic_flash name = "Flash" desc = "When a problem arises, SCIENCE is the solution." diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 204b94477e7..62a2d254e78 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -19,98 +19,98 @@ var/dheight = 0 //position relative to covered area, parallel to dir //these objects are indestructable - Destroy() - return 1 +/obj/docking_port/Destroy() + return QDEL_HINT_LETMELIVE - //returns a list(x0,y0, x1,y1) where points 0 and 1 are bounding corners of the projected rectangle - proc/return_coords(_x, _y, _dir) - if(!_dir) - _dir = dir - if(!_x) - _x = x - if(!_y) - _y = y +//returns a list(x0,y0, x1,y1) where points 0 and 1 are bounding corners of the projected rectangle +/obj/docking_port/proc/return_coords(_x, _y, _dir) + if(!_dir) + _dir = dir + if(!_x) + _x = x + if(!_y) + _y = y - //byond's sin and cos functions are inaccurate. This is faster and perfectly accurate - var/cos = 1 - var/sin = 0 - switch(_dir) - if(WEST) - cos = 0 - sin = 1 - if(SOUTH) - cos = -1 - sin = 0 - if(EAST) - cos = 0 - sin = -1 + //byond's sin and cos functions are inaccurate. This is faster and perfectly accurate + var/cos = 1 + var/sin = 0 + switch(_dir) + if(WEST) + cos = 0 + sin = 1 + if(SOUTH) + cos = -1 + sin = 0 + if(EAST) + cos = 0 + sin = -1 - return list( - _x + (-dwidth*cos) - (-dheight*sin), - _y + (-dwidth*sin) + (-dheight*cos), - _x + (-dwidth+width-1)*cos - (-dheight+height-1)*sin, - _y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos - ) + return list( + _x + (-dwidth*cos) - (-dheight*sin), + _y + (-dwidth*sin) + (-dheight*cos), + _x + (-dwidth+width-1)*cos - (-dheight+height-1)*sin, + _y + (-dwidth+width-1)*sin + (-dheight+height-1)*cos + ) - //returns turfs within our projected rectangle in a specific order. - //this ensures that turfs are copied over in the same order, regardless of any rotation - proc/return_ordered_turfs(_x, _y, _z, _dir) - if(!_dir) - _dir = dir - if(!_x) - _x = x - if(!_y) - _y = y - if(!_z) - _z = z - var/cos = 1 - var/sin = 0 - switch(_dir) - if(WEST) - cos = 0 - sin = 1 - if(SOUTH) - cos = -1 - sin = 0 - if(EAST) - cos = 0 - sin = -1 +//returns turfs within our projected rectangle in a specific order. +//this ensures that turfs are copied over in the same order, regardless of any rotation +/obj/docking_port/proc/return_ordered_turfs(_x, _y, _z, _dir) + if(!_dir) + _dir = dir + if(!_x) + _x = x + if(!_y) + _y = y + if(!_z) + _z = z + var/cos = 1 + var/sin = 0 + switch(_dir) + if(WEST) + cos = 0 + sin = 1 + if(SOUTH) + cos = -1 + sin = 0 + if(EAST) + cos = 0 + sin = -1 - . = list() + . = list() - var/xi - var/yi - for(var/dx=0, dx S.dwidth) - return 2 - if(width-dwidth > S.width-S.dwidth) - return 3 - if(dheight > S.dheight) - return 4 - if(height-dheight > S.height-S.dheight) - return 5 - //check the dock isn't occupied - if(S.get_docked()) - return 6 - return 0 //0 means we can dock +//this is to check if this shuttle can physically dock at dock S +/obj/docking_port/mobile/proc/canDock(obj/docking_port/stationary/S) + if(!istype(S)) + return 1 + if(istype(S, /obj/docking_port/stationary/transit)) + return 0 + //check dock is big enough to contain us + if(dwidth > S.dwidth) + return 2 + if(width-dwidth > S.width-S.dwidth) + return 3 + if(dheight > S.dheight) + return 4 + if(height-dheight > S.height-S.dheight) + return 5 + //check the dock isn't occupied + if(S.get_docked()) + return 6 + return 0 //0 means we can dock - //call the shuttle to destination S - proc/request(obj/docking_port/stationary/S) - if(canDock(S)) - ERROR("[type](\"[name]\") cannot dock at [S]\")") - return 1 //we can't dock at S +//call the shuttle to destination S +/obj/docking_port/mobile/proc/request(obj/docking_port/stationary/S) + if(canDock(S)) + ERROR("[type](\"[name]\") cannot dock at [S]\")") + return 1 //we can't dock at S - switch(mode) - if(SHUTTLE_CALL) - if(S == destination) - if(world.time <= timer) - timer = world.time - else - destination = S + switch(mode) + if(SHUTTLE_CALL) + if(S == destination) + if(world.time <= timer) timer = world.time - if(SHUTTLE_RECALL) - if(S == destination) - timer = world.time - timeLeft(1) - else - destination = S - timer = world.time - mode = SHUTTLE_CALL else destination = S - mode = SHUTTLE_CALL timer = world.time - enterTransit() //hyperspace + if(SHUTTLE_RECALL) + if(S == destination) + timer = world.time - timeLeft(1) + else + destination = S + timer = world.time + mode = SHUTTLE_CALL + else + destination = S + mode = SHUTTLE_CALL + timer = world.time + enterTransit() //hyperspace - //recall the shuttle to where it was previously - proc/cancel() - if(mode != SHUTTLE_CALL) - return +//recall the shuttle to where it was previously +/obj/docking_port/mobile/proc/cancel() + if(mode != SHUTTLE_CALL) + return - timer = world.time - timeLeft(1) - mode = SHUTTLE_RECALL + timer = world.time - timeLeft(1) + mode = SHUTTLE_RECALL - proc/enterTransit() - previous = null +/obj/docking_port/mobile/proc/enterTransit() + previous = null // if(!destination) // return - var/obj/docking_port/stationary/S0 = get_docked() - var/obj/docking_port/stationary/S1 = findTransitDock() - if(S1) - if(dock(S1)) - WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].") - else - previous = S0 + var/obj/docking_port/stationary/S0 = get_docked() + var/obj/docking_port/stationary/S1 = findTransitDock() + if(S1) + if(dock(S1)) + WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].") else - WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]") + previous = S0 + else + WARNING("shuttle \"[id]\" could not enter transit space. S0=[S0 ? S0.id : "null"] S1=[S1 ? S1.id : "null"]") - //this is the main proc. It instantly moves our mobile port to stationary port S1 - //it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc - proc/dock(obj/docking_port/stationary/S1) - . = canDock(S1) - if(.) - ERROR("[type](\"[name]\") cannot dock at [S1]") - return . +//this is the main proc. It instantly moves our mobile port to stationary port S1 +//it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc +/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1) + . = canDock(S1) + if(.) + ERROR("[type](\"[name]\") cannot dock at [S1]") + return . - if(canMove()) - return -1 + if(canMove()) + return -1 - closePortDoors() + closePortDoors() // //rotate transit docking ports, so we don't need zillions of variants // if(istype(S1, /obj/docking_port/stationary/transit)) // S1.dir = turn(NORTH, -travelDir) - var/obj/docking_port/stationary/S0 = get_docked() - var/turf_type = /turf/space - var/area_type = /area/space - if(S0) - if(S0.turf_type) - turf_type = S0.turf_type - if(S0.area_type) - area_type = S0.area_type + var/obj/docking_port/stationary/S0 = get_docked() + var/turf_type = /turf/space + var/area_type = /area/space + if(S0) + if(S0.turf_type) + turf_type = S0.turf_type + if(S0.area_type) + area_type = S0.area_type - var/list/L0 = return_ordered_turfs() - var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir) - - //remove area surrounding docking port - if(areaInstance.contents.len) - var/area/A0 = locate("[area_type]") - if(!A0) - A0 = new area_type(null) - for(var/turf/T0 in L0) - A0.contents += T0 - - //move or squish anything in the way ship at destination - roadkill(L1, S1.dir) - - for(var/i=1, i<=L0.len, ++i) - var/turf/T0 = L0[i] - if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs! - continue - - var/turf/T1 = L1[i] - if(!T1) - continue - - T0.copyTurf(T1) - areaInstance.contents += T1 - - //copy over air - if(istype(T1, /turf/simulated)) - var/turf/simulated/Ts1 = T1 - Ts1.copy_air_with_tile(T0) - - //move mobile to new location - loc = S1.loc - dir = S1.dir - - //move all objects - for(var/obj/O in T0) - if(O.invisibility >= 101) - continue - if(O == T0.lighting_object) - continue - O.loc = T1 - - //close open doors - if(istype(O, /obj/machinery/door)) - var/obj/machinery/door/Door = O - spawn(-1) - if(Door) - Door.close() - - for(var/mob/M in T0) - if(!M.move_on_shuttle) - continue - M.loc = T1 - - //docking turbulence - if(M.client) - spawn(0) - if(M.buckled) - shake_camera(M, 2, 1) // turn it down a bit come on - else - shake_camera(M, 7, 1) - if(istype(M, /mob/living/carbon)) - if(!M.buckled) - M.Weaken(3) - - T0.ChangeTurf(turf_type) - - //air system updates - for(var/turf/T1 in L1) - T1.redraw_lighting() - SSair.remove_from_active(T1) - T1.CalculateAdjacentTurfs() - SSair.add_to_active(T1,1) + var/list/L0 = return_ordered_turfs() + var/list/L1 = return_ordered_turfs(S1.x, S1.y, S1.z, S1.dir) + //remove area surrounding docking port + if(areaInstance.contents.len) + var/area/A0 = locate("[area_type]") + if(!A0) + A0 = new area_type(null) for(var/turf/T0 in L0) - T0.redraw_lighting() - SSair.remove_from_active(T0) - T0.CalculateAdjacentTurfs() - SSair.add_to_active(T0,1) + A0.contents += T0 -/* - if(istype(S1, /obj/docking_port/stationary/transit)) - var/d = turn(dir, 180 + travelDir) - for(var/turf/space/transit/T in S1.return_ordered_turfs()) - T.pushdirection = d - T.update_icon() -*/ + //move or squish anything in the way ship at destination + roadkill(L1, S1.dir) - proc/findTransitDock() - var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit") - if(T && !canDock(T)) - return T - /* commented out due to issues with rotation - for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit) - if(S.id) + for(var/i=1, i<=L0.len, ++i) + var/turf/T0 = L0[i] + if(!istype(T0, /turf/simulated/shuttle)) //only move shuttle turfs! + continue + + var/turf/T1 = L1[i] + if(!T1) + continue + + T0.copyTurf(T1) + areaInstance.contents += T1 + + //copy over air + if(istype(T1, /turf/simulated)) + var/turf/simulated/Ts1 = T1 + Ts1.copy_air_with_tile(T0) + + //move mobile to new location + loc = S1.loc + dir = S1.dir + + //move all objects + for(var/obj/O in T0) + if(O.invisibility >= 101) continue - if(!canDock(S)) - return S - */ + if(O == T0.lighting_object) + continue + O.loc = T1 - - //shuttle-door closing is handled in the dock() proc whilst looping through turfs - //this one closes the door where we are docked at, if there is one there. - proc/closePortDoors() - var/turf/T = get_step(loc, turn(dir,180)) - if(T) - var/obj/machinery/door/Door = locate() in T - if(Door) + //close open doors + if(istype(O, /obj/machinery/door)) + var/obj/machinery/door/Door = O spawn(-1) - Door.close() + if(Door) + Door.close() - proc/roadkill(list/L, dir, x, y) - for(var/turf/T in L) - for(var/atom/movable/AM in T) - if(ismob(AM)) - if(istype(AM, /mob/living)) - var/mob/living/M = AM - M.Paralyse(10) - M.take_organ_damage(80) - M.anchored = 0 + for(var/mob/M in T0) + if(!M.move_on_shuttle) + continue + M.loc = T1 + + //docking turbulence + if(M.client) + spawn(0) + if(M.buckled) + shake_camera(M, 2, 1) // turn it down a bit come on else - continue + shake_camera(M, 7, 1) + if(istype(M, /mob/living/carbon)) + if(!M.buckled) + M.Weaken(3) + + T0.ChangeTurf(turf_type) + + //air system updates + for(var/turf/T1 in L1) + T1.redraw_lighting() + SSair.remove_from_active(T1) + T1.CalculateAdjacentTurfs() + SSair.add_to_active(T1,1) + + for(var/turf/T0 in L0) + T0.redraw_lighting() + SSair.remove_from_active(T0) + T0.CalculateAdjacentTurfs() + SSair.add_to_active(T0,1) - if(!AM.anchored) - step(AM, dir) - else - qdel(AM) /* - //used to check if atom/A is within the shuttle's bounding box - proc/onShuttleCheck(atom/A) - var/turf/T = get_turf(A) - if(!T) - return 0 - - var/list/L = return_coords() - if(L[1] > L[3]) - L.Swap(1,3) - if(L[2] > L[4]) - L.Swap(2,4) - - if(L[1] <= T.x && T.x <= L[3]) - if(L[2] <= T.y && T.y <= L[4]) - return 1 - return 0 + if(istype(S1, /obj/docking_port/stationary/transit)) + var/d = turn(dir, 180 + travelDir) + for(var/turf/space/transit/T in S1.return_ordered_turfs()) + T.pushdirection = d + T.update_icon() +*/ + +/obj/docking_port/mobile/proc/findTransitDock() + var/obj/docking_port/stationary/transit/T = SSshuttle.getDock("[id]_transit") + if(T && !canDock(T)) + return T +/* commented out due to issues with rotation + for(var/obj/docking_port/stationary/transit/S in SSshuttle.transit) + if(S.id) + continue + if(!canDock(S)) + return S */ - //used by shuttle subsystem to check timers - proc/check() - var/timeLeft = timeLeft(1) - if(timeLeft <= 0) - switch(mode) - if(SHUTTLE_CALL) - if(dock(destination)) - setTimer(20) //can't dock for some reason, try again in 2 seconds - return - if(SHUTTLE_RECALL) - if(dock(previous)) - setTimer(20) //can't dock for some reason, try again in 2 seconds - return - mode = SHUTTLE_IDLE - timer = 0 - destination = null - proc/setTimer(wait) - if(timer <= 0) - timer = world.time - timer += wait - timeLeft(1) +//shuttle-door closing is handled in the dock() proc whilst looping through turfs +//this one closes the door where we are docked at, if there is one there. +/obj/docking_port/mobile/proc/closePortDoors() + var/turf/T = get_step(loc, turn(dir,180)) + if(T) + var/obj/machinery/door/Door = locate() in T + if(Door) + spawn(-1) + Door.close() - //returns timeLeft - proc/timeLeft(divisor) - if(divisor <= 0) - divisor = 10 - if(!timer) - return round(callTime/divisor, 1) - return max( round((timer+callTime-world.time)/divisor,1), 0 ) +/obj/docking_port/mobile/proc/roadkill(list/L, dir, x, y) + for(var/turf/T in L) + for(var/atom/movable/AM in T) + if(ismob(AM)) + if(istype(AM, /mob/living)) + var/mob/living/M = AM + M.Paralyse(10) + M.take_organ_damage(80) + M.anchored = 0 + else + continue - proc/getStatusText() - var/obj/docking_port/stationary/dockedAt = get_docked() - . = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown" - if(istype(dockedAt, /obj/docking_port/stationary/transit)) - var/obj/docking_port/stationary/dst - if(mode == SHUTTLE_RECALL) - dst = previous + if(!AM.anchored) + step(AM, dir) else - dst = destination - . += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)" + qdel(AM) +/* +//used to check if atom/A is within the shuttle's bounding box +/obj/docking_port/mobile/proc/onShuttleCheck(atom/A) + var/turf/T = get_turf(A) + if(!T) + return 0 + + var/list/L = return_coords() + if(L[1] > L[3]) + L.Swap(1,3) + if(L[2] > L[4]) + L.Swap(2,4) + + if(L[1] <= T.x && T.x <= L[3]) + if(L[2] <= T.y && T.y <= L[4]) + return 1 + return 0 +*/ +//used by shuttle subsystem to check timers +/obj/docking_port/mobile/proc/check() + var/timeLeft = timeLeft(1) + if(timeLeft <= 0) + switch(mode) + if(SHUTTLE_CALL) + if(dock(destination)) + setTimer(20) //can't dock for some reason, try again in 2 seconds + return + if(SHUTTLE_RECALL) + if(dock(previous)) + setTimer(20) //can't dock for some reason, try again in 2 seconds + return + mode = SHUTTLE_IDLE + timer = 0 + destination = null + + +/obj/docking_port/mobile/proc/setTimer(wait) + if(timer <= 0) + timer = world.time + timer += wait - timeLeft(1) + +//returns timeLeft +/obj/docking_port/mobile/proc/timeLeft(divisor) + if(divisor <= 0) + divisor = 10 + if(!timer) + return round(callTime/divisor, 1) + return max( round((timer+callTime-world.time)/divisor,1), 0 ) + +/obj/docking_port/mobile/proc/getStatusText() + var/obj/docking_port/stationary/dockedAt = get_docked() + . = (dockedAt && dockedAt.name) ? dockedAt.name : "unknown" + if(istype(dockedAt, /obj/docking_port/stationary/transit)) + var/obj/docking_port/stationary/dst + if(mode == SHUTTLE_RECALL) + dst = previous + else + dst = destination + . += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)" /obj/machinery/computer/shuttle name = "Shuttle Console" @@ -478,6 +478,7 @@ circuit = /obj/item/weapon/circuitboard/shuttle var/shuttleId var/possible_destinations = "" + var/admin_controlled /obj/machinery/computer/shuttle/New(location, obj/item/weapon/circuitboard/shuttle/C) ..() @@ -494,12 +495,19 @@ var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]

" if(M) + var/destination_found for(var/obj/docking_port/stationary/S in SSshuttle.stationary) if(!options.Find(S.id)) continue if(M.canDock(S)) continue + destination_found = 1 dat += "Send to [S.name]
" + if(!destination_found) + dat += "Shuttle Locked
" + if(admin_controlled) + dat += "Authorized personnel only
" + dat += "Request Authorization
" dat += "Close" var/datum/browser/popup = new(user, "computer", M ? M.name : "shuttle", 300, 200) @@ -540,7 +548,18 @@ circuit = /obj/item/weapon/circuitboard/ferry/request var/cooldown //prevents spamming admins possible_destinations = "ferry_home" + admin_controlled = 1 +/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list) + ..() + if(href_list["request"]) + if(cooldown) + return + cooldown = 1 + usr << "Your request has been recieved by Centcom." + admins << "FERRY: [key_name(usr)] (?) (JMP) (Move Ferry) is requesting to move the transport ferry to Centcom." + spawn(600) //One minute cooldown + cooldown = 0 #undef DOCKING_PORT_HIGHLIGHT diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index f139e46f55d..042832894d7 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -25,7 +25,7 @@ if(success) if(target_zone == surgery.location) - if(get_location_accessible(target, target_zone)) + if(get_location_accessible(target, target_zone) || surgery.ignore_clothes) initiate(user, target, target_zone, tool, surgery) return 1 else @@ -88,25 +88,7 @@ /datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(locate(/datum/surgery_step/saw) in surgery.steps) - var/limb_type - switch(target_zone) - if("head") - limb_type = /obj/item/organ/limb/head - if("chest") - limb_type = /obj/item/organ/limb/chest - if("l_arm") - limb_type = /obj/item/organ/limb/l_arm - if("r_arm") - limb_type = /obj/item/organ/limb/r_arm - if("l_leg") - limb_type = /obj/item/organ/limb/l_leg - if("r_leg") - limb_type = /obj/item/organ/limb/r_leg - else - return - var/obj/item/organ/limb/limb = target.getlimb(limb_type) - if(limb) - limb.heal_damage(45,0,0) + target.heal_organ_damage(45,0) return ..() /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) diff --git a/html/changelog.html b/html/changelog.html index 8ba799e8ebd..efe183bfc12 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,67 @@ -->
+

03 May 2015

+

AnturK updated:

+
    +
  • Abductors can purchase spare gear with experimentation points.
  • +
+

Ikarrus updated:

+
    +
  • Admins can now adjust the pre-game delay time.
  • +
+

MrStonedOne updated:

+
    +
  • MasterController and subsystem rejiggering!
  • +
  • The MC can now dynamcially change the rate a subsystem is triggered based on how laggy it's being. This has been applied to atmos to allow for faster air processing without lagging the server
  • +
  • Pipes and atmos machinery now processes in tune with air, rather than seperately.
  • +
  • Fixed hotspots and fire causing more lag than they needed to
  • +
  • Fixed some objects not getting garbage collected because they didn't properly clear references in Destory()
  • +
  • The qdel subsystem will now limit its processing time to a 5th of a second each tick to prevent lag when a lot of deletes happen
  • +
  • Fixed the ticker not showing a tip of the round if an admin forces the round to start immediately
  • +
+ +

02 May 2015

+

Boggart updated:

+
    +
  • Cryo tubes can no longer be used for ventcrawling.
  • +
+

Ikarrus updated:

+
    +
  • Admins can choose the strength and size of Centcom teams to send, ranging from officials to deathsquads, with the 'Make Centcom Respone Team' button.
  • +
+

phil235 updated:

+
    +
  • Space carps can no longer knock down anyone, but they now deal additional stamina damage to humans.
  • +
  • Radiation effects from uranium walls are nerfed to the level of uranium floor.
  • +
  • You can no longer put an inactive MMI in a cyborg shell. Ghosted brains now get an alert when someone puts their brain in a MMI. You can now examine the MMI to see if its brain is active.
  • +
+ +

01 May 2015

+

Ikarrus updated:

+
    +
  • Gang bosses can now rally their gang to their location with their gangtool.
  • +
  • Gangtools can no longer recall the shuttle if station integrity is lower than 70%
  • +
  • Removed requirement to be in the territory to tag it.
  • +
  • Recruitment Pen cost reduced to 40.
  • +
  • Communications console should now accurately print the (lack of a) location of the last shuttle call.
  • +
+

Xhuis updated:

+
    +
  • Revenants will no longer spawn without admin intervention. They are pending a remake.
  • +
+ +

30 April 2015

+

Fayrik updated:

+
    +
  • Ported NanoUI to most atmospherics equipment.
  • +
+

TheVekter updated:

+
    +
  • Hooch is now made with 2 parts Ethanol, 1 part Welder fuel and 1 part Universal Enzyme as a catalyst.
  • +
  • No-slip shoes are paintable, painting them doesn't remove no-slip properties.
  • +
+

29 April 2015

AndroidSFV updated:

    @@ -85,7 +146,6 @@

    Ikarrus updated:

    • Spraycans and crayons can now draw Poseur Tags, aka Fake Gang Tags, as grafiti.
    • -
    • Gangs Capture goal reduced to 60%
    • Influence income changed to provide weaker gangs a bigger boost, while slowing down stronger gangs to promote opportunity for comebacks.
    • Gangs only earn influence on territories they have held on to since the previous Status Report (the income calculation every 5 minutes). This places more significance on defending your existing territory.
    • You must be in the territory physically to tag it now. So no more tagging everything from maint.
    • @@ -116,7 +176,7 @@

      25 April 2015

      Boggart updated:

        -
      • Ports Nienhaus's guitar, generalizes handheld instrument code.
      • +
      • Generalizes handheld instrument code and Ports Nienhaus's guitar, sounds by BartNixon of Tau Ceti.
      • Fixes being unable to build disposal pipes on walls, makes changing the RPD's settings not affect pipes that are currently building, makes the RPD use the datum/browser ui, makes it use categories and makes it show the selected mode.

      Gun Hog updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 813ddd15b61..eeb910a68c4 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -2296,7 +2296,8 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: Buffed Ripley's movement and drilling speed in low pressure environments. 2015-04-25: Boggart: - - rscadd: Ports Nienhaus's guitar, generalizes handheld instrument code. + - rscadd: Generalizes handheld instrument code and Ports Nienhaus's guitar, sounds + by BartNixon of Tau Ceti. - rscadd: Fixes being unable to build disposal pipes on walls, makes changing the RPD's settings not affect pipes that are currently building, makes the RPD use the datum/browser ui, makes it use categories and makes it show the selected @@ -2354,7 +2355,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Ikarrus: - rscadd: Spraycans and crayons can now draw Poseur Tags, aka Fake Gang Tags, as grafiti. - - tweak: Gangs Capture goal reduced to 60% - tweak: Influence income changed to provide weaker gangs a bigger boost, while slowing down stronger gangs to promote opportunity for comebacks. - tweak: Gangs only earn influence on territories they have held on to since the @@ -2383,3 +2383,54 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: Choosing your clown, mime, cyborg and AI name as well as religion and deity is now done in the preferences window. As a chaplain , your bible's icon is now chosen by clicking the bible. +2015-04-30: + Fayrik: + - rscadd: Ported NanoUI to most atmospherics equipment. + TheVekter: + - tweak: Hooch is now made with 2 parts Ethanol, 1 part Welder fuel and 1 part Universal + Enzyme as a catalyst. + - tweak: No-slip shoes are paintable, painting them doesn't remove no-slip properties. +2015-05-01: + Ikarrus: + - rscadd: Gang bosses can now rally their gang to their location with their gangtool. + - rscadd: Gangtools can no longer recall the shuttle if station integrity is lower + than 70% + - rscdel: Removed requirement to be in the territory to tag it. + - tweak: Recruitment Pen cost reduced to 40. + - bugfix: Communications console should now accurately print the (lack of a) location + of the last shuttle call. + Xhuis: + - rscdel: Revenants will no longer spawn without admin intervention. They are pending + a remake. +2015-05-02: + Boggart: + - bugfix: Cryo tubes can no longer be used for ventcrawling. + Ikarrus: + - rscadd: Admins can choose the strength and size of Centcom teams to send, ranging + from officials to deathsquads, with the 'Make Centcom Respone Team' button. + phil235: + - tweak: Space carps can no longer knock down anyone, but they now deal additional + stamina damage to humans. + - tweak: Radiation effects from uranium walls are nerfed to the level of uranium + floor. + - rscadd: You can no longer put an inactive MMI in a cyborg shell. Ghosted brains + now get an alert when someone puts their brain in a MMI. You can now examine + the MMI to see if its brain is active. +2015-05-03: + AnturK: + - rscadd: Abductors can purchase spare gear with experimentation points. + Ikarrus: + - rscadd: Admins can now adjust the pre-game delay time. + MrStonedOne: + - experiment: MasterController and subsystem rejiggering! + - rscadd: The MC can now dynamcially change the rate a subsystem is triggered based + on how laggy it's being. This has been applied to atmos to allow for faster + air processing without lagging the server + - tweak: Pipes and atmos machinery now processes in tune with air, rather than seperately. + - bugfix: Fixed hotspots and fire causing more lag than they needed to + - bugfix: Fixed some objects not getting garbage collected because they didn't properly + clear references in Destory() + - tweak: The qdel subsystem will now limit its processing time to a 5th of a second + each tick to prevent lag when a lot of deletes happen + - bugfix: Fixed the ticker not showing a tip of the round if an admin forces the + round to start immediately diff --git a/html/changelogs/Fayrik-TheNanoing.yml b/html/changelogs/Fayrik-TheNanoing.yml deleted file mode 100644 index 556f54168d2..00000000000 --- a/html/changelogs/Fayrik-TheNanoing.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: Fayrik - -delete-after: True - -changes: -- rscadd: "Ported NanoUI to most atmospherics equipment." \ No newline at end of file diff --git a/html/changelogs/Gun-Hog-PR-9147-Blood-Tithe-to-Jordie.yml b/html/changelogs/Gun-Hog-PR-9147-Blood-Tithe-to-Jordie.yml new file mode 100644 index 00000000000..78035d54353 --- /dev/null +++ b/html/changelogs/Gun-Hog-PR-9147-Blood-Tithe-to-Jordie.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: Gun Hog + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Top scientists at Nanotrasen have made strong progress in Artificial Intelligence technology, and have completed a design for replicating a human mind: Positronic Brains. Prototypes produced on your research station should be compatible with all Man-Machine Interface compliant machines, be it Mechs, AIs, and even Cyborg bodies. Please note that Cyborgs created from artificial brains are called Androids." + - tweak: "The pAI role preference and related jobbans have been renamed to properly reflect that they are not soley for pAI, but include drones and positroinc prains." diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index 8325e86e0f1..b2bbe321a2f 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index ccdac8d866d..682103c7dcb 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 15ec64bf77e..1d42d7752c2 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 33764a17413..58aeede23dd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -28,6 +28,7 @@ #include "code\__DEFINES\math.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\preferences.dm" +#include "code\__DEFINES\qdel.dm" #include "code\__DEFINES\say.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\stat.dm" @@ -90,7 +91,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\ATMOSPHERICS\atmospherics.dm" -#include "code\ATMOSPHERICS\datum_pipe_network.dm" #include "code\ATMOSPHERICS\datum_pipeline.dm" #include "code\ATMOSPHERICS\he_pipes.dm" #include "code\ATMOSPHERICS\pipes.dm" @@ -118,7 +118,6 @@ #include "code\ATMOSPHERICS\pipes\manifold4w.dm" #include "code\ATMOSPHERICS\pipes\simple.dm" #include "code\ATMOSPHERICS\pipes\tank.dm" -#include "code\ATMOSPHERICS\pipes\vent.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\master_controller.dm" @@ -137,7 +136,6 @@ #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\objects.dm" #include "code\controllers\subsystem\pai.dm" -#include "code\controllers\subsystem\pipenets.dm" #include "code\controllers\subsystem\power.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\server_maintenance.dm" @@ -152,11 +150,11 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datumvars.dm" +#include "code\datums\debug.dm" #include "code\datums\gas_mixture.dm" #include "code\datums\hud.dm" #include "code\datums\martial.dm" #include "code\datums\mind.dm" -#include "code\datums\mixed.dm" #include "code\datums\modules.dm" #include "code\datums\mutations.dm" #include "code\datums\recipe.dm" @@ -1127,6 +1125,7 @@ #include "code\modules\mob\living\carbon\brain\emote.dm" #include "code\modules\mob\living\carbon\brain\life.dm" #include "code\modules\mob\living\carbon\brain\MMI.dm" +#include "code\modules\mob\living\carbon\brain\posibrain.dm" #include "code\modules\mob\living\carbon\brain\say.dm" #include "code\modules\mob\living\carbon\human\blood.dm" #include "code\modules\mob\living\carbon\human\death.dm" @@ -1306,6 +1305,7 @@ #include "code\modules\power\lighting.dm" #include "code\modules\power\port_gen.dm" #include "code\modules\power\power.dm" +#include "code\modules\power\powernet.dm" #include "code\modules\power\smes.dm" #include "code\modules\power\solar.dm" #include "code\modules\power\switch.dm"