diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index f9c4fe4ae39..fb033e74eaa 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -458,7 +458,7 @@
"aiP" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/permabrig)
"aiQ" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/permabrig)
"aiR" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/security/permabrig)
-"aiS" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/permabrig)
+"aiS" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/permabrig)
"aiT" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0; tag = "icon-alarm0 (EAST)"},/obj/machinery/camera{c_tag = "Brig Armory"; dir = 4; network = list("SS13")},/obj/machinery/flasher/portable,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/armoury)
"aiU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/flasher/portable,/obj/effect/decal/warning_stripes/red/hollow,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/armoury)
"aiV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor,/area/security/armoury)
@@ -955,7 +955,7 @@
"ass" = (/obj/machinery/computer/security{network = list("SS13","Research Outpost","Mining Outpost")},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig)
"ast" = (/obj/machinery/door_control{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -35; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 1-4."; id = "BrigEast"; name = "Brig Cells 1-4 Hallway Doors"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -25; range = 10},/obj/machinery/door_control{desc = "A remote control switch for the brig doors leading to cells 5 and 6."; id = "BrigWest"; name = "Brig Cells 5-6 Hallway Doors"; normaldoorcontrol = 1; pixel_x = -5; pixel_y = -25; range = 20},/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/item/device/radio/intercom/department/security{pixel_x = 28},/turf/simulated/floor{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/brig)
"asu" = (/obj/structure/sign/poster/legit{pixel_x = 32},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/lobby)
-"asv" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C)
+"asv" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/lobby)
"asw" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C)
"asx" = (/obj/machinery/door/window/brigdoor{dir = 2; name = "Secure Door"; req_access_txt = "2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor,/area/security/prison/cell_block/C)
"asy" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison/cell_block/C)
@@ -1162,10 +1162,9 @@
"awr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A)
"aws" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A)
"awt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A)
-"awu" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/turf/simulated/floor/plating,/area/security/lobby)
+"awu" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/lobby)
"awv" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/security/lobby)
"aww" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Lobby"; req_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor,/area/security/lobby)
-"awx" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/lobby)
"awy" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/lobby)
"awz" = (/turf/simulated/wall/r_wall,/area/security/prison/cell_block/C)
"awA" = (/obj/structure/closet{name = "Evidence Closet"},/obj/machinery/light_switch{pixel_x = -25},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/detectives_office)
@@ -4271,7 +4270,7 @@
"bEg" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/engine/gravitygenerator)
"bEh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor{icon_state = "dark"},/area/engine/gravitygenerator)
"bEi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/engine/gravitygenerator)
-"bEj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/engine/gravitygenerator)
+"bEj" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/engine/gravitygenerator)
"bEk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/space,/area/space)
"bEl" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/captain,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/captain/bedroom)
"bEm" = (/turf/simulated/floor/carpet,/area/crew_quarters/captain/bedroom)
@@ -7313,7 +7312,7 @@
"cKG" = (/obj/structure/table,/obj/item/clothing/head/welding{pixel_x = 1; pixel_x = -5; pixel_y = 3},/obj/item/stack/sheet/glass{amount = 50},/obj/item/clothing/head/welding{pixel_x = 0; pixel_x = -5; pixel_y = 3},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor,/area/atmos)
"cKH" = (/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/weapon/wrench,/obj/item/device/pipe_painter,/obj/item/device/pipe_painter,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor,/area/atmos)
"cKI" = (/obj/structure/table,/obj/item/device/t_scanner,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/radio/headset/headset_eng,/obj/item/weapon/cartridge/atmos,/obj/item/weapon/cartridge/atmos,/obj/item/device/t_scanner,/turf/simulated/floor,/area/atmos)
-"cKJ" = (/obj/machinery/atmospherics/trinary/tvalve{dir = 1},/turf/simulated/floor,/area/atmos)
+"cKJ" = (/obj/machinery/atmospherics/trinary/tvalve/digital/flipped,/turf/simulated/floor,/area/atmos)
"cKK" = (/obj/machinery/atmospherics/binary/pump{dir = 4; name = "Waste to Port"},/turf/simulated/floor,/area/atmos)
"cKL" = (/obj/machinery/atmospherics/pipe/manifold4w/visible,/turf/simulated/floor,/area/atmos)
"cKM" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/visible,/turf/simulated/floor,/area/atmos)
@@ -7712,14 +7711,14 @@
"cSp" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/closet/firecloset,/turf/simulated/floor,/area/atmos)
"cSq" = (/turf/simulated/floor{icon_state = "red"; dir = 10},/area/atmos)
"cSr" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; output_tag = "n2_out"; sensors = list("n2_sensor" = "Tank")},/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/turf/simulated/floor{icon_state = "red"},/area/atmos)
-"cSs" = (/obj/machinery/atmospherics/binary/valve/digital{name = "Nitrogen Outlet Valve"},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/atmos)
+"cSs" = (/obj/machinery/atmospherics/binary/valve/digital/open{name = "Nitrogen Outlet Valve"},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/atmos)
"cSt" = (/obj/machinery/light,/obj/machinery/atmospherics/binary/volume_pump/on{name = "Space Loop In"},/turf/simulated/floor,/area/atmos)
"cSu" = (/obj/machinery/atmospherics/pipe/simple/visible/green{level = 2},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/atmos)
"cSv" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; output_tag = "o2_out"; sensors = list("o2_sensor" = "Tank")},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/atmos)
-"cSw" = (/obj/machinery/atmospherics/binary/valve/digital{name = "Oxygen Outlet Valve"},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/atmos)
+"cSw" = (/obj/machinery/atmospherics/binary/valve/digital/open{name = "Oxygen Outlet Valve"},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/atmos)
"cSx" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/turf/simulated/floor{icon_state = "arrival"; dir = 10},/area/atmos)
"cSy" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; output_tag = "air_out"; pressure_setting = 2000; sensors = list("air_sensor" = "Tank")},/turf/simulated/floor{icon_state = "arrival"},/area/atmos)
-"cSz" = (/obj/machinery/camera{c_tag = "Atmospherics South-East"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/binary/valve/digital{name = "Mixed Air Outlet Valve"},/turf/simulated/floor{icon_state = "arrival"; dir = 6},/area/atmos)
+"cSz" = (/obj/machinery/camera{c_tag = "Atmospherics South-East"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/binary/valve/digital/open{name = "Mixed Air Outlet Valve"},/turf/simulated/floor{icon_state = "arrival"; dir = 6},/area/atmos)
"cSA" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/atmos)
"cSB" = (/turf/simulated/floor/plating/airless,/obj/structure/cable,/obj/machinery/power/tracker,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk1"; icon_state = "catwalk1"},/area/solar/starboard)
"cSC" = (/obj/machinery/floodlight,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/storage/secure)
@@ -8099,12 +8098,12 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaajjaaaalSalTalTalTalTalUalValWalXalXalXalXalYaaaacGaaaaaaaaaamNaptaptapuamNaaaaaaaaaapvapwapxapyapzapAapAapAapBapBapBapBapCapDapEapEapEapFapGapHapFapEapEapEapIapJapKapLapMapKapNapJapOapOapOapPapQapOapRapSapTapUapVapWapXapmapnapYapYamKapZapZapZamKaqaamKaabaloaabaaaajkajPajmaaaaaaajkajPajmaaaaaaajkajPajmaabaabaaaaabaiIaabaaaaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaqbamLamLamLamLamLaaaamMaaaamLamLamLamLamLaabacGaaaaaaaaaanwaqcaptaqdamNamRaqeaoEaqfaqgaqhaqiaqjaqkaqlaqmapBaqnaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaqAaqsaqBaqCaqDaqEaqFaqGaqHaqCapOaqIaqJaqKaqLapOaqMaqNaqOaqPaqQaqRapXapmaqSaqTaqUaqVaqWaqWaqXamKaqYamKaabaloaabaaaajkajPajmaaaaaaajkajPajmaaaaaaajkajPajmaaaaaaaaaaabaloaabaaaaaaaqZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaaaaaaaaaaabaaaaaaaaaanvaaaaaaaaaaabaaaaaaaaaacGaaaaaaaaaamNaraaptaptarbarcardarearfarganLarharianGanGarjapBarkarlarmarnaroarparqarrarsartaruarvarrarwarxaryarzarAarBarCarDarEarFarGarHarIarJarKapOarLarMarMarNarMarOapXapmaovaovaovaovarPaovarQarRarSamKakBarTakEaaaaaaaiIaabaabaabaabaiIaabaabaabaabaiIaabaabaabaabarUarVakEaabaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaabalpalpalpalpalpaaaamMaaaalpalpalpalpalpaabacGaaaaaaaaaamNarWarWarWamNamRamSamSamSarXarYaoMarZasaanGasbapBascasdaseasfasgashasiasjaskaslasmasnasoaspashasqarFasrassastasrarEasuapOasvaswasxasyapOaszasAarMarNarMasBapXasCasDasEasFasEasGasHamKamKapnamKaloasIasJakCakCarTakCakCakCakCarTakCakCakCakCarTakCakCakCasKasLasIaloaabaaaagQaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaasMasMasNasNasNasNasNasNasMasMaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaabalpalpalpalpalpaaaamMaaaalpalpalpalpalpaabacGaaaaaaaaaamNarWarWarWamNamRamSamSamSarXarYaoMarZasaanGasbapBascasdaseasfasgashasiasjaskaslasmasnasoaspashasqarFasrassastasrarEasuapOarGaswasxasyapOaszasAarMarNarMasBapXasCasDasEasFasEasGasHamKamKapnamKaloasIasJakCakCarTakCakCakCakCarTakCakCakCakCarTakCakCakCasKasLasIaloaabaaaagQaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaasMasMasNasNasNasNasNasNasMasMaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaaaalSalTalTalTalTalUalValWalXalXalXalXalYaaaacGaaaaaaaaaasOasPasPasPasQasRaaaaaaapwapwapwapwapwasSanGasTasUapBapBapBasVasWapEapEapEapEasXasYapEapEapEasZataatbatcatdateatfatgathapOatiatjatkatlatmatnatoatpatqarMatrapXatsattatuatvatwatxatyatzatAatBamKatCarTatDaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabatEatFatDaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabasMasMatGatHatIatJatKatLatMatIasMasMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaaabatNamLamLamLamLamLaaaamMaaaamLamLamLamLamLaabacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapwatOanGasTasUatPaqoaqpaqqaqraqsatQaquatRatSatTatUatVatWaqsatXatYatZauaaubaubaucaudapOaueaufaugauhapOauiaujaukarNarMaulapXatsarPattattattaumaovaunauoaupamKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaabaabaabaabauqaabaabaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaasMasMasMasMauratJausatJausautatJatJatJauuasMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGaaaaaaaabaaaaabaaaaaaauvaaaaaaaabaaaaabaaaaaaacGaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaapwauwanGauxasUarkauyauzauAauBauCauDauEauFauGauHauIauJauKauLauMauNauNauOauNauNauPauQauRauSauTapOauUapOauVauWauXauYauZavaapXatsavbavcavcavcavdaveavfavgavhamKaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaabaabaabaviaabaabaaaaaaaabaaaaabaabaaaaaaaaaaaaaaaaaaaaaasMavjavkavlavmavnavoavpatJatJavqavratJavsasMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaacGacGacGaabaabaabaabavtavuavtaabaabaabaabacGacGacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapwavvanGavwasUascavxavyavzavAashasiavBashavCavDashavEaspashavFavGavHavGavGavHavGavIapOatiavJapOavKapOavLavMavNavOavPavQavRavSavTavUavUavUavVavWavXavYavYavYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaabaabavZawaavZaabaabaaaaabaaaaaaaabaabaaaaaaaaaaaaaaaaaaasMawbawcawdaweawfawgatJatJatJawhawiatJawjasMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaahaaaaaaaaaaaaaabaaaaabaaaaaaaabaaaavtawkawlaaaaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmawmawmawmawmawmapwapwawnapwasUasUasUawoawpawqawrawrawsawrawsawrawrawtasZasZawuawvawwawxawvawwawxawyawzawzawzawzawzapOawAawBawCawCawDawCawEawFavUawGawHawIavVawJawKawLawMavWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaaavZawNavZaaaaabaaaaabaaaaaaaaaaabaabaaaaaaaaaaaaaaaasMawOawPavlawQawRawSawTatJawUawVawWawXasMawYaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaahaaaaaaaaaaaaaabaaaaabaaaaaaaabaaaavtawkawlaaaaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmawmawmawmawmawmapwapwawnapwasUasUasUawoawpawqawrawrawsawrawsawrawrawtasZasZasvawvawwawuawvawwawuawyawzawzawzawzawzapOawAawBawCawCawDawCawEawFavUawGawHawIavVawJawKawLawMavWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaaavZawNavZaaaaabaaaaabaaaaaaaaaaabaabaaaaaaaaaaaaaaaasMawOawPavlawQawRawSawTatJawUawVawWawXasMawYaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsapsapsaaaaaaaaaaaaaaaaaaaabaaaaabaaaaaaaabavtavtawZaxaavtaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmaxbaxcaxdaxeaxfaxgaxhaxiaxhaxjaxhaxhaxkaxlaxlaxlaxlaxlaxmaxnaxoaxlaxlaxlaxlaxpaxlaxlaxlaxlaxqaxraxsaxtaxuaxvaxwaxxapWaxyaxzaxAaxBaxCaxDaxEaxFavUaxGaxHaxIavVaxJaxKaxJaxLavWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaabavZavZaxMavZavZaabaaaaabaaaaaaaaaaaaaabaabaaaaaaaaaaaaasMaxNaxOavlasMavlavlaxPaxQasMasMasMasMasMasMaabaabaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsaaaaaaaaaaaaaaaaaaaabaabaaaaabaaaaaaaabaxRaxSaxTaxUaxRaxVaxVaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqayjaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabayCayDayEayFayCaabaaaaabaaaaaaaabaaaaaaaabaabaaaaaaayGasMavlasMavlayHayIayHayJayHayHayHayKayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxVaxVaxVaxVaxVaabaabaxRayLayMayNaxRayOaxVaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmayPayQayRaySayTawmayUayVayWayXayYayZazaazbazcayXayXayXazdayXayXayXayXayXayXazeazfazgazgazgazhaziazjaziazkazlazmaznapWazoazoazoazoazoazoaxEaxFavUazpaxHazqavVaxJazraxJaxLavWaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaabayCazsaztazuayCaabaaaaabaaaaaaaabaaaaaaayGazvayGazvayGayKayHayHayHayHayHayHayHayHayHazwazxayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm
index fb42cd3ed3d..b6735bb7be1 100644
--- a/_maps/map_files/cyberiad/z2.dmm
+++ b/_maps/map_files/cyberiad/z2.dmm
@@ -71,8 +71,8 @@
"bs" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/wall{tag = "icon-iron3"; icon_state = "iron3"},/area/space)
"bt" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea)
"bu" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea)
-"bv" = (/obj/structure/rack,/obj/item/clothing/under/dress/dress_saloon,/obj/item/clothing/head/hairflower,/turf/simulated/floor/holofloor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/holodeck/source_theatre)
-"bw" = (/obj/effect/landmark/costume,/obj/structure/rack,/turf/simulated/floor/holofloor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/holodeck/source_theatre)
+"bv" = (/obj/effect/landmark/costume,/obj/structure/rack/holorack,/turf/simulated/floor/holofloor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/holodeck/source_theatre)
+"bw" = (/obj/structure/rack/holorack,/obj/item/clothing/under/dress/dress_saloon,/obj/item/clothing/head/hairflower,/turf/simulated/floor/holofloor{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/holodeck/source_theatre)
"bx" = (/turf/simulated/floor/holofloor{icon_state = "engine"; name = "Holodeck Projector Floor"},/area/holodeck/source_wildlife)
"by" = (/turf/simulated/floor/holofloor{icon_state = "engine"; name = "Holodeck Projector Floor"},/area/holodeck/source_plating)
"bz" = (/turf/simulated/floor/holofloor{icon_state = "engine"; name = "Burn-Mix Floor"; nitrogen = 0; oxygen = 2500; temperature = 370; toxins = 5000},/area/holodeck/source_burntest)
@@ -1821,7 +1821,7 @@
(1,1,1) = {"
aaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoapaqarasatauavawaxayazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaOaPaPaPaPaPaQaPaPaPaPaPaQaPaPaPaPaPaQaPaPaPaPaPaQaPaPaPaPaPaQaPaPaPaPaPaQaPaPaPaPaPaR
-ajaSaTaUaVaWaXaYaZbabbbcbdbebfbgaXaWbbaTaUaYbcaVbebaabatauavbhbibjbkaAblbmbnapaqarasatauavbhbibjbkboblbmbnapaqarasataJaLaMaSaTaUaVaWaXaYaZbabbbcbdbebfbgaXaWbbaTaUaYaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbqbrbqbqbsbtbubtbubtbsbvbwbwbwbwbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbAbBbBbBbCbD
+ajaSaTaUaVaWaXaYaZbabbbcbdbebfbgaXaWbbaTaUaYbcaVbebaabatauavbhbibjbkaAblbmbnapaqarasatauavbhbibjbkboblbmbnapaqarasataJaLaMaSaTaUaVaWaXaYaZbabbbcbdbebfbgaXaWbbaTaUaYaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbqbrbqbqbsbtbubtbubtbsbwbvbvbvbvbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbAbBbBbBbCbD
amaVbabdaYbfaTaXbbaWbeaZbgaUbcaSaTbfbebabdaXaZaYaUaWaeaqarasatauavbhaxbjbkboblbmbnapaqararasataubhbibjbkboblbmbnapaqaGaLaMaVbabdaYbfaTaXbbaWbeaZbgaUbcaSaTbfbebabdaXaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbEbqbqbFbsbGbHbGbHbGbsbIbIbIbIbIbsbxbJbxbJbxbsbybybybybybsbzbKbzbKbzbsbLbMbMbMbNbD
adaYaWbgaXbcbaaTbebfaUbbaSbdaZaVbabcaUaWbgaTbbaXbdbfahbhbibjbkboblbmaDapaqarasatauavbhbiavbhbibjbmbnapaqarasatauavbhaxaLaMaYaWbgaXbcbaaTbebfaUbbaSbdaZaVbabcaUaWbgaTaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbObqbqbqbsbPbQbPbQbPbsbIbIbIbIbIbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD
alaXbfaSaTaZaWbaaUbcbdbeaVbgbbaYaWaZbdbfaSbabeaTbgbcagbmbnapaqarasataJavbhbibjbkboblbmbnasatauavatauavbhbibjbkboblbmaDaLaMaXbfaSaTaZaWbaaUbcbdbeaVbgbbaYaWaZbdbfaSbaaMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpbqbqbRbSbqbsbTbTbTbTbTbsbUbUbUbUbVbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD
diff --git a/_maps/map_files/cyberiad/z5.dmm b/_maps/map_files/cyberiad/z5.dmm
index b9f75a486b5..958a023b33d 100644
--- a/_maps/map_files/cyberiad/z5.dmm
+++ b/_maps/map_files/cyberiad/z5.dmm
@@ -877,10 +877,10 @@
"qS" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/explored)
"qT" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/explored)
"qU" = (/turf/simulated/wall/r_wall,/area/mine/laborcamp)
-"qV" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/item/device/radio/intercom/locked/prison{pixel_y = 25},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
-"qW" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
-"qX" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
-"qY" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/machinery/camera{c_tag = "Labor Camp Storage"; dir = 8; network = list("Labor")},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
+"qV" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
+"qW" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/item/device/radio/intercom/locked/prison{pixel_y = 25},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
+"qX" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/obj/machinery/camera{c_tag = "Labor Camp Storage"; dir = 8; network = list("Labor")},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
+"qY" = (/obj/structure/rack{dir = 1},/obj/item/clothing/glasses/meson,/obj/item/device/flashlight,/obj/item/weapon/storage/bag/ore,/obj/item/weapon/shovel{attack_verb = list("ineffectively hit"); desc = "A large tool for digging and moving dirt. Was modified with extra safety, making it ineffective as a weapon."; force = 1; name = "safety shovel"; pixel_x = -5; throwforce = 1},/obj/item/weapon/pickaxe{attack_verb = list("ineffectively hit"); desc = "A pickaxe designed to be only effective at digging rock and ore, very ineffective as a weapon."; force = 1; name = "safety pickaxe"; pixel_x = 5; throwforce = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/laborcamp)
"qZ" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/mine/laborcamp)
"ra" = (/obj/structure/table,/obj/item/device/healthanalyzer,/obj/item/stack/medical/advanced/bruise_pack,/turf/simulated/floor{icon_state = "white"},/area/mine/laborcamp)
"rb" = (/obj/structure/sign/redcross{pixel_y = 32},/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "white"},/area/mine/laborcamp)
@@ -1257,7 +1257,6 @@
"yi" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/obj/item/device/gps/mining{gpstag = "MINE2"},/obj/item/device/gps/mining{gpstag = "MINE1"},/obj/item/device/gps/mining,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -3},/turf/simulated/floor,/area/mine/eva)
"yj" = (/turf/simulated/floor,/area/mine/eva)
"yk" = (/obj/structure/dispenser/oxygen,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/mine/eva)
-"yl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/floor/plating,/area/mine/eva)
"ym" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/eva)
"yn" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/eva)
"yo" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/mine/eva)
@@ -1594,7 +1593,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacctac
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacaaaaaaaaaaaaaaaaacacacacqQqQqQqQqQqQqQqQqQqQqQqQbkbkbkbkbkbkbkbkqQqQqQbkbkbkbkbkbkbkbkplplplplqRplplplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacacacacacacaaaaaaaaacbkbkaaaaaaafafafafpepepepeafafafaeaeaeqKaeaeaeafafafpepepepepepepepepepepepepepepepepepepeafafafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaacacacacacqQqQqQqQqQqQqQqQqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkplplplplplplplplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacacaaaaaaaaaabkbkaaaaaaafafafafpepepepeafafafaeaeaeqKaeaeaeafafafpepepepepepepepepepepepepepepepepepepepeafafafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaacacacacacacqUqUqUqUqUqUqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkplplplplplplplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacacaaaaaaaaaaaaaaaaaaaaafafafpepepepeafafafaeaeaeqKaeaeaeafafafpepepepepepepepepepepepepepepepepepepepeafafafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaaaacqUqUqUqUqUqUqVqWqXqYqUqQqQqQqQqQqQqQqQqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkplplplplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkctbkbkbkbkbkbkbkbkbkbkbkbkacacacacaaaaaaaaaaaaaaaaaaafafafpepepepeafafafaeaeaeqKaeaeaeafafafpepepepepepepepepepepepepepepepepepepepepeafafafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaaaacqUqUqUqUqUqUqWqVqYqXqUqQqQqQqQqQqQqQqQqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkplplplplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkctbkbkbkbkbkbkbkbkbkbkbkbkacacacacaaaaaaaaaaaaaaaaaaafafafpepepepeafafafaeaeaeqKaeaeaeafafafpepepepepepepepepepepepepepepepepepepepepeafafafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaaaacqUqZrarbrcrdrerfrfrgqUrdrdrdrdrdrdrdrdrdrdrdbkbkbkbkbkbkbkbkbkbkbkbkbkplplplbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkctbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacacaaaaaaaaaaaaaaaaafafafpepepepeafafafafaeaeqKaeaeaeaeafafafpepepepepepepepepepepepepepepepepepepepepepeafafafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqUrhrirjrkrdrlrfrmrnrorprqrqrdrrrsrtqQqQqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacaaaaaaacaaaaaaaaafafafpepepepeafafafafaeaeqKaeaeaeaeafafafpepepepepepepepepepepepepepepepepepepepepepepepeafafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqUqUqUrdrurvrurdrwrxrdrdqUqUqUryqUrzrtrtqQqQqQqQqQqQbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacaaaaaabkbkbkaaaaafafafafpepepepepeafafaeaeqSrAqTaeaeafafafpepepepepepepepepepepepepepepepepepepepepepepepepeafafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -1689,7 +1688,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacaaaaaaaaaaaaaaacacacacacaaaaafaeaeaewtwEwFwGwHwIwJwKwLwMwNwOwPwHqCaeaeafafafafacacacacacacbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkacacacafafaeaeaeaeaeaeaeaeaeaeafafafafafacacacacbkbkbkvNwQwRwSwTwRwRvNvVvWwUvTvNwVwWwXwXwXweaeaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaafafafaeaeaeaeaeaeaeaewYwZxaxawZwZaeaeaeaeaeaeafafafafpepepepepepepepepepeafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaacacacaaaaacafaeaeaewtxbxcxdwHxcxexcxcxfxgxhwPxixjaeaeaeaeaeafafafacacacacacacacbkbkbkbkbkbkbkbkbkbkbkbkacacafafntaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafacacacacacacvNxkwRxlxmxnxovNvNvNvNvTvNwVxpxpxpxqweaeaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaaeaeaeaeaeaeaeaeaeaeaewYxrxsxsxtwZaexuaeaeaeofntafafafpepepepepepepepepepeafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaaaaaaacafaeaeaewtxvxcxcxwxcxexxxcxcwHxyxzwHqzaeaeaeaeaeaeaeafafafafacacacacacacbkbkbkbkbkbkbkbkbkacacafafaewfaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafacacacvNxAxBxCwRxDxExFxqxGxHxIvNxJxpxKxLxMweaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaeaexNxNxOxOwYxPxQxRxSwZwZwZwZaeaeaeaeafafafafpepepepepepepepepeafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacafafaeaewtxTxcxUwNxVxWxXxcwtwtwtwtwtwvsdqCaeaeaeaeaeaeaeaeafafafacacacacacbkbkbkbkbkbkbkacacacafaeaeaeaeaeaeaeaeaeaeaesdqCaeaeaeaeaeaeaeaeaeafafacacxYvNvNvNxZvNvNyaybycyaybvNvNvNvNvNydvNvNweweaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaexOxOyeyfygyhyiyjyjykylymynyoqCaeaeaenuafafafpepepepepepepeafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacafafaeaewtxTxcxUwNxVxWxXxcwtwtwtwtwtwvsdqCaeaeaeaeaeaeaeaeafafafacacacacacbkbkbkbkbkbkbkacacacafaeaeaeaeaeaeaeaeaeaeaesdqCaeaeaeaeaeaeaeaeaeafafacacxYvNvNvNxZvNvNyaybycyaybvNvNvNvNvNydvNvNweweaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaexOxOyeyfygyhyiyjyjykyoymynyoqCaeaeaenuafafafpepepepepepepeafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaewtypyqyrwHysytyuyvywyxyyyzyAyBujukrArArArArAqTaeaeaeaeafafafacacacacacbkbkbkacacacacafafaeaeuhrArArArArArArArAujukrArArArAqTaeaeaeaeaeafacacacacacxZyCyDyExpxMyFxqxMxFyGyHyIxqxMxpyJyKweweweyLyMyMyMyMyMyMyMyNyNyNyNyNyNyNxOxOxOyOyfyPyQyRySyjyjyTyUyVyWyXyYaeaeaenuafafafpepepepepepeafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaewtwtwtwtwtyZzazbwtwtzcwtwtwtwtqxqzaeaeaeaeaeqKaeaeaeaeafaeafafacacacacacacacacacacafafaeaeaeqKaeaeaeaeaeaeaeaeqxqzaeaeaeaeqKaeaeaeaeaeafafntafafacvNvNvNvNxpxMzdzezfxHzgzhzhzizizjzhzkzlzhzlzmzmzmzmzmzmzmzmznznznznznznznzozpzozqzpzrzsztzuzvzwzxyozyzzyoqzaeaeaeaeafafafafpepepepepeafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafafaeaeaeaeaewtzAzBzCzDwtzEzFonaeaeaeaeaeqMaeaeaeqSrArAqTaeaeaeaeafacacacacacacacacacacafaeaeuhrAuiaeaeaeaeafaeaeqMaeaeaeaeaeaeqKaeaeaeaeaeaeaewfaeafafafafafvNxpzGzHzIzIzHzJzKzLzIzIzMzHzNzOzOzOzPzPzPzPzPzPzPzPzQzQzQzQzQzQzRzSzSzSzTzUzVzWzXzYzZzYzYzYzYzYzYAaaeaeaeaenuafafafpepepepeafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index 5748857bbf3..3db4914cb35 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -145,7 +145,7 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(can_unwrench && istype(W, /obj/item/weapon/wrench))
var/turf/T = get_turf(src)
- if (level==1 && isturf(T) && T.intact)
+ if (level == 1 && isturf(T) && T.intact)
user << "You must remove the plating first."
return 1
var/datum/gas_mixture/int_air = return_air()
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index 283dbba4955..9fe7885c052 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -3,7 +3,6 @@
// Uses no power but can not transfer gases from a low pressure area to a high pressure area
icon = 'icons/atmos/passive_gate.dmi'
icon_state = "map"
- level = 1
name = "passive gate"
desc = "A one-way air valve that does not require power"
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index 38fe1b6c93d..f091135940b 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -15,8 +15,7 @@ Thus, the two variables affect pump operation are set in New():
/obj/machinery/atmospherics/binary/pump
icon = 'icons/atmos/pump.dmi'
icon_state = "map_off"
- level = 1
-
+
name = "gas pump"
desc = "A pump"
diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm
index 048d52d2a7a..a46382ab085 100644
--- a/code/ATMOSPHERICS/components/binary_devices/valve.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm
@@ -6,8 +6,6 @@
desc = "A pipe valve"
can_unwrench = 1
-
- level = 1
var/open = 0
diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
index 86736cd7c78..c697251bc44 100644
--- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
@@ -15,7 +15,6 @@ Thus, the two variables affect pump operation are set in New():
/obj/machinery/atmospherics/binary/volume_pump
icon = 'icons/atmos/volume_pump.dmi'
icon_state = "map_off"
- level = 1
name = "volumetric gas pump"
desc = "A volumetric pump"
diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
index ad58aff1014..55216a5a5c2 100644
--- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
@@ -7,7 +7,6 @@
icon_state = "base"
use_power = 1
initialize_directions = 0
- level = 1
can_unwrench = 1
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index d75c479ff10..7ec6d70d119 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -1,8 +1,6 @@
/obj/machinery/atmospherics/trinary/filter
icon = 'icons/atmos/filter.dmi'
icon_state = "map"
- density = 0
- level = 1
can_unwrench = 1
@@ -26,7 +24,7 @@ Filter types:
var/frequency = 0
var/datum/radio_frequency/radio_connection
-/obj/machinery/atmospherics/trinary/mixer/flipped
+/obj/machinery/atmospherics/trinary/filter/flipped
icon_state = "mmap"
flipped = 1
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 9d88e6d1e8d..cd219cd6f4e 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -1,8 +1,6 @@
/obj/machinery/atmospherics/trinary/mixer
icon = 'icons/atmos/mixer.dmi'
icon_state = "map"
- density = 0
- level = 1
can_unwrench = 1
diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
index a16f62ab5f9..a008b8886d5 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
@@ -21,15 +21,28 @@
/obj/machinery/atmospherics/trinary/New()
..()
- switch(dir)
- if(NORTH)
- initialize_directions = EAST|NORTH|SOUTH
- if(SOUTH)
- initialize_directions = SOUTH|WEST|NORTH
- if(EAST)
- initialize_directions = EAST|WEST|SOUTH
- if(WEST)
- initialize_directions = WEST|NORTH|EAST
+
+ if(!flipped)
+ switch(dir)
+ if(NORTH)
+ initialize_directions = EAST|NORTH|SOUTH
+ if(SOUTH)
+ initialize_directions = SOUTH|WEST|NORTH
+ if(EAST)
+ initialize_directions = EAST|WEST|SOUTH
+ if(WEST)
+ initialize_directions = WEST|NORTH|EAST
+ else
+ switch(dir)
+ if(NORTH)
+ initialize_directions = SOUTH|NORTH|WEST
+ if(SOUTH)
+ initialize_directions = NORTH|SOUTH|EAST
+ if(EAST)
+ initialize_directions = WEST|EAST|NORTH
+ if(WEST)
+ initialize_directions = EAST|WEST|SOUTH
+
air1 = new
air2 = new
air3 = new
@@ -65,14 +78,17 @@
//Node 2 is filtered output
//Node 3 is rest output
//If we flip the filter, 1 and 3 shall exchange positions
+
+ if(can_unwrench) // Overridden here to avoid having to snowflake the flipped/icon_state on the construction
+ qdel(stored)
+ stored = new(src, make_from = src)
var/node1_connect = turn(dir, -180)
var/node2_connect = turn(dir, -90)
var/node3_connect = dir
if(flipped)
- node1_connect = turn(node1_connect, 180)
- node3_connect = turn(node3_connect, 180)
+ node2_connect = turn(node2_connect, -180)
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
if(target.initialize_directions & get_dir(target,src))
diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
index 6d3f2843058..7e91c931f16 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm
@@ -10,19 +10,29 @@
can_unwrench = 1
- level = 1
-
var/state = TVALVE_STATE_STRAIGHT
/obj/machinery/atmospherics/trinary/tvalve/bypass
icon_state = "map_tvalve1"
state = TVALVE_STATE_SIDE
+/obj/machinery/atmospherics/trinary/tvalve/flipped
+ icon_state = "map_tvalvem0"
+ flipped = 1
+
+/obj/machinery/atmospherics/trinary/tvalve/flipped/bypass
+ icon_state = "map_tvalvem1"
+ flipped = 1
+ state = TVALVE_STATE_SIDE
+
/obj/machinery/atmospherics/trinary/tvalve/update_icon(animation)
+ var/flipstate = ""
+ if(flipped)
+ flipstate = "m"
if(animation)
- flick("tvalve[src.state][!src.state]",src)
+ flick("tvalve[flipstate][src.state][!src.state]",src)
else
- icon_state = "tvalve[state]"
+ icon_state = "tvalve[flipstate][state]"
/obj/machinery/atmospherics/trinary/tvalve/update_underlays()
if(..())
@@ -32,7 +42,10 @@
return
add_underlay(T, node1, turn(dir, -180))
- add_underlay(T, node2, turn(dir, -90))
+ if(flipped)
+ add_underlay(T, node2, turn(dir, 90))
+ else
+ add_underlay(T, node2, turn(dir, -90))
add_underlay(T, node3, dir)
@@ -93,6 +106,15 @@
/obj/machinery/atmospherics/trinary/tvalve/digital/bypass
icon_state = "map_tvalve1"
state = TVALVE_STATE_SIDE
+
+/obj/machinery/atmospherics/trinary/tvalve/digital/flipped
+ icon_state = "map_tvalvem0"
+ flipped = 1
+
+/obj/machinery/atmospherics/trinary/tvalve/digital/flipped/bypass
+ icon_state = "map_tvalvem1"
+ flipped = 1
+ state = TVALVE_STATE_SIDE
/obj/machinery/atmospherics/trinary/tvalve/digital/power_change()
var/old_stat = stat
diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
index b18e5648eac..79078b66f6f 100644
--- a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
@@ -1,6 +1,4 @@
/obj/machinery/atmospherics/unary/heat_reservoir
-//currently the same code as cold_sink but anticipating process() changes
-
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
density = 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
index 08e2712f38f..92bdee806bf 100644
--- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm
@@ -22,8 +22,6 @@
var/datum/radio_frequency/radio_connection
Mtoollink = 1
settagwhitelist = list("id_tag")
-
- level = 1
/obj/machinery/atmospherics/unary/outlet_injector/on
on = 1
diff --git a/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm b/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm
index ef26254c027..b9399f42e6c 100644
--- a/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/portables_connector.dm
@@ -11,8 +11,6 @@
var/obj/machinery/portable_atmospherics/connected_device
var/on = 0
- use_power = 0
- level = 1
/obj/machinery/atmospherics/unary/portables_connector/Destroy()
if(connected_device)
diff --git a/code/ATMOSPHERICS/components/unary_devices/tank.dm b/code/ATMOSPHERICS/components/unary_devices/tank.dm
index 465fc1103d9..88f32eba44a 100644
--- a/code/ATMOSPHERICS/components/unary_devices/tank.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/tank.dm
@@ -7,7 +7,6 @@
var/volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet
- level = 1
density = 1
/obj/machinery/atmospherics/unary/tank/update_underlays()
diff --git a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
index b0be337687a..6cbaa60e6b6 100644
--- a/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/thermal_plate.dm
@@ -1,16 +1,13 @@
#define RADIATION_CAPACITY 30000 //Radiation isn't particularly effective (TODO BALANCE)
-
-
/obj/machinery/atmospherics/unary/thermal_plate
//Based off Heat Reservoir and Space Heater
//Transfers heat between a pipe system and environment, based on which has a greater thermal energy concentration
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "off"
- level = 1
can_unwrench = 1
- name = "Thermal Transfer Plate"
+ name = "thermal tansfer plate"
desc = "Transfers heat to and from an area"
/obj/machinery/atmospherics/unary/thermal_plate/update_icon()
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
index c2d49512dd9..3df03bebde7 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
@@ -7,14 +7,13 @@
icon = 'icons/atmos/vent_pump.dmi'
icon_state = "map_vent"
- name = "Air Vent"
+ name = "air vent"
desc = "Has a valve and pump attached to it"
use_power = 1
can_unwrench = 1
var/area/initial_loc
- level = 1
var/area_uid
var/id_tag = null
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
index 87a45435196..cc62e860bde 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
@@ -4,14 +4,13 @@
req_one_access_txt = "24;10"
- name = "Air Scrubber"
+ name = "air scrubber"
desc = "Has a valve and pump attached to it"
use_power = 1
idle_power_usage = 10
active_power_usage = 60
- level = 1
can_unwrench = 1
var/area/initial_loc
diff --git a/code/modules/hydroponics/_hydro_setup.dm b/code/__DEFINES/hydroponics.dm
similarity index 96%
rename from code/modules/hydroponics/_hydro_setup.dm
rename to code/__DEFINES/hydroponics.dm
index a3fd4604a66..a53e66f0a0f 100644
--- a/code/modules/hydroponics/_hydro_setup.dm
+++ b/code/__DEFINES/hydroponics.dm
@@ -55,4 +55,5 @@
#define TRAIT_PRODUCT_COLOUR 35
#define TRAIT_BIOLUM 36
#define TRAIT_BIOLUM_COLOUR 37
-#define TRAIT_IMMUTABLE 38
\ No newline at end of file
+#define TRAIT_IMMUTABLE 38
+#define TRAIT_RARITY 39
\ No newline at end of file
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 2e748d40b7b..c832bcc03d4 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -22,4 +22,7 @@ var/global/list/rcd_list = list() //list of Rapid Construction Devices.
var/global/list/apcs = list()
var/global/list/air_alarms = list()
-var/global/list/power_monitors = list()
\ No newline at end of file
+var/global/list/power_monitors = list()
+
+var/global/list/tracking_implants = list() //list of all tracking implants to work out what treks everyone are on. Sadly not on lavaworld not implemented...
+var/global/list/beacons = list()
\ No newline at end of file
diff --git a/code/datums/material_container.dm b/code/datums/material_container.dm
index 8f84812e49e..5de0b6e1644 100644
--- a/code/datums/material_container.dm
+++ b/code/datums/material_container.dm
@@ -41,7 +41,8 @@
/datum/material_container/Destroy()
owner = null
- return ..()
+ ..()
+ return QDEL_HINT_QUEUE
//For inserting an amount of material
/datum/material_container/proc/insert_amount(amt, material_type = null)
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 2055c2790b7..4d0ec45eecb 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -48,7 +48,8 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
/datum/wires/Destroy()
holder = null
- return ..()
+ ..()
+ return QDEL_HINT_QUEUE
/datum/wires/proc/GenerateWires()
var/list/colours_to_pick = wireColours.Copy() // Get a copy, not a reference.
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index 87f83439980..b5ad01dd92d 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -29,6 +29,7 @@
H.equip_or_collect(Barpack, slot_r_hand)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack)
+ H.equip_or_collect(new /obj/item/toy/russian_revolver(H.back), slot_in_backpack)
H.dna.SetSEState(SOBERBLOCK,1)
H.mutations += SOBER
diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm
index f6b39cb5f38..a8b3b4f218e 100644
--- a/code/game/machinery/Beacon.dm
+++ b/code/game/machinery/Beacon.dm
@@ -1,5 +1,4 @@
/obj/machinery/bluespace_beacon
-
icon = 'icons/obj/objects.dmi'
icon_state = "floor_beaconf"
name = "Bluespace Gigabeacon"
@@ -12,47 +11,45 @@
var/syndicate = 0
var/obj/item/device/radio/beacon/Beacon
- New()
- ..()
+/obj/machinery/bluespace_beacon/New()
+ ..()
+ var/turf/T = loc
+ Beacon = new /obj/item/device/radio/beacon
+ Beacon.invisibility = INVISIBILITY_MAXIMUM
+ Beacon.loc = T
+ Beacon.syndicate = syndicate
+
+ hide(T.intact)
+
+/obj/machinery/bluespace_beacon/Destroy()
+ if(Beacon)
+ qdel(Beacon)
+ Beacon = null
+ return ..()
+
+// update the invisibility and icon
+/obj/machinery/bluespace_beacon/hide(var/intact)
+ invisibility = intact ? 101 : 0
+ update_icon()
+
+// update the icon_state
+/obj/machinery/bluespace_beacon/update_icon()
+ var/state="floor_beacon"
+
+ if(invisibility)
+ icon_state = "[state]f"
+
+ else
+ icon_state = "[state]"
+
+/obj/machinery/bluespace_beacon/process()
+ if(!Beacon)
var/turf/T = loc
Beacon = new /obj/item/device/radio/beacon
Beacon.invisibility = INVISIBILITY_MAXIMUM
Beacon.loc = T
- Beacon.syndicate = syndicate
-
- hide(T.intact)
-
- Destroy()
- if(Beacon)
- qdel(Beacon)
- Beacon = null
- return ..()
-
- // update the invisibility and icon
- hide(var/intact)
- invisibility = intact ? 101 : 0
- updateicon()
-
- // update the icon_state
- proc/updateicon()
- var/state="floor_beacon"
-
- if(invisibility)
- icon_state = "[state]f"
-
- else
- icon_state = "[state]"
-
- process()
- if(!Beacon)
- var/turf/T = loc
- Beacon = new /obj/item/device/radio/beacon
- Beacon.invisibility = INVISIBILITY_MAXIMUM
- Beacon.loc = T
- if(Beacon)
- if(Beacon.loc != loc)
- Beacon.loc = loc
-
- updateicon()
-
+ if(Beacon)
+ if(Beacon.loc != loc)
+ Beacon.loc = loc
+ update_icon()
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index a0111fabfbf..98d4cd9a5fc 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -12,153 +12,144 @@
light_color = LIGHT_COLOR_CYAN
-
- attack_ai(var/mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob)
+ return attack_hand(user)
- attack_hand(var/mob/user as mob)
+/obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob)
+ if(..())
+ return 1
+
+ user.set_machine(src)
+ var/dat
- if(..())
- return
- user.set_machine(src)
- var/dat
+ dat += "Holodeck Control System
"
+ dat += "
Current Loaded Programs:
"
-
- dat += "Holodeck Control System
"
- dat += "
Current Loaded Programs:
"
-
- dat += "((Empty Court))
"
- dat += "((Boxing Court))
"
- dat += "((Basketball Court))
"
- dat += "((Thunderdome Court))
"
- dat += "((Beach))
"
- dat += "((Desert))
"
- dat += "((Space))
"
- dat += "((Picnic Area))
"
- dat += "((Snow Field))
"
- dat += "((Theatre))
"
- dat += "((Meeting Hall))
"
+ dat += "((Empty Court))
"
+ dat += "((Boxing Court))
"
+ dat += "((Basketball Court))
"
+ dat += "((Thunderdome Court))
"
+ dat += "((Beach))
"
+ dat += "((Desert))
"
+ dat += "((Space))
"
+ dat += "((Picnic Area))
"
+ dat += "((Snow Field))
"
+ dat += "((Theatre))
"
+ dat += "((Meeting Hall))
"
// dat += "((Shutdown System))
"
- dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
"
+ dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
"
- if(emagged)
+ if(emagged)
/* dat += "(Begin Atmospheric Burn Simulation)
"
- dat += "Ensure the holodeck is empty before testing.
"
- dat += "
"*/
- dat += "(Begin Wildlife Simulation)
"
- dat += "Ensure the holodeck is empty before testing.
"
- dat += "
"
- if(issilicon(user))
- dat += "(Re-Enable Safety Protocols?)
"
- dat += "Safety Protocols are DISABLED
"
- else
- if(issilicon(user))
- dat += "(Override Safety Protocols?)
"
- dat += "
"
- dat += "Safety Protocols are ENABLED
"
+ dat += "Ensure the holodeck is empty before testing.
"
+ dat += "
"*/
+ dat += "(Begin Wildlife Simulation)
"
+ dat += "Ensure the holodeck is empty before testing.
"
+ dat += "
"
+ if(issilicon(user))
+ dat += "(Re-Enable Safety Protocols?)
"
+ dat += "Safety Protocols are DISABLED
"
+ else
+ if(issilicon(user))
+ dat += "(Override Safety Protocols?)
"
+ dat += "
"
+ dat += "Safety Protocols are ENABLED
"
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+ return
+/obj/machinery/computer/HolodeckControl/Topic(href, href_list)
+ if(..())
+ return 1
- return
+ if(href_list["emptycourt"])
+ target = locate(/area/holodeck/source_emptycourt)
+ if(target)
+ loadProgram(target)
+ else if(href_list["boxingcourt"])
+ target = locate(/area/holodeck/source_boxingcourt)
+ if(target)
+ loadProgram(target)
- Topic(href, href_list)
- if(..())
- return
- if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- usr.set_machine(src)
+ else if(href_list["basketball"])
+ target = locate(/area/holodeck/source_basketball)
+ if(target)
+ loadProgram(target)
- if(href_list["emptycourt"])
- target = locate(/area/holodeck/source_emptycourt)
- if(target)
- loadProgram(target)
+ else if(href_list["thunderdomecourt"])
+ target = locate(/area/holodeck/source_thunderdomecourt)
+ if(target)
+ loadProgram(target)
- else if(href_list["boxingcourt"])
- target = locate(/area/holodeck/source_boxingcourt)
- if(target)
- loadProgram(target)
+ else if(href_list["beach"])
+ target = locate(/area/holodeck/source_beach)
+ if(target)
+ loadProgram(target)
- else if(href_list["basketball"])
- target = locate(/area/holodeck/source_basketball)
- if(target)
- loadProgram(target)
+ else if(href_list["desert"])
+ target = locate(/area/holodeck/source_desert)
+ if(target)
+ loadProgram(target)
- else if(href_list["thunderdomecourt"])
- target = locate(/area/holodeck/source_thunderdomecourt)
- if(target)
- loadProgram(target)
+ else if(href_list["space"])
+ target = locate(/area/holodeck/source_space)
+ if(target)
+ loadProgram(target)
- else if(href_list["beach"])
- target = locate(/area/holodeck/source_beach)
- if(target)
- loadProgram(target)
+ else if(href_list["picnicarea"])
+ target = locate(/area/holodeck/source_picnicarea)
+ if(target)
+ loadProgram(target)
- else if(href_list["desert"])
- target = locate(/area/holodeck/source_desert)
- if(target)
- loadProgram(target)
+ else if(href_list["snowfield"])
+ target = locate(/area/holodeck/source_snowfield)
+ if(target)
+ loadProgram(target)
- else if(href_list["space"])
- target = locate(/area/holodeck/source_space)
- if(target)
- loadProgram(target)
+ else if(href_list["theatre"])
+ target = locate(/area/holodeck/source_theatre)
+ if(target)
+ loadProgram(target)
- else if(href_list["picnicarea"])
- target = locate(/area/holodeck/source_picnicarea)
- if(target)
- loadProgram(target)
+ else if(href_list["meetinghall"])
+ target = locate(/area/holodeck/source_meetinghall)
+ if(target)
+ loadProgram(target)
- else if(href_list["snowfield"])
- target = locate(/area/holodeck/source_snowfield)
- if(target)
- loadProgram(target)
-
- else if(href_list["theatre"])
- target = locate(/area/holodeck/source_theatre)
- if(target)
- loadProgram(target)
-
- else if(href_list["meetinghall"])
- target = locate(/area/holodeck/source_meetinghall)
- if(target)
- loadProgram(target)
-
- else if(href_list["turnoff"])
- target = locate(/area/holodeck/source_plating)
- if(target)
- loadProgram(target)
+ else if(href_list["turnoff"])
+ target = locate(/area/holodeck/source_plating)
+ if(target)
+ loadProgram(target)
/*
- else if(href_list["burntest"])
- if(!emagged) return
- target = locate(/area/holodeck/source_burntest)
- if(target)
- loadProgram(target)
+ else if(href_list["burntest"])
+ if(!emagged) return
+ target = locate(/area/holodeck/source_burntest)
+ if(target)
+ loadProgram(target)
*/
- else if(href_list["wildlifecarp"])
- if(!emagged) return
- target = locate(/area/holodeck/source_wildlife)
- if(target)
- loadProgram(target)
-
- else if(href_list["AIoverride"])
- if(!issilicon(usr)) return
- emagged = !emagged
- if(emagged)
- message_admins("[key_name_admin(usr)] overrode the holodeck's safeties")
- log_game("[key_name(usr)] overrided the holodeck's safeties")
- else
- message_admins("[key_name_admin(usr)] restored the holodeck's safeties")
- log_game("[key_name(usr)] restored the holodeck's safeties")
-
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
+ else if(href_list["wildlifecarp"])
+ if(!emagged) return
+ target = locate(/area/holodeck/source_wildlife)
+ if(target)
+ loadProgram(target)
+ else if(href_list["AIoverride"])
+ if(!issilicon(usr)) return
+ emagged = !emagged
+ if(emagged)
+ message_admins("[key_name_admin(usr)] overrode the holodeck's safeties")
+ log_game("[key_name(usr)] overrided the holodeck's safeties")
+ else
+ message_admins("[key_name_admin(usr)] restored the holodeck's safeties")
+ log_game("[key_name(usr)] restored the holodeck's safeties")
+ add_fingerprint(usr)
+ updateUsrDialog()
+ return
/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob, params)
return
@@ -189,12 +180,10 @@
emergencyShutdown()
..()
-
/obj/machinery/computer/HolodeckControl/ex_act(severity)
emergencyShutdown()
..()
-
/obj/machinery/computer/HolodeckControl/blob_act()
emergencyShutdown()
..()
@@ -206,8 +195,8 @@
if(!..())
return
+
if(active)
-
if(!checkInteg(linkedholodeck))
damaged = 1
target = locate(/area/holodeck/source_plating)
@@ -332,14 +321,7 @@
targetsource.copy_contents_to(linkedholodeck , 1)
active = 0
-
-
-
-
-
-
// Holographic Items!
-
/turf/simulated/floor/holofloor/
thermal_conductivity = 0
@@ -363,53 +345,24 @@
return
// HOLOFLOOR DOES NOT GIVE A FUCK
-
-
-
-
-
-
-
-
-
/obj/structure/table/holotable
name = "table"
- desc = "A square piece of metal standing on four metal legs. It can not move."
- icon = 'icons/obj/structures.dmi'
- icon_state = "table"
- density = 1
- anchored = 1.0
- layer = 2.8
- throwpass = 1 //You can throw objects over this, despite it's density.
-
-/obj/structure/table/holotable/attack_alien(mob/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
+/obj/structure/table/holotable/attack_alien(mob/user as mob)
return attack_hand(user)
-/obj/structure/table/holotable/attack_animal(mob/living/simple_animal/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
+/obj/structure/table/holotable/attack_animal(mob/living/simple_animal/user as mob)
return attack_hand(user)
/obj/structure/table/holotable/attack_hand(mob/user as mob)
return // HOLOTABLE DOES NOT GIVE A FUCK
-
/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
- var/obj/item/weapon/grab/G = W
- if(G.state<2)
- user << "\red You need a better grip to do that!"
- return
- G.affecting.loc = src.loc
- G.affecting.Weaken(5)
- visible_message("\red [G.assailant] puts [G.affecting] on the table.")
- qdel(W)
- return
+ if (istype(W, /obj/item/weapon/grab))
+ return ..()
if (istype(W, /obj/item/weapon/wrench))
- user << "It's a holotable! There are no bolts!"
- return
-
- if(isrobot(user))
+ user << "It's a holotable! There are no bolts!"
return
/obj/structure/table/holotable/wood
@@ -418,7 +371,6 @@
icon = 'icons/obj/structures.dmi'
icon_state = "wood_table"
-
/obj/item/clothing/gloves/boxing/hologlove
name = "boxing gloves"
desc = "Because you really needed another excuse to punch your crewmates."
@@ -435,10 +387,23 @@
pressure_resistance = 4*ONE_ATMOSPHERE
anchored = 1.0
flags = ON_BORDER
+
+/obj/structure/rack/holorack
+ name = "rack"
+/obj/structure/rack/holorack/attack_alien(mob/user as mob)
+ return attack_hand(user)
-/obj/structure/holowindow/Destroy()
- return ..()
+/obj/structure/rack/holorack/attack_animal(mob/living/simple_animal/user as mob)
+ return attack_hand(user)
+
+/obj/structure/rack/holorack/attack_hand(mob/user as mob)
+ return // HOLORACK DOES NOT GIVE A FUCK
+
+/obj/structure/rack/holorack/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+ if (istype(W, /obj/item/weapon/wrench))
+ user << "It's a holorack! There are no bolts!"
+ return
/obj/item/weapon/holo
damtype = STAMINA
@@ -454,22 +419,17 @@
flags = NOSHIELD
var/active = 0
-/obj/item/weapon/holo/esword/green
- New()
- _color = "green"
+/obj/item/weapon/holo/esword/green/New()
+ _color = "green"
-/obj/item/weapon/holo/esword/red
- New()
- _color = "red"
+/obj/item/weapon/holo/esword/red/New()
+ _color = "red"
/obj/item/weapon/holo/esword/IsShield()
if(active)
return 1
return 0
-/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob)
- ..()
-
/obj/item/weapon/holo/esword/New()
_color = pick("red","blue","green","purple")
@@ -480,13 +440,13 @@
icon_state = "sword[_color]"
w_class = 4
playsound(user, 'sound/weapons/saberon.ogg', 50, 1)
- user << "\blue [src] is now active."
+ user << "[src] is now active."
else
force = 3
icon_state = "sword0"
w_class = 2
playsound(user, 'sound/weapons/saberoff.ogg', 50, 1)
- user << "\blue [src] can now be concealed."
+ user << "[src] can now be concealed."
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_l_hand()
@@ -495,7 +455,6 @@
return
//BASKETBALL OBJECTS
-
/obj/item/weapon/beach_ball/holoball
icon = 'icons/obj/basketball.dmi'
icon_state = "basketball"
@@ -506,7 +465,7 @@
/obj/structure/holohoop
name = "basketball hoop"
- desc = "Boom, Shakalaka!."
+ desc = "Boom, Shakalaka!"
icon = 'icons/obj/basketball.dmi'
icon_state = "hoop"
anchored = 1
@@ -517,16 +476,16 @@
if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
var/obj/item/weapon/grab/G = W
if(G.state<2)
- user << "\red You need a better grip to do that!"
+ user << "You need a better grip to do that!"
return
G.affecting.loc = src.loc
G.affecting.Weaken(5)
- visible_message("\red [G.assailant] dunks [G.affecting] into the [src]!", 3)
+ visible_message("[G.assailant] dunks [G.affecting] into the [src]!", 3)
qdel(W)
return
else if (istype(W, /obj/item) && get_dist(src,user)<2)
user.drop_item(src)
- visible_message("\blue [user] dunks [W] into the [src]!", 3)
+ visible_message("[user] dunks [W] into the [src]!", 3)
return
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
@@ -536,14 +495,13 @@
return
if(prob(50))
I.loc = src.loc
- visible_message("\blue Swish! \the [I] lands in \the [src].", 3)
+ visible_message("Swish! \the [I] lands in \the [src].", 3)
else
- visible_message("\red \the [I] bounces off of \the [src]'s rim!", 3)
+ visible_message("\The [I] bounces off of \the [src]'s rim!", 3)
return 0
else
return ..(mover, target, height, air_group)
-
/obj/machinery/readybutton
name = "Ready Declaration Device"
desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
@@ -563,10 +521,6 @@
user << "The station AI is not to interact with these devices"
return
-/obj/machinery/readybutton/New()
- ..()
-
-
/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
user << "The device is a solid button, there's nothing you can do with it!"
@@ -604,7 +558,6 @@
icon_state = "auth_off"
/obj/machinery/readybutton/proc/begin_event()
-
eventstarted = 1
for(var/obj/structure/holowindow/W in currentarea)
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index d144eebac2c..af429a3014b 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -17,126 +17,118 @@
light_color = LIGHT_COLOR_DARKRED
+/obj/machinery/computer/prisoner/attack_ai(var/mob/user as mob)
+ return src.attack_hand(user)
- attack_ai(var/mob/user as mob)
- return src.attack_hand(user)
+/obj/machinery/computer/prisoner/attack_hand(var/mob/user as mob)
+ if(..())
+ return 1
+ user.set_machine(src)
+ var/dat
+ dat += "Prisoner Implant Manager System
"
+ if(screen == 0)
+ dat += "
Unlock Console"
+ else if(screen == 1)
+ if(istype(inserted_id))
+ var/p = inserted_id:points
+ var/g = inserted_id:goal
+ dat += text("[inserted_id]
")
+ dat += text("Collected points: [p]. Reset.
")
+ dat += text("Card goal: [g]. Set
")
+ dat += text("Space Law recommends sentences of 100 points per minute they would normally serve in the brig.
")
+ else
+ dat += text("Insert Prisoner ID
")
+ dat += "
Chemical Implants
"
+ var/turf/Tr = null
+ for(var/obj/item/weapon/implant/chem/C in tracking_implants)
+ Tr = get_turf(C)
+ if((Tr) && (Tr.z != src.z)) continue//Out of range
+ if(!C.implanted) continue
+ // AUTOFIXED BY fix_string_idiocy.py
+ // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\computer\prisoner.dm:41: dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: "
+ dat += {"[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject:
+ ((1))
+ ((5))
+ ((10))
+ ********************************
"}
+ // END AUTOFIX
+ dat += "
Tracking Implants
"
+ for(var/obj/item/weapon/implant/tracking/T in tracking_implants)
+ Tr = get_turf(T)
+ if((Tr) && (Tr.z != src.z)) continue//Out of range
+ if(!T.implanted) continue
+ var/loc_display = "Unknown"
+ var/mob/living/carbon/M = T.imp_in
+ if((M.z in config.station_levels) && !istype(M.loc, /turf/space))
+ var/turf/mob_loc = get_turf(M)
+ loc_display = mob_loc.loc
+ if(T.malfunction)
+ loc_display = pick(teleportlocs)
+ dat += "ID: [T.id] | Location: [loc_display]
"
+ dat += "(Message Holder) |
"
+ dat += "********************************
"
+ dat += "
Lock Console"
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+ return
+/obj/machinery/computer/prisoner/process()
+ if(!..())
+ src.updateDialog()
+ return
- attack_hand(var/mob/user as mob)
- if(..())
- return
- user.set_machine(src)
- var/dat
- dat += "Prisoner Implant Manager System
"
- if(screen == 0)
- dat += "
Unlock Console"
- else if(screen == 1)
- if(istype(inserted_id))
- var/p = inserted_id:points
- var/g = inserted_id:goal
- dat += text("[inserted_id]
")
- dat += text("Collected points: [p]. Reset.
")
- dat += text("Card goal: [g]. Set
")
- dat += text("Space Law recommends sentences of 100 points per minute they would normally serve in the brig.
")
- else
- dat += text("Insert Prisoner ID.
")
- dat += "
Chemical Implants
"
- var/turf/Tr = null
- for(var/obj/item/weapon/implant/chem/C in world)
- Tr = get_turf(C)
- if((Tr) && (Tr.z != src.z)) continue//Out of range
- if(!C.implanted) continue
+/obj/machinery/computer/prisoner/Topic(href, href_list)
+ if(..())
+ return 1
+
+ usr.set_machine(src)
- // AUTOFIXED BY fix_string_idiocy.py
- // C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\computer\prisoner.dm:41: dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: "
- dat += {"[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject:
- ((1))
- ((5))
- ((10))
- ********************************
"}
- // END AUTOFIX
- dat += "
Tracking Implants
"
- for(var/obj/item/weapon/implant/tracking/T in world)
- Tr = get_turf(T)
- if((Tr) && (Tr.z != src.z)) continue//Out of range
- if(!T.implanted) continue
- var/loc_display = "Unknown"
- var/mob/living/carbon/M = T.imp_in
- if((M.z in config.station_levels) && !istype(M.loc, /turf/space))
- var/turf/mob_loc = get_turf(M)
- loc_display = mob_loc.loc
- if(T.malfunction)
- loc_display = pick(teleportlocs)
- dat += "ID: [T.id] | Location: [loc_display]
"
- dat += "(Message Holder) |
"
- dat += "********************************
"
- dat += "
Lock Console"
+ if(href_list["id"])
+ switch(href_list["id"])
+ if("0")
+ var/obj/item/weapon/card/id/prisoner/I = usr.get_active_hand()
+ if(istype(I))
+ usr.drop_item()
+ I.loc = src
+ inserted_id = I
+ else usr << "\red No valid ID."
+ if("1")
+ inserted_id.loc = get_step(src,get_turf(usr))
+ inserted_id = null
+ if("2")
+ inserted_id.points = 0
+ if("3")
+ var/num = round(input(usr, "Choose prisoner's goal:", "Input an Integer", null) as num|null)
+ if(num >= 0)
+ inserted_id.goal = num
+ if(href_list["inject1"])
+ var/obj/item/weapon/implant/I = locate(href_list["inject1"])
+ if(I) I.activate(1)
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
- return
+ else if(href_list["inject5"])
+ var/obj/item/weapon/implant/I = locate(href_list["inject5"])
+ if(I) I.activate(5)
+ else if(href_list["inject10"])
+ var/obj/item/weapon/implant/I = locate(href_list["inject10"])
+ if(I) I.activate(10)
- process()
- if(!..())
- src.updateDialog()
- return
-
-
- Topic(href, href_list)
- if(..())
- return
- if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- usr.set_machine(src)
-
- if(href_list["id"])
- switch(href_list["id"])
- if("0")
- var/obj/item/weapon/card/id/prisoner/I = usr.get_active_hand()
- if(istype(I))
- usr.drop_item()
- I.loc = src
- inserted_id = I
- else usr << "\red No valid ID."
- if("1")
- inserted_id.loc = get_step(src,get_turf(usr))
- inserted_id = null
- if("2")
- inserted_id.points = 0
- if("3")
- var/num = round(input(usr, "Choose prisoner's goal:", "Input an Integer", null) as num|null)
- if(num >= 0)
- inserted_id.goal = num
- if(href_list["inject1"])
- var/obj/item/weapon/implant/I = locate(href_list["inject1"])
- if(I) I.activate(1)
-
- else if(href_list["inject5"])
- var/obj/item/weapon/implant/I = locate(href_list["inject5"])
- if(I) I.activate(5)
-
- else if(href_list["inject10"])
- var/obj/item/weapon/implant/I = locate(href_list["inject10"])
- if(I) I.activate(10)
-
- else if(href_list["lock"])
- if(src.allowed(usr))
- screen = !screen
- else
- usr << "Unauthorized Access."
-
- else if(href_list["warn"])
- var/warning = sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN))
- if(!warning) return
- var/obj/item/weapon/implant/I = locate(href_list["warn"])
- if((I)&&(I.imp_in))
- var/mob/living/carbon/R = I.imp_in
- R << "\green You hear a voice in your head saying: '[warning]'"
-
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
+ else if(href_list["lock"])
+ if(src.allowed(usr))
+ screen = !screen
+ else
+ usr << "Unauthorized access."
+ else if(href_list["warn"])
+ var/warning = sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN))
+ if(!warning) return
+ var/obj/item/weapon/implant/I = locate(href_list["warn"])
+ if((I)&&(I.imp_in))
+ var/mob/living/carbon/R = I.imp_in
+ R << "You hear a voice in your head saying: '[warning]'"
+ src.add_fingerprint(usr)
+ src.updateUsrDialog()
+ return
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 8f9802f840a..48d1b27d9bd 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -929,8 +929,9 @@ About the new airlock wires panel:
operating = 0
air_update_turf(1)
update_freelok_sight()
- if(locate(/mob/living) in get_turf(src))
- open()
+ if(safe)
+ if(locate(/mob/living) in get_turf(src))
+ open()
return
diff --git a/code/game/machinery/kitchen/monkeyrecycler.dm b/code/game/machinery/kitchen/monkeyrecycler.dm
index 01b4968d909..22115ad0cdc 100644
--- a/code/game/machinery/kitchen/monkeyrecycler.dm
+++ b/code/game/machinery/kitchen/monkeyrecycler.dm
@@ -78,7 +78,7 @@
if(grinded >= required_grind)
user << "\blue The machine hisses loudly as it condenses the grinded monkey meat. After a moment, it dispenses a brand new monkey cube."
playsound(src.loc, 'sound/machines/hiss.ogg', 50, 1)
- grinded -= 5
+ grinded -= required_grind
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src.loc)
user << "\blue The machine's display flashes that it has [grinded] monkeys worth of material left."
else
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 6a3783a5cd6..667602686b5 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -16,7 +16,7 @@
#define PIPE_PASSIVE_GATE 15
#define PIPE_VOLUME_PUMP 16
#define PIPE_HEAT_EXCHANGE 17
-#define PIPE_MTVALVE 18
+#define PIPE_TVALVE 18
#define PIPE_MANIFOLD4W 19
#define PIPE_CAP 20
#define PIPE_OMNI_MIXER 21
@@ -117,7 +117,7 @@
else if(istype(make_from, /obj/machinery/atmospherics/trinary/tvalve/digital))
src.pipe_type = PIPE_DTVALVE
else if(istype(make_from, /obj/machinery/atmospherics/trinary/tvalve))
- src.pipe_type = PIPE_MTVALVE
+ src.pipe_type = PIPE_TVALVE
else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply))
src.pipe_type = PIPE_SUPPLY_MANIFOLD4W
connect_types = list(2)
@@ -152,7 +152,6 @@
var/obj/machinery/atmospherics/trinary/triP = make_from
if(istype(triP) && triP.flipped)
src.flipped = 1
- src.dir = turn(src.dir, -45)
else
src.pipe_type = pipe_type
@@ -166,13 +165,13 @@
else if (pipe_type == PIPE_UNIVERSAL)
connect_types = list(1,2,3)
//src.pipe_dir = get_pipe_dir()
- update()
+ update(make_from)
src.pixel_x = rand(-5, 5)
src.pixel_y = rand(-5, 5)
//update the name and icon of the pipe item depending on the type
-/obj/item/pipe/proc/update()
+/obj/item/pipe/proc/update(var/obj/machinery/atmospherics/make_from)
var/list/nlist = list( \
"pipe", \
"bent pipe", \
@@ -234,7 +233,7 @@
"passivegate", \
"volumepump", \
"heunary", \
- "mtvalve", \
+ "tvalve", \
"manifold4w", \
"cap", \
"omni_mixer", \
@@ -257,6 +256,9 @@
"dtvalve", \
)
icon_state = islist[pipe_type + 1]
+ var/obj/machinery/atmospherics/trinary/triP = make_from
+ if(istype(triP) && triP.flipped)
+ icon_state = "m_[icon_state]"
//called when a turf is attacked with a pipe item
// place the pipe on the turf, setting pipe level to 1 (underfloor) if the turf is not intact
@@ -288,11 +290,14 @@
set name = "Flip Pipe"
set src in view(1)
- if ( usr.stat || usr.restrained() )
+ if (usr.stat || usr.restrained())
return
- if (pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER))
- src.dir = turn(src.dir, flipped ? 45 : -45)
+ if (pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE))
+ if(flipped)
+ icon_state = copytext(icon_state,3)
+ else
+ icon_state = "m_[icon_state]"
flipped = !flipped
return
@@ -307,8 +312,6 @@
if ((pipe_type in list (PIPE_SIMPLE_BENT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_BENT, PIPE_HE_BENT, PIPE_INSULATED_BENT)) \
&& (src.dir in cardinal))
src.dir = src.dir|turn(src.dir, 90)
- else if ((pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER)) && flipped)
- src.dir = turn(src.dir, 45+90)
else if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_SUPPLY_STRAIGHT, PIPE_SCRUBBERS_STRAIGHT, PIPE_UNIVERSAL, PIPE_HE_STRAIGHT, PIPE_INSULATED_STRAIGHT, PIPE_MVALVE, PIPE_DVALVE))
if(dir==2)
dir = 1
@@ -354,8 +357,11 @@
return dir|flip|cw|acw
if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD)
return flip|cw|acw
- if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_MTVALVE, PIPE_DTVALVE)
- return dir|flip|cw
+ if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE)
+ if(!flipped)
+ return dir|flip|cw
+ else
+ return flip|cw|acw
if(PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP)
return dir
return 0
@@ -506,28 +512,21 @@
V.name = pipename
V.construction(dir, get_pdir(), color)
- if(PIPE_MTVALVE)
- var/obj/machinery/atmospherics/trinary/tvalve/V = new( src.loc )
- if (pipename)
- V.name = pipename
- V.construction(dir, pipe_dir, color)
-
- if(PIPE_DTVALVE)
- var/obj/machinery/atmospherics/trinary/tvalve/digital/V = new( src.loc )
- if (pipename)
- V.name = pipename
- V.construction(dir, pipe_dir, color)
-
if(PIPE_PUMP) //gas pump
var/obj/machinery/atmospherics/binary/pump/P = new(src.loc)
P.construction(dir, pipe_dir, color)
- if(PIPE_GAS_FILTER, PIPE_GAS_MIXER)
+ if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE)
var/obj/machinery/atmospherics/trinary/P
- if(pipe_type == PIPE_GAS_FILTER)
- P = new /obj/machinery/atmospherics/trinary/filter(src.loc)
- else if(pipe_type == PIPE_GAS_MIXER)
- P = new /obj/machinery/atmospherics/trinary/mixer(src.loc)
+ switch(pipe_type)
+ if(PIPE_GAS_FILTER)
+ P = new /obj/machinery/atmospherics/trinary/filter(src.loc)
+ if(PIPE_GAS_MIXER)
+ P = new /obj/machinery/atmospherics/trinary/mixer(src.loc)
+ if(PIPE_TVALVE)
+ P = new /obj/machinery/atmospherics/trinary/tvalve(src.loc)
+ if(PIPE_DTVALVE)
+ P = new /obj/machinery/atmospherics/trinary/tvalve/digital(src.loc)
P.flipped = flipped
if (pipename)
P.name = pipename
@@ -666,7 +665,7 @@
#undef PIPE_PASSIVE_GATE
#undef PIPE_VOLUME_PUMP
#undef PIPE_HEAT_EXCHANGE
-#undef PIPE_MTVALVE
+#undef PIPE_TVALVE
#undef PIPE_MANIFOLD4W
#undef PIPE_CAP
#undef PIPE_OMNI_MIXER
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index b58c9a215d8..d5e1bd9d90e 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -392,6 +392,29 @@ var/list/turret_icons
attacked = 0
..()
+
+/obj/machinery/porta_turret/attack_animal(mob/living/simple_animal/M)
+ M.changeNext_move(CLICK_CD_MELEE)
+ M.do_attack_animation(src)
+ if(M.melee_damage_upper == 0)
+ return
+ if(!(stat & BROKEN))
+ visible_message("[M] [M.attacktext] [src]!")
+ take_damage(M.melee_damage_upper)
+ else
+ M << "That object is useless to you."
+ return
+
+/obj/machinery/porta_turret/attack_alien(mob/living/carbon/alien/humanoid/M)
+ M.changeNext_move(CLICK_CD_MELEE)
+ M.do_attack_animation(src)
+ if(!(stat & BROKEN))
+ playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
+ visible_message("[M] has slashed at [src]!")
+ take_damage(15)
+ else
+ M << "That object is useless to you."
+ return
/obj/machinery/porta_turret/emag_act(user as mob)
if(!emagged)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 2f2e2a9dbf8..6bb538b349f 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -27,6 +27,11 @@ var/const/SAFETY_COOLDOWN = 100
RefreshParts()
update_icon()
+/obj/machinery/recycler/Destroy()
+ qdel(materials)
+ materials = null
+ return ..()
+
/obj/machinery/recycler/RefreshParts()
var/amt_made = 0
var/mat_mod = 0
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index a1f8d2ee5fa..4aaaf47f8c7 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -177,7 +177,7 @@
var/list/L = list()
var/list/areaindex = list()
- for(var/obj/item/device/radio/beacon/R in world)
+ for(var/obj/item/device/radio/beacon/R in beacons)
var/turf/T = get_turf(R)
if (!T)
continue
@@ -192,7 +192,7 @@
areaindex[tmpname] = 1
L[tmpname] = R
- for (var/obj/item/weapon/implant/tracking/I in world)
+ for (var/obj/item/weapon/implant/tracking/I in tracking_implants)
if (!I.implanted || !ismob(I.loc))
continue
else
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 78b78c26e27..b8f0db0fefb 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -856,8 +856,8 @@
/obj/item/weapon/gun/projectile/shotgun/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1,
/obj/item/weapon/gun/projectile/shotgun = 2,/obj/item/weapon/gun/projectile/automatic/ar = 2)
premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2,/obj/item/ammo_box/magazine/m50 = 4,/obj/item/ammo_box/magazine/m45 = 2,/obj/item/ammo_box/magazine/m75 = 2)
- contraband = list(/obj/item/clothing/under/patriotsuit = 1,/obj/item/weapon/bedsheet/patriot = 3)
-
+ contraband = list(/obj/item/clothing/under/patriotsuit = 1,/obj/item/weapon/bedsheet/patriot = 3)
+
/obj/machinery/vending/cigarette
name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating
desc = "If you want to get cancer, might as well do it in style"
@@ -967,15 +967,14 @@
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
-
- products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3,
- /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3,
- /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
- /obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
- /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
- /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3,
- /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/coffeeaseed = 3, /obj/item/seeds/teaasperaseed = 3,/obj/item/seeds/peanutseed = 3)
-
+ products = list(/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/appleseed = 3,/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,
+ /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/chantermycelium = 3,
+ /obj/item/seeds/chiliseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/coffeeaseed = 3,/obj/item/seeds/cornseed = 3,
+ /obj/item/seeds/eggplantseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/lemonseed = 3,
+ /obj/item/seeds/limeseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/potatoseed = 3,/obj/item/seeds/poppyseed = 3,
+ /obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/replicapod = 3,/obj/item/seeds/riceseed = 3,/obj/item/seeds/soyaseed = 3,/obj/item/seeds/sunflowerseed = 3,
+ /obj/item/seeds/teaasperaseed = 3,/obj/item/seeds/tobaccoseed = 3,/obj/item/seeds/tomatoseed = 3,
+ /obj/item/seeds/towermycelium = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/whitebeetseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1)
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index 42837d06aba..a3ec474fb08 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -20,7 +20,7 @@
recharge_port.recharge_floor = null
recharge_port = null
recharging_mecha = null
- ..()
+ return ..()
/turf/simulated/floor/mech_bay_recharge_floor/Entered(var/obj/mecha/mecha)
. = ..()
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 576442ac902..3eba9cc2132 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -73,6 +73,7 @@
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
name = "DEATH-RIPLEY"
icon_state = "deathripley"
+ initial_icon = "deathripley"
step_in = 2
opacity=0
max_temperature = 65000
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 80ee405c026..24fd10d631d 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -45,6 +45,7 @@
var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
var/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ var/armour_penetration = 0 //percentage of armour effectiveness to remove
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers.
diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm
index 678cf8c057a..47e88049b65 100644
--- a/code/game/objects/items/devices/pipe_painter.dm
+++ b/code/game/objects/items/devices/pipe_painter.dm
@@ -20,13 +20,13 @@
var/turf/T = P.loc
if (P.level < 2 && T.level==1 && isturf(T) && T.intact)
- user << "\red You must remove the plating first."
+ user << "You must remove the plating first."
return
P.change_color(pipe_colors[mode])
/obj/item/device/pipe_painter/attack_self(mob/user as mob)
- mode = input("Which colour do you want to use?", "Pipe painter", mode) in modes
+ mode = input("Which colour do you want to use?", "Pipe Painter", mode) in modes
/obj/item/device/pipe_painter/examine(mob/user)
..(user)
diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm
index b85e447444c..36de16c95fa 100644
--- a/code/game/objects/items/devices/radio/beacon.dm
+++ b/code/game/objects/items/devices/radio/beacon.dm
@@ -3,11 +3,20 @@
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "signaler"
- var/code = "electronic"
+ var/code = "Beacon"
origin_tech = "bluespace=1"
var/emagged = 0
var/syndicate = 0
+/obj/item/device/radio/beacon/New()
+ ..()
+ code = "[code] ([beacons.len + 1])"
+ beacons += src
+
+/obj/item/device/radio/beacon/Destroy()
+ beacons -= src
+ return ..()
+
/obj/item/device/radio/beacon/emag_act(user as mob)
if(!emagged)
emagged = 1
@@ -21,28 +30,26 @@
/obj/item/device/radio/beacon/send_hear()
return null
-
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
- if ((usr.canmove && !( usr.restrained() )))
- src.code = t
- if (!( src.code ))
- src.code = "beacon"
+ if (usr.stat || usr.restrained())
+ return
+
+ code = t
+ if (isnull(code))
+ code = initial(code)
src.add_fingerprint(usr)
return
-
/obj/item/device/radio/beacon/bacon //Probably a better way of doing this, I'm lazy.
proc/digest_delay()
spawn(600)
qdel(src)
-
// SINGULO BEACON SPAWNER
-
/obj/item/device/radio/beacon/syndicate
name = "suspicious beacon"
desc = "A label on it reads: Activate to have a singularity beacon teleported to your location."
diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm
index d9e06c361b0..81d9a7769e5 100644
--- a/code/game/objects/items/random_items.dm
+++ b/code/game/objects/items/random_items.dm
@@ -89,7 +89,7 @@
icon = 'icons/obj/drinks.dmi'
New()
..()
- var/list/drinks_only = list("beer2","hot_coco","orangejuice","tomatojuice","limejuice","carrotjuice","berryjuice","poisonberryjuice","watermelonjuice","lemonjuice","banana","nothing","potato","milk","soymilk","cream","coffee","tea","icecoffee","icetea","cola","nuka_cola","spacemountainwind","thirteenloko","dr_gibb","space_up","lemon_lime","beer","whiskey","gin","rum","vodka","holywater","tequilla","vermouth","wine","tonic","kahlua","cognac","hooch","ale","sodawater","ice","bilk","atomicbomb","threemileisland","goldschlager","patron","gintonic","cubalibre","whiskeycola","martini","vodkamartini","whiterussian","screwdrivercocktail","booger","bloodymary","gargleblaster","bravebull","tequillasunrise","toxinsspecial","beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea","moonshine","b52","irishcoffee","margarita","blackrussian","manhattan","manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood","vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead","mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte","cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk","silencer","changelingsting","irishcarbomb","syndicatebomb","erikasurprise","driestmartini")
+ var/list/drinks_only = list("beer2","hot_coco","orangejuice","tomatojuice","limejuice","carrotjuice","berryjuice","poisonberryjuice","watermelonjuice","lemonjuice","banana","nothing","potato","milk","soymilk","cream","coffee","tea","icecoffee","icetea","cola","nuka_cola","spacemountainwind","thirteenloko","dr_gibb","space_up","lemon_lime","beer","whiskey","gin","rum","vodka","holywater","tequilla","vermouth","wine","tonic","kahlua","cognac","ale","sodawater","ice","bilk","atomicbomb","threemileisland","goldschlager","patron","gintonic","cubalibre","whiskeycola","martini","vodkamartini","whiterussian","screwdrivercocktail","booger","bloodymary","gargleblaster","bravebull","tequillasunrise","toxinsspecial","beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea","moonshine","b52","irishcoffee","margarita","blackrussian","manhattan","manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood","vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead","mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte","cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk","silencer","changelingsting","irishcarbomb","syndicatebomb","erikasurprise","driestmartini")
if(prob(50))
drinks_only += list("pancuronium","adminordrazine","lsd","omnizine","blood")
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 1a0f5ed4023..29aeace7ea7 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1350,3 +1350,68 @@ obj/item/toy/cards/deck/syndicate/black
user << "The string on [src] hasn't rewound all the way!"
return
+/obj/item/toy/russian_revolver
+ name = "russian revolver"
+ desc = "for fun and games!"
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "detective_gold"
+ item_state = "gun"
+ lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
+ flags = CONDUCT
+ slot_flags = SLOT_BELT
+ materials = list(MAT_METAL=2000)
+ w_class = 3.0
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 5
+ force = 5.0
+ origin_tech = "combat=1"
+ attack_verb = list("struck", "hit", "bashed")
+ var/bullet_position = 1
+ var/is_empty = 0
+
+/obj/item/toy/russian_revolver/suicide_act(mob/user)
+ user.visible_message("[user] quickly loads six bullets into the [src.name]'s cylinder and points it at \his head before pulling the trigger! It looks like they are trying to commit suicide.")
+ playsound(loc, 'sound/weapons/Gunshot.ogg', 50, 1)
+ return (BRUTELOSS)
+
+/obj/item/toy/russian_revolver/New()
+ spin_cylinder()
+ ..()
+
+
+/obj/item/toy/russian_revolver/attack_self(mob/user)
+ if(is_empty)
+ user.visible_message("[user] loads a bullet into the [src]'s cylinder.")
+ is_empty = 0
+ else
+ spin_cylinder()
+ user.visible_message("[user] spins the cylinder on the [src]!")
+
+
+/obj/item/toy/russian_revolver/attack(mob/living/carbon/M, mob/user)
+ if(M != user) //can't use this on other people
+ return
+ if(is_empty)
+ user << "The [src] is empty."
+ return
+ user.visible_message("[user] points the [src] at their head, ready to pull the trigger!")
+ if(do_after(user, 30, target = M))
+ if(bullet_position != 1)
+ user.visible_message("*click*")
+ playsound(src, 'sound/weapons/empty.ogg', 100, 1)
+ bullet_position -= 1
+ return
+ if(bullet_position == 1)
+ is_empty = 1
+ playsound(src, 'sound/weapons/Gunshot.ogg', 50, 1)
+ user.visible_message("The [src] goes off!")
+ M.apply_damage(200, "brute", "head", used_weapon = "Self-inflicted gunshot would to the head.", sharp=1)
+ M.death()
+ else
+ user.visible_message("[user] lowers the [src] from their head.")
+
+
+/obj/item/toy/russian_revolver/proc/spin_cylinder()
+ bullet_position = rand(1,6)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 820a3311cff..447e862c751 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -12,53 +12,60 @@
var/allow_reagents = 0
var/malfunction = 0
- proc/trigger(emote, source as mob)
- return
+/obj/item/weapon/implant/proc/trigger(emote, source as mob)
+ return
- proc/activate()
- return
+/obj/item/weapon/implant/proc/activate()
+ return
- // What does the implant do upon injection?
- // return 0 if the implant fails (ex. Revhead and loyalty implant.)
- // return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
- proc/implanted(var/mob/source)
- return 1
+// What does the implant do upon injection?
+// return 0 if the implant fails (ex. Revhead and loyalty implant.)
+// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
+/obj/item/weapon/implant/proc/implanted(var/mob/source)
+ return 1
- proc/get_data()
- return "No information available"
+/obj/item/weapon/implant/proc/get_data()
+ return "No information available"
- proc/hear(message, source as mob)
- return
+/obj/item/weapon/implant/proc/hear(message, source as mob)
+ return
- proc/islegal()
- return 0
+/obj/item/weapon/implant/proc/islegal()
+ return 1
- proc/meltdown() //breaks it down, making implant unrecongizible
- imp_in << "\red You feel something melting inside [part ? "your [part.name]" : "you"]!"
- if (part)
- part.take_damage(burn = 15, used_weapon = "Electronics meltdown")
- else
- var/mob/living/M = imp_in
- M.apply_damage(15,BURN)
- name = "melted implant"
- desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
- icon_state = "implant_melted"
- malfunction = MALFUNCTION_PERMANENT
+/obj/item/weapon/implant/proc/meltdown() //breaks it down, making implant unrecongizible
+ imp_in << "\red You feel something melting inside [part ? "your [part.name]" : "you"]!"
+ if (part)
+ part.take_damage(burn = 15, used_weapon = "Electronics meltdown")
+ else
+ var/mob/living/M = imp_in
+ M.apply_damage(15,BURN)
+ name = "melted implant"
+ desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
+ icon_state = "implant_melted"
+ malfunction = MALFUNCTION_PERMANENT
- Destroy()
- if(part)
- part.implants.Remove(src)
- return ..()
+/obj/item/weapon/implant/Destroy()
+ if(part)
+ part.implants.Remove(src)
+ return ..()
/obj/item/weapon/implant/tracking
name = "tracking"
desc = "Track with this."
origin_tech = "materials=2;magnets=2;programming=2;biotech=2"
var/id = 1.0
+
+/obj/item/weapon/implant/tracking/New()
+ ..()
+ tracking_implants += src
+
+/obj/item/weapon/implant/tracking/Destroy()
+ tracking_implants -= src
+ return ..()
-
- get_data()
- var/dat = {"Implant Specifications:
+/obj/item/weapon/implant/tracking/get_data()
+ var/dat = {"Implant Specifications:
Name: Tracking Beacon
Life: 10 minutes after death of host
Important Notes: None
@@ -72,24 +79,23 @@ disintegrate into bio-safe elements.
Integrity: Gradient creates slight risk of being overcharged and frying the
circuitry. As a result neurotoxins can cause massive damage.
Implant Specifics:
"}
- return dat
+ return dat
- emp_act(severity)
- if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
- return
- malfunction = MALFUNCTION_TEMPORARY
+/obj/item/weapon/implant/tracking/emp_act(severity)
+ if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
+ return
+ malfunction = MALFUNCTION_TEMPORARY
- var/delay = 20
- switch(severity)
- if(1)
- if(prob(60))
- meltdown()
- if(2)
- delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
-
- spawn(delay)
- malfunction--
+ var/delay = 20
+ switch(severity)
+ if(1)
+ if(prob(60))
+ meltdown()
+ if(2)
+ delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
+ spawn(delay)
+ malfunction--
/obj/item/weapon/implant/dexplosive
name = "explosive"
@@ -97,8 +103,8 @@ Implant Specifics:
"}
origin_tech = "materials=2;combat=3;biotech=4;syndicate=4"
icon_state = "implant_evil"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/dexplosive/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp RX-78 Employee Management Implant
Life: Activates upon death.
@@ -108,23 +114,22 @@ Implant Specifics:
"}
Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
Special Features: Explodes
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- trigger(emote, source as mob)
- if(emote == "deathgasp")
- src.activate("death")
- return
+/obj/item/weapon/implant/dexplosive/trigger(emote, source as mob)
+ if(emote == "deathgasp")
+ src.activate("death")
+ return
+/obj/item/weapon/implant/dexplosive/activate(var/cause)
+ if((!cause) || (!src.imp_in)) return 0
+ explosion(src, 0, 1, 3, 6)//This might be a bit much, dono will have to see.
+ if(src.imp_in)
+ src.imp_in.gib()
- activate(var/cause)
- if((!cause) || (!src.imp_in)) return 0
- explosion(src, 0, 1, 3, 6)//This might be a bit much, dono will have to see.
- if(src.imp_in)
- src.imp_in.gib()
-
- islegal()
- return 0
+/obj/item/weapon/implant/dexplosive/islegal()
+ return 0
//BS12 Explosive
/obj/item/weapon/implant/explosive
@@ -135,8 +140,8 @@ Implant Specifics:
"}
var/phrase = "supercalifragilisticexpialidocious"
icon_state = "implant_evil"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/explosive/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp RX-78 Intimidation Class Implant
Life: Activates upon codephrase.
@@ -146,112 +151,112 @@ Implant Specifics:
"}
Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
Special Features: Explodes
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- hear_talk(mob/M as mob, msg)
- hear(msg)
+/obj/item/weapon/implant/explosive/hear_talk(mob/M as mob, msg)
+ hear(msg)
+ return
+
+/obj/item/weapon/implant/explosive/hear(var/msg)
+ var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
+ msg = sanitize_simple(msg, replacechars)
+ if(findtext(msg,phrase))
+ activate()
+ qdel(src)
+
+/obj/item/weapon/implant/explosive/activate()
+ if (malfunction == MALFUNCTION_PERMANENT)
return
- hear(var/msg)
- var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
- msg = sanitize_simple(msg, replacechars)
- if(findtext(msg,phrase))
- activate()
- qdel(src)
+ var/need_gib = null
+ if(istype(imp_in, /mob/))
+ var/mob/T = imp_in
+ message_admins("Explosive implant triggered in [key_name_admin(T)]")
+ log_game("Explosive implant triggered in [key_name(T)].")
+ need_gib = 1
- activate()
- if (malfunction == MALFUNCTION_PERMANENT)
- return
-
- var/need_gib = null
- if(istype(imp_in, /mob/))
- var/mob/T = imp_in
- message_admins("Explosive implant triggered in [key_name_admin(T)]")
- log_game("Explosive implant triggered in [key_name(T)].")
- need_gib = 1
-
- if(ishuman(imp_in))
- if (elevel == "Localized Limb")
- if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste.
- imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- sleep(25)
- if (istype(part,/obj/item/organ/external/chest) || \
- istype(part,/obj/item/organ/external/groin) || \
- istype(part,/obj/item/organ/external/head))
- part.createwound(BRUISE, 60) //mangle them instead
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- qdel(src)
- else
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- part.droplimb()
- qdel(src)
- if (elevel == "Destroy Body")
- explosion(get_turf(T), -1, 0, 1, 6)
- T.gib()
- if (elevel == "Full Explosion")
- explosion(get_turf(T), 0, 1, 3, 6)
- T.gib()
-
- else
- explosion(get_turf(imp_in), 0, 1, 3, 6)
-
- if(need_gib)
- imp_in.gib()
-
- var/turf/t = get_turf(imp_in)
-
- if(t)
- t.hotspot_expose(3500,125)
-
- implanted(mob/source as mob)
- elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
- phrase = input("Choose activation phrase:") as text
- var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
- phrase = sanitize_simple(phrase, replacechars)
- usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0)
- usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
- return 1
-
- emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
- switch (severity)
- if (2.0) //Weak EMP will make implant tear limbs off.
- if (prob(50))
- small_boom()
- if (1.0) //strong EMP will melt implant either making it go off, or disarming it
- if (prob(70))
- if (prob(50))
- small_boom()
- else
- if (prob(50))
- activate() //50% chance of bye bye
- else
- meltdown() //50% chance of implant disarming
- spawn (20)
- malfunction--
-
- islegal()
- return 0
-
- proc/small_boom()
- if (ishuman(imp_in) && part)
- imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- spawn(25)
- if (ishuman(imp_in) && part)
- //No tearing off these parts since it's pretty much killing
- //and you can't replace groins
+ if(ishuman(imp_in))
+ if (elevel == "Localized Limb")
+ if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste.
+ imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ sleep(25)
if (istype(part,/obj/item/organ/external/chest) || \
istype(part,/obj/item/organ/external/groin) || \
istype(part,/obj/item/organ/external/head))
part.createwound(BRUISE, 60) //mangle them instead
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
+ qdel(src)
else
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
part.droplimb()
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- qdel(src)
+ qdel(src)
+ if (elevel == "Destroy Body")
+ explosion(get_turf(T), -1, 0, 1, 6)
+ T.gib()
+ if (elevel == "Full Explosion")
+ explosion(get_turf(T), 0, 1, 3, 6)
+ T.gib()
+
+ else
+ explosion(get_turf(imp_in), 0, 1, 3, 6)
+
+ if(need_gib)
+ imp_in.gib()
+
+ var/turf/t = get_turf(imp_in)
+
+ if(t)
+ t.hotspot_expose(3500,125)
+
+/obj/item/weapon/implant/explosive/implanted(mob/source as mob)
+ elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
+ phrase = input("Choose activation phrase:") as text
+ var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
+ phrase = sanitize_simple(phrase, replacechars)
+ usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0)
+ usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
+ return 1
+
+/obj/item/weapon/implant/explosive/emp_act(severity)
+ if (malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch (severity)
+ if (2.0) //Weak EMP will make implant tear limbs off.
+ if (prob(50))
+ small_boom()
+ if (1.0) //strong EMP will melt implant either making it go off, or disarming it
+ if (prob(70))
+ if (prob(50))
+ small_boom()
+ else
+ if (prob(50))
+ activate() //50% chance of bye bye
+ else
+ meltdown() //50% chance of implant disarming
+ spawn (20)
+ malfunction--
+
+/obj/item/weapon/implant/explosive/islegal()
+ return 0
+
+/obj/item/weapon/implant/explosive/proc/small_boom()
+ if (ishuman(imp_in) && part)
+ imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ spawn(25)
+ if (ishuman(imp_in) && part)
+ //No tearing off these parts since it's pretty much killing
+ //and you can't replace groins
+ if (istype(part,/obj/item/organ/external/chest) || \
+ istype(part,/obj/item/organ/external/groin) || \
+ istype(part,/obj/item/organ/external/head))
+ part.createwound(BRUISE, 60) //mangle them instead
+ else
+ part.droplimb()
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
+ qdel(src)
/obj/item/weapon/implant/chem
name = "chem"
@@ -259,8 +264,8 @@ Implant Specifics:
"}
origin_tech = "materials=3;biotech=4"
allow_reagents = 1
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/chem/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp MJ-420 Prisoner Management Implant
Life: Deactivates upon death but remains within the body.
@@ -275,56 +280,58 @@ the implant releases the chemicals directly into the blood stream.
Can only be loaded while still in its original case.
Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
the implant may become unstable and either pre-maturely inject the subject or simply break."}
- return dat
+ return dat
+/obj/item/weapon/implant/chem/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(50)
+ reagents = R
+ R.my_atom = src
+ tracking_implants += src
+
+/obj/item/weapon/implant/chem/Destroy()
+ tracking_implants -= src
+ return ..()
- New()
- ..()
- var/datum/reagents/R = new/datum/reagents(50)
- reagents = R
- R.my_atom = src
+/obj/item/weapon/implant/chem/trigger(emote, source as mob)
+ if(emote == "deathgasp")
+ src.activate(src.reagents.total_volume)
+ return
+/obj/item/weapon/implant/chem/activate(var/cause)
+ if((!cause) || (!src.imp_in)) return 0
+ var/mob/living/carbon/R = src.imp_in
+ src.reagents.trans_to(R, cause)
+ R << "You hear a faint *beep*."
+ if(!src.reagents.total_volume)
+ R << "You hear a faint click from your chest."
+ spawn(0)
+ qdel(src)
+ return
- trigger(emote, source as mob)
- if(emote == "deathgasp")
- src.activate(src.reagents.total_volume)
+/obj/item/weapon/implant/chem/emp_act(severity)
+ if (malfunction)
return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch(severity)
+ if(1)
+ if(prob(60))
+ activate(20)
+ if(2)
+ if(prob(30))
+ activate(5)
- activate(var/cause)
- if((!cause) || (!src.imp_in)) return 0
- var/mob/living/carbon/R = src.imp_in
- src.reagents.trans_to(R, cause)
- R << "You hear a faint *beep*."
- if(!src.reagents.total_volume)
- R << "You hear a faint click from your chest."
- spawn(0)
- qdel(src)
- return
-
- emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- switch(severity)
- if(1)
- if(prob(60))
- activate(20)
- if(2)
- if(prob(30))
- activate(5)
-
- spawn(20)
- malfunction--
+ spawn(20)
+ malfunction--
/obj/item/weapon/implant/loyalty
name = "loyalty"
desc = "Makes you loyal or such."
origin_tech = "materials=2;biotech=4;programming=4"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/loyalty/get_data()
+ var/dat = {"
Implant Specifications:
Name: Nanotrasen Employee Management Implant
Life: Ten years.
@@ -334,27 +341,27 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a small pod of nanobots that manipulate the host's mental functions.
Special Features: Will prevent and cure most forms of brainwashing.
Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
- return dat
+ return dat
- implanted(mob/M)
- if(!istype(M, /mob/living/carbon/human)) return 0
- var/mob/living/carbon/human/H = M
- if(H.mind in ticker.mode.head_revolutionaries)
- H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!")
- return 0
- else if(H.mind in ticker.mode:revolutionaries)
- ticker.mode:remove_revolutionary(H.mind)
- H << "You feel a surge of loyalty towards Nanotrasen."
- return 1
+/obj/item/weapon/implant/loyalty/implanted(mob/M)
+ if(!istype(M, /mob/living/carbon/human)) return 0
+ var/mob/living/carbon/human/H = M
+ if(H.mind in ticker.mode.head_revolutionaries)
+ H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!")
+ return 0
+ else if(H.mind in ticker.mode:revolutionaries)
+ ticker.mode:remove_revolutionary(H.mind)
+ H << "You feel a surge of loyalty towards Nanotrasen."
+ return 1
/obj/item/weapon/implant/traitor
name = "Mindslave Implant"
desc = "Divide and Conquer"
icon_state = "implant_evil"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/traitor/get_data()
+ var/dat = {"
Implant Specifications:
Name: Mind-Slave Implant
Life: ???
@@ -364,50 +371,53 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a small pod of nanobots that manipulate the host's mental functions.
Special Features: Diplomacy was never so easy.
Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
- return dat
+ return dat
- implanted(mob/M, mob/user)
- var/list/implanters
- var/ref = "\ref[user.mind]"
- if(!ishuman(M)) return 0
- if(!M.mind) return 0
- var/mob/living/carbon/human/H = M
- if(M == user)
- user << "Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot."
- if(isliving(user))
- var/mob/living/L = user
- L.adjustBrainLoss(20)
- return
- if(locate(/obj/item/weapon/implant/loyalty) in H.contents)
- H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
- return 0
- if(locate(/obj/item/weapon/implant/traitor) in H.contents)
- H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
- return 0
- H.implanting = 1
- H << "You feel completely loyal to [user.name]."
- if(!(user.mind in ticker.mode:implanter))
- ticker.mode:implanter[ref] = list()
- implanters = ticker.mode:implanter[ref]
- implanters.Add(H.mind)
- ticker.mode.implanted.Add(H.mind)
- ticker.mode.implanted[H.mind] = user.mind
- //ticker.mode:implanter[user.mind] += H.mind
- ticker.mode:implanter[ref] = implanters
- ticker.mode.traitors += H.mind
- H.mind.special_role = "traitor"
- H << "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost."
- var/datum/objective/protect/p = new
- p.owner = H.mind
- p.target = user:mind
- p.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]."
- H.mind.objectives += p
- for(var/datum/objective/objective in H.mind.objectives)
- H << "Objective #1: [objective.explanation_text]"
- ticker.mode.update_traitor_icons_added(H.mind)
- ticker.mode.update_traitor_icons_added(user.mind)
- log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].")
- return 1
+/obj/item/weapon/implant/traitor/implanted(mob/M, mob/user)
+ var/list/implanters
+ var/ref = "\ref[user.mind]"
+ if(!ishuman(M)) return 0
+ if(!M.mind) return 0
+ var/mob/living/carbon/human/H = M
+ if(M == user)
+ user << "Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot."
+ if(isliving(user))
+ var/mob/living/L = user
+ L.adjustBrainLoss(20)
+ return
+ if(locate(/obj/item/weapon/implant/loyalty) in H.contents)
+ H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
+ return 0
+ if(locate(/obj/item/weapon/implant/traitor) in H.contents)
+ H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
+ return 0
+ H.implanting = 1
+ H << "You feel completely loyal to [user.name]."
+ if(!(user.mind in ticker.mode:implanter))
+ ticker.mode:implanter[ref] = list()
+ implanters = ticker.mode:implanter[ref]
+ implanters.Add(H.mind)
+ ticker.mode.implanted.Add(H.mind)
+ ticker.mode.implanted[H.mind] = user.mind
+ //ticker.mode:implanter[user.mind] += H.mind
+ ticker.mode:implanter[ref] = implanters
+ ticker.mode.traitors += H.mind
+ H.mind.special_role = "traitor"
+ H << "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost."
+ var/datum/objective/protect/p = new
+ p.owner = H.mind
+ p.target = user:mind
+ p.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]."
+ H.mind.objectives += p
+ for(var/datum/objective/objective in H.mind.objectives)
+ H << "Objective #1: [objective.explanation_text]"
+ ticker.mode.update_traitor_icons_added(H.mind)
+ ticker.mode.update_traitor_icons_added(user.mind)
+ log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].")
+ return 1
+
+/obj/item/weapon/implant/traitor/islegal()
+ return 0
/obj/item/weapon/implant/adrenalin
name = "adrenalin"
@@ -415,8 +425,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
origin_tech = "materials=2;biotech=4;combat=3;syndicate=4"
var/uses = 3
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/adrenalin/get_data()
+ var/dat = {"
Implant Specifications:
Name: Cybersun Industries Adrenalin Implant
Life: Five days.
@@ -426,41 +436,38 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Removes stuns, increases speed, and has a mild healing effect.
Special Features: Will prevent and cure most forms of brainwashing.
Integrity: Implant can only be used three times before the nanobots are depleted."}
- return dat
+ return dat
+/obj/item/weapon/implant/adrenalin/trigger(emote, mob/source as mob)
+ if (src.uses < 1) return 0
+ if (emote == "pale")
+ src.uses--
+ source << "\blue You feel a sudden surge of energy!"
+ source.SetStunned(0)
+ source.SetWeakened(0)
+ source.SetParalysis(0)
+ imp_in.adjustStaminaLoss(-75)
+ source.lying = 0
+ source.update_canmove()
- trigger(emote, mob/source as mob)
- if (src.uses < 1) return 0
- if (emote == "pale")
- src.uses--
- source << "\blue You feel a sudden surge of energy!"
- source.SetStunned(0)
- source.SetWeakened(0)
- source.SetParalysis(0)
- imp_in.adjustStaminaLoss(-75)
- source.lying = 0
- source.update_canmove()
+ source.reagents.add_reagent("synaptizine", 10)
+ source.reagents.add_reagent("omnizine", 10)
+ source.reagents.add_reagent("stimulative_agent", 10)
- source.reagents.add_reagent("synaptizine", 10)
- source.reagents.add_reagent("omnizine", 10)
- source.reagents.add_reagent("stimulative_agent", 10)
-
- return
-
-
- implanted(mob/source)
- source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0)
- source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate."
- return 1
+ return
+/obj/item/weapon/implant/adrenalin/implanted(mob/source)
+ source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0)
+ source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate."
+ return 1
/obj/item/weapon/implant/death_alarm
name = "death alarm implant"
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
var/mobname = "Will Robinson"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/death_alarm/get_data()
+ var/dat = {"
Implant Specifications:
Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
Life: Activates upon death.
@@ -470,61 +477,61 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
Special Features: Alerts crew to crewmember death.
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- process()
- if (!implanted) return
- var/mob/M = imp_in
+/obj/item/weapon/implant/death_alarm/process()
+ if (!implanted) return
+ var/mob/M = imp_in
- if(isnull(M)) // If the mob got gibbed
- activate()
- else if(M.stat == 2)
- activate("death")
+ if(isnull(M)) // If the mob got gibbed
+ activate()
+ else if(M.stat == 2)
+ activate("death")
- activate(var/cause)
- var/mob/M = imp_in
- var/area/t = get_area(M)
- switch (cause)
- if("death")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
- //give the syndies a bit of stealth
- a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm")
- else
- a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm")
- qdel(a)
- processing_objects.Remove(src)
- if ("emp")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- var/name = prob(50) ? t.name : pick(teleportlocs)
- a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm")
- qdel(a)
+/obj/item/weapon/implant/death_alarm/activate(var/cause)
+ var/mob/M = imp_in
+ var/area/t = get_area(M)
+ switch (cause)
+ if("death")
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
+ if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
+ //give the syndies a bit of stealth
+ a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm")
else
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
- qdel(a)
- processing_objects.Remove(src)
-
- emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
- if (malfunction) //so I'm just going to add a meltdown chance here
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- activate("emp") //let's shout that this dude is dead
- if(severity == 1)
- if(prob(40)) //small chance of obvious meltdown
- meltdown()
- else if (prob(60)) //but more likely it will just quietly die
- malfunction = MALFUNCTION_PERMANENT
+ a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm")
+ qdel(a)
+ processing_objects.Remove(src)
+ if ("emp")
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
+ var/name = prob(50) ? t.name : pick(teleportlocs)
+ a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm")
+ qdel(a)
+ else
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
+ a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
+ qdel(a)
processing_objects.Remove(src)
- spawn(20)
- malfunction--
+/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
+ if (malfunction) //so I'm just going to add a meltdown chance here
+ return
+ malfunction = MALFUNCTION_TEMPORARY
- implanted(mob/source as mob)
- mobname = source.real_name
- processing_objects.Add(src)
- return 1
+ activate("emp") //let's shout that this dude is dead
+ if(severity == 1)
+ if(prob(40)) //small chance of obvious meltdown
+ meltdown()
+ else if (prob(60)) //but more likely it will just quietly die
+ malfunction = MALFUNCTION_PERMANENT
+ processing_objects.Remove(src)
+
+ spawn(20)
+ malfunction--
+
+/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob)
+ mobname = source.real_name
+ processing_objects.Add(src)
+ return 1
/obj/item/weapon/implant/compressed
name = "compressed matter implant"
@@ -534,8 +541,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
var/activation_emote = "sigh"
var/obj/item/scanned = null
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/compressed/get_data()
+ var/dat = {"
Implant Specifications:
Name: Nanotrasen \"Profit Margin\" Class Employee Lifesign Sensor
Life: Activates upon death.
@@ -545,40 +552,39 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
Special Features: Alerts crew to crewmember death.
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- trigger(emote, mob/source as mob)
- if (src.scanned == null)
- return 0
-
- if (emote == src.activation_emote)
- source << "The air glows as \the [src.scanned.name] uncompresses."
- activate()
-
- activate()
- var/turf/t = get_turf(src)
- if (imp_in)
- imp_in.put_in_hands(scanned)
- else
- scanned.loc = t
- qdel(src)
-
- implanted(mob/source as mob)
- src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- if (source.mind)
- source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
- source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
- return 1
-
- islegal()
+/obj/item/weapon/implant/compressed/trigger(emote, mob/source as mob)
+ if (src.scanned == null)
return 0
+ if (emote == src.activation_emote)
+ source << "The air glows as \the [src.scanned.name] uncompresses."
+ activate()
+
+/obj/item/weapon/implant/compressed/activate()
+ var/turf/t = get_turf(src)
+ if (imp_in)
+ imp_in.put_in_hands(scanned)
+ else
+ scanned.loc = t
+ qdel(src)
+
+/obj/item/weapon/implant/compressed/implanted(mob/source as mob)
+ src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
+ if (source.mind)
+ source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
+ source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
+ return 1
+
+/obj/item/weapon/implant/compressed/islegal()
+ return 0
+
/obj/item/weapon/implant/cortical
name = "cortical stack"
desc = "A fist-sized mass of biocircuits and chips."
icon_state = "implant_evil"
-
/obj/item/weapon/implant/emp
name = "emp implant"
desc = "Triggers an EMP."
@@ -599,6 +605,6 @@ the implant may become unstable and either pre-maturely inject the subject or si
return
/obj/item/weapon/implant/emp/implanted(mob/living/carbon/source)
- source.mind.store_memory("EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
- source << "The implanted EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
- return 1
\ No newline at end of file
+ source.mind.store_memory("EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
+ source << "The implanted EMP implant can be activated [uses] time\s by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm
index b589c68eea7..f5e281bbb32 100644
--- a/code/game/objects/items/weapons/implants/implantpad.dm
+++ b/code/game/objects/items/weapons/implants/implantpad.dm
@@ -10,89 +10,100 @@
throw_range = 5
w_class = 2.0
var/obj/item/weapon/implantcase/case = null
- var/broadcasting = null
- var/listening = 1.0
- proc
- update()
+
+/obj/item/weapon/implantpad/Destroy()
+ if(case)
+ dropcase()
+ return ..()
-
- update()
- if (src.case)
- src.icon_state = "implantpad-1"
- else
- src.icon_state = "implantpad-0"
+/obj/item/weapon/implantpad/update_icon()
+ if(case)
+ src.icon_state = "implantpad-1"
+ else
+ src.icon_state = "implantpad-0"
+ return
+
+/obj/item/weapon/implantpad/proc/addcase(mob/user as mob, obj/item/weapon/implantcase/C as obj)
+ if(!user || !C)
return
-
-
- attack_hand(mob/user as mob)
- if ((src.case && (user.l_hand == src || user.r_hand == src)))
- user.put_in_active_hand(case)
-
- src.case.add_fingerprint(user)
- src.case = null
-
- src.add_fingerprint(user)
- update()
- else
- return ..()
+ if(case)
+ user << "There's already an implant in the pad!"
return
-
-
- attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob, params)
- ..()
- if(istype(C, /obj/item/weapon/implantcase))
- if(!( src.case ))
- user.drop_item()
- C.loc = src
- src.case = C
- else
+ user.unEquip(C)
+ C.forceMove(src)
+ case = C
+ update_icon()
+
+/obj/item/weapon/implantpad/proc/dropcase(mob/user as mob)
+ if(!case)
+ user << "There's no implant in the pad!"
+ return
+ if(user)
+ if(user.put_in_hands(case))
+ add_fingerprint(user)
+ case.add_fingerprint(user)
+ case = null
+ update_icon()
return
- src.update()
+
+ case.forceMove(get_turf(src))
+ case = null
+ update_icon()
+
+/obj/item/weapon/implantpad/verb/remove_implant()
+ set category = "Object"
+ set name = "Remove Implant"
+ set src in view(1)
+
+ if (usr.stat || usr.restrained())
return
+
+ dropcase(usr)
+/obj/item/weapon/implantpad/attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob, params)
+ if(istype(C, /obj/item/weapon/implantcase))
+ addcase(user, C)
+ else
+ return ..()
- attack_self(mob/user as mob)
- user.set_machine(src)
- var/dat = "Implant Mini-Computer:
"
- if (src.case)
- if(src.case.imp)
- if(istype(src.case.imp, /obj/item/weapon/implant))
- dat += src.case.imp.get_data()
- if(istype(src.case.imp, /obj/item/weapon/implant/tracking))
- dat += {"ID (1-100):
- -
- - [case.imp:id]
- +
- +
"}
- else
- dat += "The implant casing is empty."
+/obj/item/weapon/implantpad/attack_self(mob/user as mob)
+ add_fingerprint(user)
+ user.set_machine(src)
+ var/dat = "Implant Mini-Computer:
"
+ if (case)
+ if(case.imp)
+ if(istype(case.imp, /obj/item/weapon/implant))
+ dat += "Remove Case
"
+ dat += case.imp.get_data()
+ if(istype(case.imp, /obj/item/weapon/implant/tracking))
+ var/obj/item/weapon/implant/tracking/T = case.imp
+ dat += {"ID (1-100):
+ -
+ - [T.id]
+ +
+ +
"}
else
- dat += "Please insert an implant casing!"
- user << browse(dat, "window=implantpad")
- onclose(user, "implantpad")
- return
+ dat += "The implant casing is empty."
+ else
+ dat += "Please insert an implant casing!"
+ user << browse(dat, "window=implantpad")
+ onclose(user, "implantpad")
+ return
- Topic(href, href_list)
- ..()
- if (usr.stat)
- return
- if ((usr.contents.Find(src)) || ((in_range(src, usr) && istype(src.loc, /turf))))
- usr.set_machine(src)
- if (href_list["tracking_id"])
- var/obj/item/weapon/implant/tracking/T = src.case.imp
- T.id += text2num(href_list["tracking_id"])
- T.id = min(100, T.id)
- T.id = max(1, T.id)
+/obj/item/weapon/implantpad/Topic(href, href_list)
+ if(..())
+ return 1
- if (istype(src.loc, /mob))
- attack_self(src.loc)
- else
- for(var/mob/M in viewers(1, src))
- if (M.client)
- src.attack_self(M)
- src.add_fingerprint(usr)
- else
- usr << browse(null, "window=implantpad")
- return
- return
+ var/mob/living/user = usr
+ if (href_list["tracking_id"])
+ if(case && case.imp)
+ var/obj/item/weapon/implant/tracking/T = case.imp
+ T.id += text2num(href_list["tracking_id"])
+ T.id = min(100, T.id)
+ T.id = max(1, T.id)
+ else if(href_list["removecase"])
+ dropcase(user)
+
+ attack_self(user)
+ return 1
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 5b99f645368..637e882bdbb 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -25,9 +25,9 @@
origin_tech = "magnets=1"
/obj/item/weapon/locator/attack_self(mob/user as mob)
- user.set_machine(src)
+ add_fingerprint(usr)
var/dat
- if (src.temp)
+ if (temp)
dat = "[src.temp]
Clear"
else
dat = {"
@@ -44,80 +44,49 @@ Frequency:
return
/obj/item/weapon/locator/Topic(href, href_list)
- ..()
- if (usr.stat || usr.restrained())
- return
+ if(..())
+ return 1
+
var/turf/current_location = get_turf(usr)//What turf is the user on?
- if(!current_location||(current_location.z in config.admin_levels))//If turf was not found or they're on z level 2.
- usr << "The [src] is malfunctioning."
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
- usr.set_machine(src)
- if (href_list["refresh"])
- src.temp = "Persistent Signal Locator
"
- var/turf/sr = get_turf(src)
+ if(!current_location ||( current_location.z in config.admin_levels))//If turf was not found or they're on z level 2.
+ usr << "\The [src] is malfunctioning."
+ return 1
+
+ if (href_list["refresh"])
+ temp = "Persistent Signal Locator
"
+ var/turf/sr = get_turf(src)
- if (sr)
- src.temp += "Located Beacons:
"
+ if (sr)
+ temp += "Located Beacons:
"
- for(var/obj/item/device/radio/beacon/W in world)
- if (W.frequency == src.frequency)
- var/turf/tr = get_turf(W)
- if (tr.z == sr.z && tr)
- var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
- if (direct < 5)
- direct = "very strong"
- else
- if (direct < 10)
- direct = "strong"
- else
- if (direct < 20)
- direct = "weak"
- else
- direct = "very weak"
- src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]
"
+ for(var/obj/item/device/radio/beacon/W in beacons)
+ if (W.frequency == frequency && !W.syndicate)
+ if (W && W.z == z)
+ var/turf/TB = get_turf(W)
+ temp += "[W.code]: [TB.x], [TB.y], [TB.z]
"
- src.temp += "Extranneous Signals:
"
- for (var/obj/item/weapon/implant/tracking/W in world)
- if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc)))
- continue
- else
- var/mob/M = W.loc
- if (M.stat == 2)
- if (M.timeofdeath + 6000 < world.time)
- continue
+ temp += "Located Implants:
"
+ for (var/obj/item/weapon/implant/tracking/T in tracking_implants)
+ if (!T.implanted || !T.imp_in)
+ continue
- var/turf/tr = get_turf(W)
- if (tr.z == sr.z && tr)
- var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
- if (direct < 20)
- if (direct < 5)
- direct = "very strong"
- else
- if (direct < 10)
- direct = "strong"
- else
- direct = "weak"
- src.temp += "[W.id]-[dir2text(get_dir(sr, tr))]-[direct]
"
+ if (T && T.z == z)
+ temp += "[T.id]: [T.imp_in.x], [T.imp_in.y], [T.imp_in.z]
"
- src.temp += "You are at \[[sr.x],[sr.y],[sr.z]\] in orbital coordinates.
Refresh
"
- else
- src.temp += "Processing Error: Unable to locate orbital position.
"
+ temp += "You are at \[[sr.x],[sr.y],[sr.z]\]."
+ temp += "
Refresh
"
else
- if (href_list["freq"])
- src.frequency += text2num(href_list["freq"])
- src.frequency = sanitize_frequency(src.frequency)
- else
- if (href_list["temp"])
- src.temp = null
- if (istype(src.loc, /mob))
- attack_self(src.loc)
+ temp += "Processing error: Unable to locate orbital position.
"
+ else
+ if (href_list["freq"])
+ frequency += text2num(href_list["freq"])
+ frequency = sanitize_frequency(frequency)
else
- for(var/mob/M in viewers(1, src))
- if (M.client)
- src.attack_self(M)
- return
+ if (href_list["temp"])
+ temp = null
+ attack_self(usr)
+ return 1
/*
* Hand-tele
@@ -171,5 +140,5 @@ Frequency:
P.creator = src
try_move_adjacent(P)
active_portals++
- src.add_fingerprint(user)
+ add_fingerprint(user)
return
diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index 3d3adcf9339..43a21f795f9 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -21,7 +21,8 @@
/datum/song/Destroy()
instrumentObj = null
- return ..()
+ ..()
+ return QDEL_HINT_QUEUE
// note is a number from 1-7 for A-G
// acc is either "b", "n", or "#"
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index 2c427d62e40..7960132730e 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -153,6 +153,7 @@ var/list/mechtoys = list(
var/points_per_intel = 250 //points gained per intel returned
var/points_per_design = 25 //points gained per max reliability research design returned (only for initilally unreliable designs)
+ var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies
var/list/techLevels = list()
var/list/researchDesigns = list()
//control
@@ -260,6 +261,18 @@ var/list/mechtoys = list(
points += points_per_design
researchDesigns += design.id
+ // Sell exotic plants
+ if(istype(A, /obj/item/seeds))
+ var/obj/item/seeds/S = A
+ if(discoveredPlants[S.type]) // This species has already been sent to CentComm
+ var/potDiff = S.seed.get_trait(TRAIT_POTENCY) - discoveredPlants[S.type] // Compare it to the previous best
+ if(potDiff > 0) // This sample is better
+ discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY)
+ points += potDiff
+ else // This is a new discovery!
+ discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY)
+ points += S.seed.get_trait(TRAIT_RARITY) // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
+
// If you send something in a crate, centcom's keeping it! - fixes secure crates being sent to centom to open them
qdel(A)
qdel(MA)
@@ -753,4 +766,4 @@ var/list/mechtoys = list(
status_signal.transmission_method = 1
status_signal.data["command"] = command
- frequency.post_signal(src, status_signal)
+ frequency.post_signal(src, status_signal)
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 60fd31ae47c..26757340fc8 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -456,7 +456,6 @@ var/list/wood_icons = list("wood","wood-broken")
levelupdate()
/turf/simulated/floor/attackby(obj/item/C as obj, mob/user as mob, params)
-
if(!C || !user)
return 0
@@ -468,18 +467,18 @@ var/list/wood_icons = list("wood","wood-broken")
qdel(C)
T.state = C //fixing it by bashing it with a light bulb, fun eh?
update_icon()
- user << "\blue You replace the light bulb."
+ user << "You replace the light bulb."
else
- user << "\blue The lightbulb seems fine, no need to replace it."
+ user << "The light bulb seems fine, no need to replace it."
if(istype(C, /obj/item/weapon/crowbar) && (!(is_plating())) && (!is_catwalk()))
if(broken || burnt)
- user << "\red You remove the broken plating."
+ user << "You remove the broken plating."
else
if(is_wood_floor())
- user << "\red You forcefully pry off the planks, destroying them in the process."
+ user << "You forcefully pry off the planks, destroying them in the process."
else
- user << "\red You remove the [floor_tile.name]."
+ user << "You remove the [floor_tile.name]."
new floor_tile.type(src)
make_plating()
@@ -488,20 +487,19 @@ var/list/wood_icons = list("wood","wood-broken")
return
-
if(istype(C, /obj/item/weapon/screwdriver))
if(is_wood_floor())
if(broken || burnt)
return
else
if(is_wood_floor())
- user << "\red You unscrew the planks."
+ user << "You unscrew the planks."
new floor_tile.type(src)
make_plating()
playsound(src, 'sound/items/Screwdriver.ogg', 80, 1)
else if(is_catwalk())
if(broken) return
- user << "\red You unscrew the catwalk's rods."
+ user << "You unscrew the catwalk's rods."
new /obj/item/stack/rods(src, 2)
ReplaceWithLattice()
for(var/direction in cardinal)
@@ -516,23 +514,23 @@ var/list/wood_icons = list("wood","wood-broken")
var/obj/item/stack/rods/R = C
if (is_plating())
if (R.amount >= 2)
- user << "\blue Reinforcing the floor..."
+ user << "Reinforcing the floor..."
if(do_after(user, 30, target = src) && R && R.amount >= 2 && is_plating())
ChangeTurf(/turf/simulated/floor/engine)
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
R.use(2)
return
else
- user << "\red You need more rods."
+ user << "You need more rods."
else if (is_catwalk())
- user << "\red The entire thing is 100% rods already, it doesn't need any more."
+ user << "The entire thing is 100% rods already, it doesn't need any more."
else
- user << "\red You must remove the plating first."
+ user << "You must remove the plating first."
return
if(istype(C, /obj/item/stack/tile))
if (is_catwalk())
- user << "\red The catwalk is too primitive to support tiling."
+ user << "The catwalk is too primitive to support tiling."
if(is_plating())
if(!broken && !burnt)
var/obj/item/stack/tile/T = C
@@ -558,7 +556,7 @@ var/list/wood_icons = list("wood","wood-broken")
levelupdate()
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
else
- user << "\blue This section is too damaged to support a tile. Use a welder to fix the damage."
+ user << "This section is too damaged to support a tile. Use a welder to fix the damage."
if(istype(C, /obj/item/stack/cable_coil))
@@ -566,29 +564,29 @@ var/list/wood_icons = list("wood","wood-broken")
var/obj/item/stack/cable_coil/coil = C
coil.turf_place(src, user)
else
- user << "\red You must remove the plating first."
+ user << "You must remove the plating first."
if(istype(C, /obj/item/weapon/shovel))
if(is_grass_floor())
new /obj/item/weapon/ore/glass(src)
new /obj/item/weapon/ore/glass(src) //Make some sand if you shovel grass
- user << "\blue You shovel the grass."
+ user << "You shovel the grass."
make_plating()
else
- user << "\red You cannot shovel this."
+ user << "You cannot shovel this."
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/welder = C
if(welder.isOn() && (is_plating()))
if(broken || burnt)
if(welder.remove_fuel(0,user))
- user << "\red You fix some dents on the broken plating."
+ user << "You fix some dents on the broken plating."
playsound(src, 'sound/items/Welder.ogg', 80, 1)
icon_state = "plating"
burnt = 0
broken = 0
else
- user << "\blue You need more welding fuel to complete this task."
+ user << "You need more welding fuel to complete this task."
if(istype(C,/obj/item/pipe))
var/obj/item/pipe/V = C
@@ -597,7 +595,7 @@ var/list/wood_icons = list("wood","wood-broken")
user.visible_message( \
"[user] starts sliding [P] along \the [src].", \
- "\blue You slide [P] along \the [src].", \
+ "You slide [P] along \the [src].", \
"You hear the scrape of metal against something.")
user.drop_item()
if (P.pipe_type in list (1,3,12)) // bent pipe rotation fix see construction.dm
diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm
index a9a07026a5d..14613d4567f 100644
--- a/code/modules/admin/verbs/adminjump.dm
+++ b/code/modules/admin/verbs/adminjump.dm
@@ -13,6 +13,8 @@
for(var/turf/T in A)
if(T.density)
continue
+ if(locate(/obj/structure/grille, T)) // Quick check to not spawn in windows
+ continue
turfs.Add(T)
var/turf/T = pick_n_take(turfs)
diff --git a/code/modules/economy/Accounts_DB.dm b/code/modules/economy/Accounts_DB.dm
index 1168a3f4bb6..2eb5a487bfd 100644
--- a/code/modules/economy/Accounts_DB.dm
+++ b/code/modules/economy/Accounts_DB.dm
@@ -11,6 +11,7 @@
var/datum/money_account/detailed_account_view
var/creating_new_account = 0
var/activated = 1
+ var/const/fund_cap = 1000000
light_color = LIGHT_COLOR_GREEN
@@ -175,6 +176,10 @@
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
+
+ starting_funds = Clamp(starting_funds, 0, station_account.money) // Not authorized to put the station in debt.
+ starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap.
+
create_account(account_name, starting_funds, src)
if(starting_funds > 0)
//subtract the money
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index 9c19f780199..15ee4a1d395 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -47,6 +47,7 @@
set_trait(TRAIT_PLANT_ICON, 0) // Icon to use for the plant growing in the tray.
set_trait(TRAIT_PRODUCT_COLOUR, 0) // Colour to apply to product icon.
set_trait(TRAIT_BIOLUM_COLOUR, 0) // The colour of the plant's radiance.
+ set_trait(TRAIT_RARITY, 0) // How rare the plant is. Used for giving points to cargo when shipping off to Centcom.
set_trait(TRAIT_POTENCY, 1) // General purpose plant strength value.
set_trait(TRAIT_REQUIRES_NUTRIENTS, 1) // The plant can starve.
set_trait(TRAIT_REQUIRES_WATER, 1) // The plant can become dehydrated.
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index dd744858635..fb10cb8de10 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -33,6 +33,7 @@
set_trait(TRAIT_MATURATION,4)
set_trait(TRAIT_PRODUCTION,4)
set_trait(TRAIT_PRODUCT_COLOUR,"#00EDC6")
+ set_trait(TRAIT_RARITY,20)
/datum/seed/chili/ghost
name = "ghostchili"
@@ -49,6 +50,7 @@
set_trait(TRAIT_PRODUCTION,10)
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_PRODUCT_COLOUR,"#00EDC6")
+ set_trait(TRAIT_RARITY,20)
// Berry plants/variants.
/datum/seed/berry
@@ -90,6 +92,7 @@
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_COLOUR,"c9fa16")
+ set_trait(TRAIT_RARITY,20)
/datum/seed/berry/poison
name = "poisonberries"
@@ -103,6 +106,7 @@
/datum/seed/berry/poison/New()
..()
set_trait(TRAIT_PRODUCT_COLOUR,"#6DC961")
+ set_trait(TRAIT_RARITY,10) // Mildly poisonous berries are common in reality
/datum/seed/berry/poison/death
name = "deathberries"
@@ -117,6 +121,7 @@
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,50)
set_trait(TRAIT_PRODUCT_COLOUR,"#7A5454")
+ set_trait(TRAIT_RARITY,30)
// Nettles/variants.
/datum/seed/nettle
@@ -155,6 +160,7 @@
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_PRODUCT_COLOUR,"#8C5030")
set_trait(TRAIT_PLANT_COLOUR,"#634941")
+ set_trait(TRAIT_RARITY,10)
//Tomatoes/variants.
/datum/seed/tomato
@@ -192,6 +198,7 @@
..()
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_PRODUCT_COLOUR,"#FF0000")
+ set_trait(TRAIT_RARITY,20)
/datum/seed/tomato/killer
name = "killertomato"
@@ -206,6 +213,7 @@
..()
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_PRODUCT_COLOUR,"#A86747")
+ set_trait(TRAIT_RARITY,30)
/datum/seed/tomato/blue
name = "bluetomato"
@@ -219,6 +227,7 @@
..()
set_trait(TRAIT_PRODUCT_COLOUR,"#4D86E8")
set_trait(TRAIT_PLANT_COLOUR,"#070AAD")
+ set_trait(TRAIT_RARITY,20)
/datum/seed/tomato/blue/teleport
name = "bluespacetomato"
@@ -234,6 +243,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#00E5FF")
set_trait(TRAIT_BIOLUM,1)
set_trait(TRAIT_BIOLUM_COLOUR,"#4DA4A8")
+ set_trait(TRAIT_RARITY,50)
//Eggplants/varieties.
/datum/seed/eggplant
@@ -299,6 +309,7 @@
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_PRODUCT_COLOUR,"#FFDD00")
set_trait(TRAIT_PLANT_COLOUR,"#D6B44D")
+ set_trait(TRAIT_RARITY,40) // Alchemy!
//Ambrosia/varieties.
/datum/seed/ambrosia
@@ -330,6 +341,10 @@
kitchen_tag = "ambrosiadeus"
preset_icon = "ambrosiadeus"
+/datum/seed/ambrosia/deus/New()
+ ..()
+ set_trait(TRAIT_RARITY,40)
+
//Tobacco/varieties
/datum/seed/tobacco
name = "tobacco"
@@ -366,6 +381,7 @@
set_trait(TRAIT_POTENCY, 5)
set_trait(TRAIT_PRODUCT_COLOUR,"#A3F0AD")
set_trait(TRAIT_PLANT_COLOUR,"#2A9C61")
+ set_trait(TRAIT_RARITY,20)
//Tea/varieties
/datum/seed/teaaspera
@@ -405,6 +421,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#A3F0AD")
set_trait(TRAIT_PLANT_COLOUR,"#2A9C61")
set_trait(TRAIT_PLANT_ICON,"tree6")
+ set_trait(TRAIT_RARITY,20)
//Coffee/varieties
/datum/seed/coffeea
@@ -445,6 +462,7 @@
set_trait(TRAIT_PRODUCT_ICON,"coffee")
set_trait(TRAIT_PRODUCT_COLOUR,"#A22043")
set_trait(TRAIT_PLANT_ICON,"bush8")
+ set_trait(TRAIT_RARITY,20)
//Mushrooms/varieties.
/datum/seed/mushroom
@@ -519,6 +537,7 @@
set_trait(TRAIT_YIELD,1)
set_trait(TRAIT_PRODUCT_COLOUR,"#FAC0F2")
set_trait(TRAIT_PLANT_COLOUR,"#C4B1C2")
+ set_trait(TRAIT_RARITY,30)
/datum/seed/mushroom/hallucinogenic
name = "reishi"
@@ -594,6 +613,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#EDE8EA")
set_trait(TRAIT_PLANT_COLOUR,"#E6D8DD")
set_trait(TRAIT_PLANT_ICON,"mushroom5")
+ set_trait(TRAIT_RARITY,30)
/datum/seed/mushroom/towercap
name = "towercap"
@@ -631,6 +651,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#DDFAB6")
set_trait(TRAIT_PLANT_COLOUR,"#EFFF8A")
set_trait(TRAIT_PLANT_ICON,"mushroom7")
+ set_trait(TRAIT_RARITY,20)
/datum/seed/mushroom/plastic
name = "plastic"
@@ -716,6 +737,7 @@
set_trait(TRAIT_PRODUCT_ICON,"flower2")
set_trait(TRAIT_PRODUCT_COLOUR,"#B5ABDD")
set_trait(TRAIT_PLANT_ICON,"flower2")
+ set_trait(TRAIT_RARITY,10)
/datum/seed/flower/novaflower
name = "novaflowers"
@@ -805,6 +827,7 @@
set_trait(TRAIT_PRODUCT_ICON,"bean")
set_trait(TRAIT_PRODUCT_COLOUR,"#EBE7C0")
set_trait(TRAIT_PLANT_ICON,"stalk")
+ set_trait(TRAIT_RARITY,20)
//Everything else
/datum/seed/peanuts
@@ -1178,6 +1201,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#96D278")
set_trait(TRAIT_PLANT_COLOUR,"#6F7A63")
set_trait(TRAIT_PLANT_ICON,"vine2")
+ set_trait(TRAIT_RARITY,30)
/datum/seed/diona
name = "diona"
diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm
index 137d724f9cd..a18ed380196 100644
--- a/code/modules/hydroponics/trays/tray_tools.dm
+++ b/code/modules/hydroponics/trays/tray_tools.dm
@@ -113,6 +113,7 @@
dat += "| Maturation time | [grown_seed.get_trait(TRAIT_MATURATION)] |
"
dat += "| Production time | [grown_seed.get_trait(TRAIT_PRODUCTION)] |
"
dat += "| Potency | [grown_seed.get_trait(TRAIT_POTENCY)] |
"
+ dat += "| Species Discovery Value | [grown_seed.get_trait(TRAIT_RARITY)] |
"
//--FalseIncarnate
//Tray-specific stats like Age and Mutation Modifier, not shown if target was not a hydroponics tray or soil
diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm
index a115b9e1672..219ec491624 100644
--- a/code/modules/mob/living/autohiss.dm
+++ b/code/modules/mob/living/autohiss.dm
@@ -73,7 +73,7 @@
/datum/species/proc/handle_autohiss(message, datum/language/lang, mode)
if(!autohiss_basic_map)
return message
- if(autohiss_exempt && (lang.name in autohiss_exempt))
+ if(autohiss_exempt && (lang && (lang.name in autohiss_exempt)))
return message
var/map = autohiss_basic_map.Copy()
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index 6265b1bdd9e..fdf2193e91b 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -62,14 +62,11 @@
/mob/living/carbon/brain/blob_act()
return
-
+
/mob/living/carbon/brain/on_forcemove(atom/newloc)
if(container)
container.loc = newloc
else //something went very wrong.
CRASH("Brainmob without container.")
- loc = container
-
-/mob/living/carbon/brain/binarycheck()
- return istype(loc, /obj/item/device/mmi/posibrain)
\ No newline at end of file
+ loc = container
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index d9e58f167cb..083ce847a52 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -25,4 +25,13 @@
if(R.radio)
spawn(0) R.radio.hear_talk(src, trim(sanitize(radio_MMI_message)), say_quote(radio_MMI_message), speaking)
- ..(message)
\ No newline at end of file
+ ..(message)
+
+/mob/living/carbon/brain/can_speak(var/datum/language/speaking)
+ if(speaking == all_languages["Robot Talk"] && istype(loc, /obj/item/device/mmi/posibrain)) //so posibrains can speak binary; less messy than adding the language
+ return 1
+
+ else return ..()
+
+/mob/living/carbon/brain/binarycheck()
+ return istype(loc, /obj/item/device/mmi/posibrain)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f588805a0d7..3b6f6b28c6a 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -285,7 +285,7 @@
while(limbs_affected != 0 && valid_limbs.len > 0)
processing_dismember = pick(valid_limbs)
if(processing_dismember.limb_name != "chest" && processing_dismember.limb_name != "head" && processing_dismember.limb_name != "groin")
- processing_dismember.droplimb(1,pick(0,1,2),0,1)
+ processing_dismember.droplimb(1,DROPLIMB_EDGE,0,1)
valid_limbs -= processing_dismember
limbs_affected -= 1
else valid_limbs -= processing_dismember
@@ -316,7 +316,7 @@
while(limbs_affected != 0 && valid_limbs.len > 0)
processing_dismember = pick(valid_limbs)
if(processing_dismember.limb_name != "chest" && processing_dismember.limb_name != "head" && processing_dismember.limb_name != "groin")
- processing_dismember.droplimb(1,pick(0,2),0,1)
+ processing_dismember.droplimb(1,DROPLIMB_EDGE,0,1)
valid_limbs -= processing_dismember
limbs_affected -= 1
else valid_limbs -= processing_dismember
@@ -341,7 +341,7 @@
while(limbs_affected != 0 && valid_limbs.len > 0)
processing_dismember = pick(valid_limbs)
if(processing_dismember.limb_name != "chest" && processing_dismember.limb_name != "head" && processing_dismember.limb_name != "groin")
- processing_dismember.droplimb(1,1,0,1)
+ processing_dismember.droplimb(1,DROPLIMB_EDGE,0,1)
valid_limbs -= processing_dismember
limbs_affected -= 1
else valid_limbs -= processing_dismember
@@ -1780,9 +1780,8 @@
prot["head"] = max(1 - I.permeability_coefficient, prot["head"])
var/protection = (prot["head"] + prot["arms"] + prot["feet"] + prot["legs"] + prot["groin"] + prot["chest"] + prot["hands"])/7
return protection
-
+
/mob/living/carbon/human/proc/get_full_print()
if(!dna || !dna.uni_identity)
return
return md5(dna.uni_identity)
-
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 3036d0252a8..39f526cb39b 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -262,7 +262,7 @@ emp_act
else
visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]!")
- var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].")
+ var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", armour_penetration = I.armour_penetration)
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
if ((weapon_sharp || weapon_edge) && prob(getarmor(user.zone_sel.selecting, "melee")))
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index 3ba7ade2e25..5b0c7813ef3 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -2,150 +2,25 @@
/mob/living/carbon/human/whisper(message as text)
var/alt_name = ""
- message = trim_strip_html_properly(message)
- log_whisper("[src.name]/[src.key] : [message]")
-
- if (src.client)
- if (src.client.prefs.muted & MUTE_IC)
- src << "\red You cannot whisper (muted)."
- return
-
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
-
- if (src.stat == 2)
- return src.say_dead(message)
-
- if (src.stat)
- return
-
if(name != GetVoice())
alt_name = "(as [get_id_name("Unknown")])"
+ message = trim_strip_html_properly(message) //bit of duplicate code, acceptable because the workaround would be annoying
+
//parse the language code and consume it
var/datum/language/speaking = parse_language(message)
- if (speaking)
- message = copytext(message,2+length(speaking.key))
-
- whisper_say(message, speaking, alt_name)
-
-
-//This is used by both the whisper verb and human/say() to handle whispering
-/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
-
- if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
- src << "You're muzzled and cannot speak!"
- return
-
- var/message_range = 1
- var/eavesdropping_range = 2
- var/watching_range = 5
- var/italics = 1
-
- var/not_heard //the message displayed to people who could not hear the whispering
- if (speaking)
- if (speaking.whisper_verb)
- verb = speaking.whisper_verb
- not_heard = "[verb] something"
- else
- var/adverb = pick("quietly", "softly")
- verb = "[speaking.speech_verb] [adverb]"
- not_heard = "[speaking.speech_verb] something [adverb]"
+ if(speaking)
+ message = copytext(message, 2 + length(speaking.key))
else
- not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null
+ speaking = get_default_language()
- message = capitalize(trim(message))
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking && (speaking.flags & HIVEMIND))
+ speaking.broadcast(src,trim(message))
+ return 1
- if(speech_problem_flag)
- var/list/handle_r = handle_speech_problems(message)
- message = handle_r[1]
- verb = handle_r[2]
- if(verb == "yells loudly")
- verb = "slurs emphatically"
- else
- var/adverb = pick("quietly", "softly")
- verb = "[verb] [adverb]"
+ message = trim_left(message)
+ message = handle_autohiss(message, speaking)
- speech_problem_flag = handle_r[3]
-
- if(!message || message=="")
- return
-
- //looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems?
- /*var/voice_sub
- for(var/obj/item/gear in list(wear_mask,wear_suit,head))
- if(!gear)
- continue
- var/obj/item/voice_changer/changer = locate() in gear
- if(changer && changer.active && changer.voice)
- voice_sub = changer.voice
-
- if(voice_sub == "Unknown")
- if(copytext(message, 1, 2) != "*")
- var/list/temp_message = text2list(message, " ")
- var/list/pick_list = list()
- for(var/i = 1, i <= temp_message.len, i++)
- pick_list += i
- for(var/i=1, i <= abs(temp_message.len/3), i++)
- var/H = pick(pick_list)
- if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
- temp_message[H] = ninjaspeak(temp_message[H])
- pick_list -= H
- message = list2text(temp_message, " ")
- message = replacetext(message, "o", "�")
- message = replacetext(message, "p", "�")
- message = replacetext(message, "l", "�")
- message = replacetext(message, "s", "�")
- message = replacetext(message, "u", "�")
- message = replacetext(message, "b", "�")*/
-
- var/list/listening = hearers(message_range, src)
- listening |= src
-
- //ghosts
- for (var/mob/M in dead_mob_list) //does this include players who joined as observers as well?
- if (!(M.client))
- continue
- if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
- listening |= M
-
- //Pass whispers on to anything inside the immediate listeners.
- for(var/mob/L in listening)
- for(var/mob/C in L.contents)
- if(istype(C,/mob/living))
- listening += C
-
- //pass on the message to objects that can hear us.
- for (var/obj/O in view(message_range, src))
- spawn (0)
- if (O)
- O.hear_talk(src, message, verb, speaking)
-
- var/list/eavesdropping = hearers(eavesdropping_range, src)
- eavesdropping -= src
- eavesdropping -= listening
-
- var/list/watching = hearers(watching_range, src)
- watching -= src
- watching -= listening
- watching -= eavesdropping
-
- //now mobs
- var/speech_bubble_test = say_test(message)
- var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
- spawn(30) qdel(speech_bubble)
-
- for(var/mob/M in listening)
- M << speech_bubble
- M.hear_say(message, verb, speaking, alt_name, italics, src)
-
- if (eavesdropping.len)
- var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
- for(var/mob/M in eavesdropping)
- M << speech_bubble
- M.hear_say(new_message, verb, speaking, alt_name, italics, src)
-
- if (watching.len)
- var/rendered = "[src.name] [not_heard]."
- for (var/mob/M in watching)
- M.show_message(rendered, 2)
+ whisper_say(message, speaking, alt_name)
\ No newline at end of file
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 15a9f473212..f606f4a16bc 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -311,6 +311,10 @@
if (C.legcuffed && !initial(C.legcuffed))
C.unEquip(C.legcuffed)
C.legcuffed = initial(C.legcuffed)
+ if(C.reagents)
+ for(var/datum/reagent/R in C.reagents.reagent_list)
+ C.reagents.clear_reagents()
+ C.reagents.addiction_list.Cut()
hud_updateflag |= 1 << HEALTH_HUD
hud_updateflag |= 1 << STATUS_HUD
@@ -322,10 +326,16 @@
setCloneLoss(0)
setBrainLoss(0)
setStaminaLoss(0)
+ SetSleeping(0)
setHalLoss(0)
SetParalysis(0)
SetStunned(0)
SetWeakened(0)
+ losebreath = 0
+ dizziness = 0
+ jitteriness = 0
+ confused = 0
+ drowsyness = 0
radiation = 0
nutrition = 400
bodytemperature = 310
@@ -337,6 +347,7 @@
ear_deaf = 0
ear_damage = 0
heal_overall_damage(1000, 1000)
+ ExtinguishMob()
fire_stacks = 0
on_fire = 0
suiciding = 0
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 5737aad1c6c..07fa3470a66 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -10,8 +10,16 @@
1 - halfblock
2 - fullblock
*/
-/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/absorb_text = null, var/soften_text = null)
+/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/absorb_text = null, var/soften_text = null, armour_penetration, penetrated_text)
var/armor = getarmor(def_zone, attack_flag)
+
+ //the if "armor" check is because this is used for everything on /living, including humans
+ if(armor && armor < 100 && armour_penetration) // Armor with 100+ protection can not be penetrated for admin items
+ armor = max(0, armor - armour_penetration)
+ if(penetrated_text)
+ src << "[penetrated_text]"
+ else
+ src << "Your armor was penetrated!"
if(armor >= 100)
if(absorb_text)
@@ -42,7 +50,7 @@
Stun(2)
//Armor
- var/armor = run_armor_check(def_zone, P.flag)
+ var/armor = run_armor_check(def_zone, P.flag, armour_penetration = P.armour_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.flag)))
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 1dfba41b225..437f9882a99 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -76,9 +76,6 @@ proc/get_radio_key_from_channel(var/channel)
verb = pick("yells","roars","hollers")
speech_problem_flag = 1
- if(COMIC in mutations)
- message = "[message]"
-
if(slurring)
message = slur(message)
verb = "slurs"
@@ -88,12 +85,19 @@ proc/get_radio_key_from_channel(var/channel)
verb = "stammers"
speech_problem_flag = 1
+ if(COMIC in mutations)
+ message = "[message]"
+
returns[1] = message
returns[2] = verb
returns[3] = speech_problem_flag
return returns
/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ switch(message_mode)
+ if("whisper") //all mobs can whisper by default
+ whisper_say(message, speaking, alt_name)
+ return 1
return 0
/mob/living/proc/handle_speech_sound()
@@ -291,4 +295,127 @@ proc/get_radio_key_from_channel(var/channel)
else //everything else failed, emote is probably invalid
if(act == "help") return //except help, because help is handled individually
- src << "\blue Unusable emote '[act]'. Say *help for a list."
\ No newline at end of file
+ src << "\blue Unusable emote '[act]'. Say *help for a list."
+
+/mob/living/whisper(message as text)
+ message = trim_strip_html_properly(message)
+
+ //parse the language code and consume it
+ var/datum/language/speaking = parse_language(message)
+ if(speaking)
+ message = copytext(message, 2 + length(speaking.key))
+ else
+ speaking = get_default_language()
+
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking && (speaking.flags & HIVEMIND))
+ speaking.broadcast(src,trim(message))
+ return 1
+
+ message = trim_left(message)
+ message = handle_autohiss(message, speaking)
+
+ whisper_say(message, speaking)
+
+/mob/living/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "You cannot speak in IC (Muted)."
+ return
+
+ if(stat)
+ if(stat == 2)
+ return say_dead(message)
+ return
+
+ if(is_muzzled())
+ src << "You're muzzled and cannot speak!"
+ return
+
+ var/message_range = 1
+ var/eavesdropping_range = 2
+ var/watching_range = 5
+ var/italics = 1
+
+ var/not_heard //the message displayed to people who could not hear the whispering
+ if(speaking)
+ if(speaking.whisper_verb)
+ verb = speaking.whisper_verb
+ not_heard = "[verb] something"
+ else
+ var/adverb = pick("quietly", "softly")
+ verb = "[speaking.speech_verb] [adverb]"
+ not_heard = "[speaking.speech_verb] something [adverb]"
+ else
+ not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null
+
+ message = trim(message)
+
+ var/speech_problem_flag = 0
+ var/list/handle_s = handle_speech_problems(message, verb)
+ message = handle_s[1]
+ verb = handle_s[2]
+ speech_problem_flag = handle_s[3]
+ if(verb == "yells loudly")
+ verb = "slurs emphatically"
+ else if(speech_problem_flag)
+ var/adverb = pick("quietly", "softly")
+ verb = "[verb] [adverb]"
+
+ if(!message || message=="")
+ return
+
+ var/list/listening = hearers(message_range, src)
+ listening |= src
+
+ //ghosts
+ for(var/mob/M in dead_mob_list) //does this include players who joined as observers as well?
+ if(!M.client)
+ continue
+ if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
+ listening |= M
+
+ //Pass whispers on to anything inside the immediate listeners.
+ for(var/mob/L in listening)
+ for(var/mob/C in L.contents)
+ if(istype(C,/mob/living))
+ listening += C
+
+ //pass on the message to objects that can hear us.
+ for(var/obj/O in view(message_range, src))
+ spawn(0)
+ if(O)
+ O.hear_talk(src, message, verb, speaking)
+
+ var/list/eavesdropping = hearers(eavesdropping_range, src)
+ eavesdropping -= src
+ eavesdropping -= listening
+
+ var/list/watching = hearers(watching_range, src)
+ watching -= src
+ watching -= listening
+ watching -= eavesdropping
+
+ //now mobs
+ var/speech_bubble_test = say_test(message)
+ var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
+ spawn(30) qdel(speech_bubble)
+
+ for(var/mob/M in listening)
+ M << speech_bubble
+ M.hear_say(message, verb, speaking, alt_name, italics, src)
+
+ if(eavesdropping.len)
+ var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
+ for(var/mob/M in eavesdropping)
+ M << speech_bubble
+ M.hear_say(new_message, verb, speaking, alt_name, italics, src)
+
+ if(watching.len)
+ var/rendered = "[src.name] [not_heard]."
+ for (var/mob/M in watching)
+ M.show_message(rendered, 2)
+
+ log_whisper("[src.name]/[src.key] : [message]")
+ return 1
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
index 40f0119c996..b08e9c32145 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -37,4 +37,8 @@
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "[src] transmits, \"[message]\""
return 1
- return ..(message, 0)
\ No newline at end of file
+ return ..(message, 0)
+
+/mob/living/silicon/robot/drone/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers")
+ say(message) //drones do not get to whisper, only speak normally
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 4e209b5343e..bcbcb1632f4 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,8 +1,11 @@
/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
log_say("[key_name(src)] : [message]")
+ if(..())
+ return 1
/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode)
if(!is_component_functioning("radio"))
src << "Your radio isn't functional at this time."
@@ -12,7 +15,8 @@
return radio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode == "department")
return holopad_talk(message, verb, speaking)
else if(message_mode)
@@ -24,7 +28,8 @@
return aiRadio.talk_into(src,message,message_mode,verb,speaking)
/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
- ..()
+ if(..())
+ return 1
if(message_mode)
if(message_mode == "general")
message_mode = null
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 41536e6bf9e..cc4aafb64e8 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -2,7 +2,7 @@
/mob/proc/say()
return
-/mob/verb/whisper()
+/mob/verb/whisper(message as text)
set name = "Whisper"
set category = "IC"
return
@@ -35,7 +35,7 @@
set_typing_indicator(0)
if(use_me)
- usr.emote("me",usr.emote_type,message)
+ custom_emote(usr.emote_type, message)
else
usr.emote(message)
diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm
index ff56a80858b..309136dcba0 100644
--- a/code/modules/ninja/energy_katana.dm
+++ b/code/modules/ninja/energy_katana.dm
@@ -5,6 +5,7 @@
item_state = "energy_katana"
force = 40
throwforce = 20
+ armour_penetration = 15
var/cooldown = 0 // Because spam aint cool, yo.
var/datum/effect/effect/system/spark_spread/spark_system
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 50a64fccb71..0ac35dd1455 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -70,7 +70,7 @@
user << "\red You must hold \the [P] steady to burn \the [src]."
/obj/item/weapon/photo/examine(mob/user)
- if(..(user, 1))
+ if(..(user, 1) || isobserver(user))
show(user)
else
user << "It is too far away."
diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm
index 1fe2737d31b..29d8af7a12f 100644
--- a/code/modules/power/powernet.dm
+++ b/code/modules/power/powernet.dm
@@ -29,7 +29,8 @@
M.powernet = null
powernets -= src
- return ..()
+ ..()
+ return QDEL_HINT_QUEUE
//Returns the amount of excess power (before refunding to SMESs) from last tick.
//This is for machines that might adjust their power consumption using this data.
@@ -51,7 +52,7 @@
cables -= C
C.powernet = null
if(is_empty())//the powernet is now empty...
- del(src)///... delete it - qdel
+ qdel(src)///... delete it - qdel
//add a cable to the current powernet
//Warning : this proc DON'T check if the cable exists
@@ -71,7 +72,7 @@
nodes -=M
M.powernet = null
if(is_empty())//the powernet is now empty...
- del(src)///... delete it - qdel
+ qdel(src)///... delete it - qdel
//add a power machine to the current powernet
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index 647ac2b105b..8117ff8441c 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -24,7 +24,21 @@
desc = "A 9mm bullet casing."
caliber = "9mm"
projectile_type = "/obj/item/projectile/bullet/weakbullet3"
+
+/obj/item/ammo_casing/c9mmap
+ desc = "A 9mm bullet casing."
+ caliber = "9mm"
+ projectile_type =/obj/item/projectile/bullet/armourpiercing
+/obj/item/ammo_casing/c9mmtox
+ desc = "A 9mm bullet casing."
+ caliber = "9mm"
+ projectile_type = /obj/item/projectile/bullet/toxinbullet
+
+/obj/item/ammo_casing/c9mminc
+ desc = "A 9mm bullet casing."
+ caliber = "9mm"
+ projectile_type = /obj/item/projectile/bullet/incendiary/firebullet
/obj/item/ammo_casing/c45
desc = "A .45 bullet casing."
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index e47acf7521e..d84b9e9dc75 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -132,11 +132,23 @@
icon_state = "smg9mm"
ammo_type = "/obj/item/ammo_casing/c9mm"
caliber = "9mm"
- max_ammo = 20
+ max_ammo = 30
+
+/obj/item/ammo_box/magazine/smgm9mm/ap
+ name = "SMG magazine (Armour Piercing 9mm)"
+ ammo_type = /obj/item/ammo_casing/c9mmap
+
+/obj/item/ammo_box/magazine/smgm9mm/toxin
+ name = "SMG magazine (Toxin Tipped 9mm)"
+ ammo_type = /obj/item/ammo_casing/c9mmtox
+
+/obj/item/ammo_box/magazine/smgm9mm/fire
+ name = "SMG Magazine (Incendiary 9mm)"
+ ammo_type = /obj/item/ammo_casing/c9mminc
/obj/item/ammo_box/magazine/smgm9mm/update_icon()
..()
- icon_state = "[initial(icon_state)]-[round(ammo_count(),5)]"
+ icon_state = "[initial(icon_state)]-[round(ammo_count(),6)]"
/obj/item/ammo_box/magazine/smgm45
name = "SMG magazine (.45)"
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 63e1d384a4d..e23c8653667 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -27,6 +27,18 @@
/obj/item/projectile/bullet/weakbullet3
damage = 20
+
+
+/obj/item/projectile/bullet/toxinbullet
+ damage = 15
+ damage_type = TOX
+
+/obj/item/projectile/bullet/incendiary/firebullet
+ damage = 10
+
+/obj/item/projectile/bullet/armourpiercing
+ damage = 17
+ armour_penetration = 10
/obj/item/projectile/bullet/pellet
name = "pellet"
diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
index b02289784a6..0cf90626ccc 100644
--- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
+++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
@@ -53,7 +53,7 @@
var/mob/living/carbon/human/H = target
var/headarmor = 0 // Target's head armour
- armor_block = H.run_armor_check(affecting, "melee") // For normal attack damage
+ armor_block = H.run_armor_check(affecting, "melee", armour_penetration = armour_penetration) // For normal attack damage
//If they have a hat/helmet and the user is targeting their head.
if(istype(H.head, /obj/item/clothing/head) && affecting == "head")
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 545e22d0822..5c4ed5c4299 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -126,13 +126,34 @@
/datum/design/mag_smg
name = "Saber Submachine Gun Magazine (9mm)"
- desc = "A 20-round magazine for the Saber submachine gun."
+ desc = "A 30-round magazine for the Saber submachine gun."
id = "mag_smg"
req_tech = list("combat" = 4, "materials" = 3)
build_type = PROTOLATHE
materials = list(MAT_METAL = 2000)
build_path = /obj/item/ammo_box/magazine/smgm9mm
category = list("Weapons")
+
+/datum/design/mag_smg/ap_mag
+ name = "Saber Submachine Gun Magazine (9mmAP)"
+ desc = "A 30-round armour piercing magazine for the Saber submachine gun. Deals slightly less damage but bypasses most armor."
+ id = "mag_smg_ap"
+ materials = list(MAT_METAL = 3000, MAT_SILVER = 100)
+ build_path = /obj/item/ammo_box/magazine/smgm9mm/ap
+
+/datum/design/mag_smg/incin_mag
+ name = "Saber Submachine Gun Magazine (9mmIC)"
+ desc = "A 30-round incendiary round magazine for the Saber submachine gun. Deals significantly less damage but sets the target on fire."
+ id = "mag_smg_ic"
+ materials = list(MAT_METAL = 3000, MAT_SILVER = 100, MAT_GLASS = 400)
+ build_path = /obj/item/ammo_box/magazine/smgm9mm/fire
+
+/datum/design/mag_smg/incin_tox
+ name = "Saber Submachine Gun Magazine (9mmTX)"
+ desc = "A 30-round uranium tipped round magazine for the Saber submachine gun. Deals toxin damage, but less overall damage."
+ id = "mag_smg_tx"
+ materials = list(MAT_METAL = 3000, MAT_GLASS = 200, MAT_URANIUM = 1000)
+ build_path = /obj/item/ammo_box/magazine/smgm9mm/toxin
/datum/design/rapidsyringe
name = "Rapid Syringe Gun"
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index 0bac36ea35b..ae0bfd6ce7d 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -62,6 +62,7 @@ Note: Must be placed west/left of and R&D console to function.
/obj/machinery/r_n_d/protolathe/Destroy()
qdel(materials)
+ materials = null
return ..()
/obj/machinery/r_n_d/protolathe/RefreshParts()
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 671fc9a369b..577397b70fc 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -102,8 +102,8 @@ won't update every console in existence) but it's more of a hassle to do. Also,
return return_name
/obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any).
- for(var/obj/machinery/r_n_d/D in oview(3,src))
- if(D.linked_console != null || D.disabled || D.panel_open)
+ for(var/obj/machinery/r_n_d/D in range(3,src))
+ if(!isnull(D.linked_console) || D.disabled || D.panel_open)
continue
if(istype(D, /obj/machinery/r_n_d/destructive_analyzer))
if(linked_destroy == null)
@@ -144,6 +144,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
break
/obj/machinery/computer/rdconsole/initialize()
+ ..()
SyncRDevices()
/* Instead of calling this every tick, it is only being called when needed
@@ -181,7 +182,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/Topic(href, href_list)
if(..())
- return
+ return 1
+
+ if(!allowed(usr))
+ return 1
add_fingerprint(usr)
@@ -601,7 +605,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/attack_hand(mob/user as mob)
if(..())
- return
+ return 1
+ if(!allowed(user))
+ user << "Access denied."
+ return 1
interact(user)
/obj/machinery/computer/rdconsole/interact(mob/user)
@@ -1113,15 +1120,13 @@ won't update every console in existence) but it's more of a hassle to do. Also,
name = "Robotics R&D Console"
desc = "A console used to interface with R&D tools."
id = 2
- req_access = null
- req_access_txt = "29"
+ req_access = list(access_robotics)
/obj/machinery/computer/rdconsole/mechanics
name = "Mechanics R&D Console"
desc = "A console used to interface with R&D tools."
id = 4
- req_access = null
- req_access_txt = "70"
+ req_access = list(access_mechanic)
/obj/machinery/computer/rdconsole/core
name = "Core R&D Console"
@@ -1131,4 +1136,5 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/experiment
name = "E.X.P.E.R.I-MENTOR R&D Console"
desc = "A console used to interface with R&D tools."
- id = 3
\ No newline at end of file
+ id = 3
+
\ No newline at end of file
diff --git a/code/modules/surgery/appendix.dm b/code/modules/surgery/appendix.dm
deleted file mode 100644
index 84bc1b8c7b4..00000000000
--- a/code/modules/surgery/appendix.dm
+++ /dev/null
@@ -1,89 +0,0 @@
-//Procedures in this file: Appendectomy
-//////////////////////////////////////////////////////////////////
-// APPENDECTOMY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/appendectomy/
- priority = 2
- can_infect = 1
- blood_level = 1
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (target_zone != "groin")
- return 0
- var/obj/item/organ/external/groin = target.get_organ("groin")
- if (!groin)
- return 0
- if (groin.open < 2)
- return 0
- return 1
-
-/datum/surgery_step/appendectomy/cut_appendix
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/kitchenknife = 75, \
- /obj/item/weapon/shard = 50, \
- )
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!ishuman(target))
- return 0
- return ..() && target.op_stage.appendix == 0
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts to separate [target]'s appendix from the abdominal wall with \the [tool].", \
- "You start to separate [target]'s appendix from the abdominal wall with \the [tool]." )
- target.custom_pain("The pain in your abdomen is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has separated [target]'s appendix with \the [tool]." , \
- "\blue You have separated [target]'s appendix with \the [tool].")
- target.op_stage.appendix = 1
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/groin = target.get_organ("groin")
- user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!", \
- "\red Your hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!")
- groin.createwound(CUT, 50, 1)
-
-/datum/surgery_step/appendectomy/remove_appendix
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
-
- min_duration = 60
- max_duration = 80
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.appendix == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts removing [target]'s appendix with \the [tool].", \
- "You start removing [target]'s appendix with \the [tool].")
- target.custom_pain("Someone's ripping out your bowels!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has removed [target]'s appendix with \the [tool].", \
- "\blue You have removed [target]'s appendix with \the [tool].")
- var/app = 0
- for(var/datum/disease/appendicitis/appendicitis in target.viruses)
- app = 1
- appendicitis.cure()
- target.resistances += appendicitis
- if (app)
- new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(target))
- else
- new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(target))
- target.op_stage.appendix = 2
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!", \
- "\red Your hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!")
- affected.createwound(BRUISE, 20)
diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm
deleted file mode 100644
index 3a12e06abbe..00000000000
--- a/code/modules/surgery/braincore.dm
+++ /dev/null
@@ -1,267 +0,0 @@
-//Procedures in this file: Brain extraction. Brain fixing. Slime Core extraction.
-//////////////////////////////////////////////////////////////////
-// BRAIN SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/brain/
- priority = 2
- blood_level = 1
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return target_zone == "head" && hasorgans(target)
-
-/datum/surgery_step/brain/saw_skull
- allowed_tools = list(
- /obj/item/weapon/circular_saw = 100, \
- /obj/item/weapon/hatchet = 75, \
- /obj/item/weapon/melee/arm_blade = 60 // Dr. Chang E. Ling, MD
- )
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target_zone == "head" && target.brain_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] begins to cut through [target]'s skull with \the [tool].", \
- "You begin to cut through [target]'s skull with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has cut through [target]'s skull open with \the [tool].", \
- "\blue You have cut through [target]'s skull open with \the [tool].")
- target.brain_op_stage = 2
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cracking [target]'s skull with \the [tool]!" , \
- "\red Your hand slips, cracking [target]'s skull with \the [tool]!" )
- target.apply_damage(max(10, tool.force), BRUTE, "head")
-
-/datum/surgery_step/brain/cut_brain
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/kitchenknife = 75, \
- /obj/item/weapon/shard = 50, \
- )
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts separating connections to [target]'s brain with \the [tool].", \
- "You start separating connections to [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] separates connections to [target]'s brain with \the [tool].", \
- "\blue You separate connections to [target]'s brain with \the [tool].")
- target.brain_op_stage = 3
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
- "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(50, BRUTE, "head", 1, sharp=1)
-
-/datum/surgery_step/brain/saw_spine
- allowed_tools = list(
- /obj/item/weapon/circular_saw = 100, \
- /obj/item/weapon/hatchet = 75, \
- /obj/item/weapon/melee/arm_blade = 60
- )
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts separating [target]'s brain from \his spine with \the [tool].", \
- "You start separating [target]'s brain from spine with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] separates [target]'s brain from \his spine with \the [tool].", \
- "\blue You separate [target]'s brain from spine with \the [tool].")
-
- var/mob/living/simple_animal/borer/borer = target.has_brain_worms()
-
- if(borer)
- borer.detatch() //Should remove borer if the brain is removed - RR
-
- user.attack_log += "\[[time_stamp()]\] Debrained [key_name(target)] with [tool.name] (INTENT: [uppertext(user.a_intent)])"
- target.attack_log += "\[[time_stamp()]\] Debrained by [key_name(user)] with [tool.name] (INTENT: [uppertext(user.a_intent)])"
- msg_admin_attack("[key_name_admin(user)] debrained [key_name_admin(target)] with [tool.name]")
-
- var/obj/item/organ/brain/B = target.internal_organs_by_name["brain"]
- if(B && istype(B))
- B.removed(user)
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
- "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(30, BRUTE, "head", 1, sharp=1)
- if (ishuman(user))
- user:bloody_body(target)
- user:bloody_hands(target, 0)
-
-
-//////////////////////////////////////////////////////////////////
-// BRAIN DAMAGE FIXING //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/brain/bone_chips
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts taking out bone chips and out of [target]'s brain with \the [tool].", \
- "You start taking out bone chips and out of [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] takes out all bone chips out of [target]'s brain with \the [tool].", \
- "\blue You take out all bone chips out of [target]'s brain with \the [tool].")
- target.brain_op_stage = 3
-
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \
- "\red Your hand slips, jabbing \the [tool] in [target]'s brain!")
- target.apply_damage(30, BRUTE, "head", 1, sharp=1)
-
-/datum/surgery_step/brain/hematoma
- allowed_tools = list(
- /obj/item/weapon/FixOVein = 100, \
- /obj/item/stack/cable_coil = 75
- )
-
- min_duration = 90
- max_duration = 110
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending hematoma in [target]'s brain with \the [tool].", \
- "You start mending hematoma in [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \
- "\blue You mend hematoma in [target]'s brain with \the [tool].")
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- if (sponge)
- sponge.damage = 0
-
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \
- "\red Your hand slips, bruising [target]'s brain with \the [tool]!")
- target.apply_damage(20, BRUTE, "head", 1, sharp=1)
-
-//////////////////////////////////////////////////////////////////
-// SLIME CORE EXTRACTION //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/slime
- is_valid_target(mob/living/carbon/slime/target)
- return istype(target, /mob/living/carbon/slime/)
-
- can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return target.stat == 2
-
-/datum/surgery_step/slime/cut_flesh
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/kitchenknife = 75, \
- /obj/item/weapon/shard = 50, \
- )
-
- min_duration = 30
- max_duration = 50
-
- can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 0
-
- begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting [target]'s flesh with \the [tool].", \
- "You start cutting [target]'s flesh with \the [tool].")
-
- end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] cuts [target]'s flesh with \the [tool].", \
- "\blue You cut [target]'s flesh with \the [tool], exposing the cores")
- target.brain_op_stage = 1
-
- fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \
- "\red Your hand slips, tearing [target]'s flesh with \the [tool]!")
-
-/datum/surgery_step/slime/cut_innards
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/kitchenknife = 75, \
- /obj/item/weapon/shard = 50, \
- )
-
- min_duration = 30
- max_duration = 50
-
- can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \
- "You start cutting [target]'s silky innards apart with \the [tool].")
-
- end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] cuts [target]'s innards apart with \the [tool], exposing the cores", \
- "\blue You cut [target]'s innards apart with \the [tool], exposing the cores")
- target.brain_op_stage = 2
-
- fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \
- "\red Your hand slips, tearing [target]'s innards with \the [tool]!")
-
-/datum/surgery_step/slime/saw_core
- allowed_tools = list(
- /obj/item/weapon/circular_saw = 100, \
- /obj/item/weapon/hatchet = 75
- )
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 2 && target.cores > 0
-
- begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \
- "You start cutting out one of [target]'s cores with \the [tool].")
-
- end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- target.cores--
- user.visible_message("\blue [user] cuts out one of [target]'s cores with \the [tool].",, \
- "\blue You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.")
-
- if(target.cores >= 0)
- new target.coretype(target.loc)
- if(target.cores <= 0)
- target.icon_state = "[target.colour] baby slime dead-nocore"
-
-
- fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, failing to cut core out!", \
- "\red Your hand slips, failing to cut core out!")
diff --git a/code/modules/surgery/brainrepair.dm b/code/modules/surgery/brainrepair.dm
deleted file mode 100644
index 60fdffe31d2..00000000000
--- a/code/modules/surgery/brainrepair.dm
+++ /dev/null
@@ -1,70 +0,0 @@
-//////////////////////////////////////////////////////////////////
-// BRAIN DAMAGE FIXING //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/brain/bone_chips
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
-
- priority = 3
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- return (sponge && sponge.damage > 0 && sponge.damage <= 20) && affected.open == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts taking bone chips out of [target]'s brain with \the [tool].", \
- "You start taking bone chips out of [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] takes out all the bone chips in [target]'s brain with \the [tool].", \
- "\blue You take out all the bone chips in [target]'s brain with \the [tool].")
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- if (sponge)
- sponge.damage = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \
- "\red Your hand slips, jabbing \the [tool] in [target]'s brain!")
- target.apply_damage(30, BRUTE, "head", 1, sharp=1)
-
-/datum/surgery_step/brain/hematoma
- allowed_tools = list(
- /obj/item/weapon/FixOVein = 100, \
- /obj/item/stack/cable_coil = 75
- )
-
- priority = 3
- min_duration = 90
- max_duration = 110
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- if(!affected) return
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- return (sponge && sponge.damage > 20) && affected.open == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending hematoma in [target]'s brain with \the [tool].", \
- "You start mending hematoma in [target]'s brain with \the [tool].")
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends hematoma in [target]'s brain with \the [tool].", \
- "\blue You mend hematoma in [target]'s brain with \the [tool].")
- var/obj/item/organ/brain/sponge = target.internal_organs_by_name["brain"]
- if (sponge)
- sponge.damage = 20
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \
- "\red Your hand slips, bruising [target]'s brain with \the [tool]!")
- target.apply_damage(20, BRUTE, "head", 1, sharp=1)
\ No newline at end of file
diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm
deleted file mode 100644
index b5fbca08ad1..00000000000
--- a/code/modules/surgery/ribcage.dm
+++ /dev/null
@@ -1,405 +0,0 @@
-//Procedures in this file: Generic ribcage opening steps, Removing alien embryo, Fixing internal organs.
-//////////////////////////////////////////////////////////////////
-// GENERIC RIBCAGE SURGERY //
-//////////////////////////////////////////////////////////////////
-/datum/surgery_step/ribcage
- priority = 2
- can_infect = 1
- blood_level = 1
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return target_zone == "chest"
-
-/datum/surgery_step/ribcage/saw_ribcage
- allowed_tools = list(
- /obj/item/weapon/circular_saw = 100, \
- /obj/item/weapon/hatchet = 75, \
- /obj/item/weapon/melee/arm_blade = 60
- )
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!ishuman(target))
- return 0
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && target.op_stage.ribcage == 0 && affected.open >= 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] begins to cut through [target]'s ribcage with \the [tool].", \
- "You begin to cut through [target]'s ribcage with \the [tool].")
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has cut through [target]'s ribcage open with \the [tool].", \
- "\blue You have cut through [target]'s ribcage open with \the [tool].")
- target.op_stage.ribcage = 1
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cracking [target]'s ribcage with \the [tool]!" , \
- "\red Your hand slips, cracking [target]'s ribcage with \the [tool]!" )
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- affected.createwound(CUT, 20)
- affected.fracture()
-
-
-/datum/surgery_step/ribcage/retract_ribcage
- allowed_tools = list(
- /obj/item/weapon/retractor = 100, \
- /obj/item/weapon/crowbar = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.ribcage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to force open the ribcage in [target]'s torso with \the [tool]."
- var/self_msg = "You start to force open the ribcage in [target]'s torso with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] forces open [target]'s ribcage with \the [tool]."
- var/self_msg = "\blue You force open [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.op_stage.ribcage = 2
-
- // Whoops!
- if(prob(10))
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- affected.fracture()
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\red [user]'s hand slips, breaking [target]'s ribcage!"
- var/self_msg = "\red Your hand slips, breaking [target]'s ribcage!"
- user.visible_message(msg, self_msg)
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- affected.createwound(BRUISE, 20)
- affected.fracture()
-
-/datum/surgery_step/ribcage/close_ribcage
- allowed_tools = list(
- /obj/item/weapon/retractor = 100, \
- /obj/item/weapon/crowbar = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
-
-
- min_duration = 20
- max_duration = 40
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.ribcage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts bending [target]'s ribcage back into place with \the [tool]."
- var/self_msg = "You start bending [target]'s ribcage back into place with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] bends [target]'s ribcage back into place with \the [tool]."
- var/self_msg = "\blue You bend [target]'s ribcage back into place with \the [tool]."
- user.visible_message(msg, self_msg)
-
- target.op_stage.ribcage = 1
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\red [user]'s hand slips, bending [target]'s ribcage in a wrong shape!"
- var/self_msg = "\red Your hand slips, bending [target]'s ribcage in a wrong shape!"
- user.visible_message(msg, self_msg)
- var/obj/item/organ/external/chest/affected = target.get_organ("chest")
- affected.createwound(BRUISE, 20)
- affected.fracture()
- if (prob(40))
- user.visible_message("\red Rib pierces the lung!")
- target.rupture_lung()
-
-/datum/surgery_step/ribcage/mend_ribcage
- allowed_tools = list(
- /obj/item/weapon/bonegel = 100, \
- /obj/item/weapon/screwdriver = 75
- )
-
- min_duration = 20
- max_duration = 40
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.ribcage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts applying \the [tool] to [target]'s ribcage."
- var/self_msg = "You start applying \the [tool] to [target]'s ribcage."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] applied \the [tool] to [target]'s ribcage."
- var/self_msg = "\blue You applied \the [tool] to [target]'s ribcage."
- user.visible_message(msg, self_msg)
-
- target.op_stage.ribcage = 0
-
-//////////////////////////////////////////////////////////////////
-// ALIEN EMBRYO SURGERY //
-//////////////////////////////////////////////////////////////////
-/datum/surgery_step/ribcage/remove_embryo
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/kitchen/utensil/fork = 20
- )
- blood_level = 2
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/embryo = 0
- for(var/obj/item/alien_embryo/A in target)
- embryo = 1
- break
- return ..() && embryo && target.op_stage.ribcage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
- var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user] rips the larva out of [target]'s ribcage!",
- "You rip the larva out of [target]'s ribcage!")
-
- for(var/obj/item/alien_embryo/A in target)
- A.loc = A.loc.loc
-
-//////////////////////////////////////////////////////////////////
-// CHEST INTERNAL ORGAN SURGERY //
-//////////////////////////////////////////////////////////////////
-/datum/surgery_step/ribcage/fix_chest_internal
- allowed_tools = list(
- /obj/item/stack/medical/advanced/bruise_pack= 100, \
- /obj/item/stack/medical/bruise_pack = 20, \
- /obj/item/stack/medical/bruise_pack/tajaran = 70, \
- )
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!ishuman(target))
- return 0
- var/is_chest_organ_damaged = 0
- var/obj/item/organ/external/chest/chest = target.get_organ("chest")
- for(var/obj/item/organ/I in chest.internal_organs)
- if(I.damage > 0)
- is_chest_organ_damaged = 1
- break
- return ..() && is_chest_organ_damaged && target.op_stage.ribcage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
- var/obj/item/organ/internal/lungs/lungs = target.internal_organs_by_name["lungs"]
- var/obj/item/organ/internal/liver/liver = target.internal_organs_by_name["liver"]
- var/obj/item/organ/internal/liver/kidney = target.internal_organs_by_name["kidney"]
-
- if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack))
- if(lungs.damage > 0)
- user.visible_message("[user] starts sealing the rupture in [target]'s lungs with regenerative membrane.", \
- "You start mending the rupture in [target]'s lungs with regenerative membrane." )
- if(heart.damage > 0)
- if(!heart.desc == "Mechanical")
- user.visible_message("[user] starts mending the bruises on [target]'s heart with regenerative membrane.", \
- "You start mending the bruises on [target]'s heart with regenerative membrane." )
- else
- user.visible_message("\blue [user] attempts to repair [target]'s mechanical heart with regenerative membrane...", \
- "\blue You attempt to repair [target]'s heart with regenerative membrane...")
- if(liver.damage > 0)
- user.visible_message("[user] starts mending the bruises on [target]'s liver with regenerative membrane.", \
- "You start mending the bruises on [target]'s liver with regenerative membrane." )
- if(kidney.damage > 0)
- user.visible_message("[user] starts mending the bruises on [target]'s kidney with regenerative membrane.", \
- "You start mending the bruises on [target]'s kidney with regenerative membrane." )
- if (istype(tool, /obj/item/stack/medical/bruise_pack))
- if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran/))
- if(lungs.damage > 0)
- user.visible_message("[user] starts covering the rupture in [target]'s lungs with the poultice.", \
- "You start covering the rupture in [target]'s lungs with the poultice." )
- if(heart.damage > 0)
- if(!heart.desc == "Mechanical")
- user.visible_message("[user] starts mending the bruises on [target]'s heart with the poultice.", \
- "You start mending the bruises on [target]'s heart with the poultice." )
- else
- user.visible_message("\blue [user] attempts to repair [target]'s mechanical heart with \the [tool]...", \
- "\blue You attempt to repair [target]'s heart with \the [tool]...")
- if(liver.damage > 0)
- user.visible_message("[user] starts putting the poultice to the bruises on [target]'s liver.", \
- "You start putting the poultice to the bruises on [target]'s liver." )
- if(kidney.damage > 0)
- user.visible_message("[user] starts putting the poultice to the bruises on [target]'s kidney.", \
- "You start putting the poultice to the bruises on [target]'s kidney." )
- if(lungs.damage > 0)
- user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \
- "You start mending the rupture in [target]'s lungs \the [tool]." )
- else
- if(heart.damage > 0)
- if(!heart.desc == "Mechanical")
- user.visible_message("[user] starts mending the bruises on [target]'s heart with \the [tool].", \
- "You start mending the bruises on [target]'s heart with \the [tool]." )
- else
- user.visible_message("\blue [user] attempts to repair [target]'s mechanical heart with \the [tool]...", \
- "\blue You attempt to repair [target]'s heart with \the [tool]...")
- if(liver.damage > 0)
- user.visible_message("[user] starts mending the bruises on [target]'s liver with \the [tool].", \
- "You start mending the bruises on [target]'s liver with \the [tool]." )
- if(kidney.damage > 0)
- user.visible_message("[user] starts mending the bruises on [target]'s kidney with \the [tool].", \
- "You start mending the bruises on [target]'s kidney with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
- var/obj/item/organ/internal/lungs/lungs = target.internal_organs_by_name["lungs"]
- var/obj/item/organ/internal/liver/liver = target.internal_organs_by_name["liver"]
- var/obj/item/organ/internal/liver/kidney = target.internal_organs_by_name["kidney"]
-
- if(lungs.damage > 0)
- user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \
- "\blue You mend the rupture in [target]'s lungs with \the [tool]." )
- lungs.damage = 0
-
- if(heart.damage > 0)
- if(heart.desc == "Mechanical")
- user.visible_message("\blue [user] pokes [target]'s mechanical heart with \the [tool].", \
- "\red [target]'s heart is not organic, you cannot operate on it with \the [tool]!")
- else
- user.visible_message("\blue [user] treats the bruises on [target]'s heart with \the [tool].", \
- "\blue You treat the bruises on [target]'s heart with \the [tool]." )
- heart.damage = 0
-
- if(liver.damage > 0)
- user.visible_message("\blue [user] treats the bruises on [target]'s liver with \the [tool].", \
- "\blue You treats the bruises on [target]'s liver with \the [tool]." )
- liver.damage = 0
-
- if(kidney.damage > 0)
- user.visible_message("\blue [user] treats the bruises on [target]'s kidney with \the [tool].", \
- "\blue You treats the bruises on [target]'s kidney with \the [tool]." )
- kidney.damage = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
- var/obj/item/organ/internal/lungs/lungs = target.internal_organs_by_name["lungs"]
- var/obj/item/organ/internal/liver/liver = target.internal_organs_by_name["liver"]
- var/obj/item/organ/internal/liver/kidney = target.internal_organs_by_name["kidney"]
- var/obj/item/organ/external/chest/affected = target.get_organ("chest")
- user.visible_message("\red [user]'s hand slips, getting mess and tearing the inside of [target]'s chest with \the [tool]!", \
- "\red Your hand slips, getting mess and tearing the inside of [target]'s chest with \the [tool]!")
- switch(tool)
- if(/obj/item/stack/medical/advanced/bruise_pack)
- if(heart.damage > 0)
- heart.take_damage(2, 0)
- if(liver.damage > 0)
- liver.take_damage(2, 0)
- if(kidney.damage > 0)
- kidney.take_damage(2, 0)
- if(lungs.damage > 0)
- lungs.take_damage(2, 0)
- target.adjustToxLoss(5)
- if(/obj/item/stack/medical/bruise_pack/tajaran)
- if(heart.damage > 0)
- heart.take_damage(2, 0)
- if(liver.damage > 0)
- liver.take_damage(2, 0)
- if(kidney.damage > 0)
- kidney.take_damage(2, 0)
- if(lungs.damage > 0)
- lungs.take_damage(2, 0)
- target.adjustToxLoss(7)
- if(/obj/item/stack/medical/bruise_pack)
- if(heart.damage > 0)
- heart.take_damage(5, 0)
- if(liver.damage > 0)
- liver.take_damage(5, 0)
- if(kidney.damage > 0)
- kidney.take_damage(5, 0)
- if(lungs.damage > 0)
- lungs.take_damage(5, 0)
- target.adjustToxLoss(10)
- affected.createwound(CUT, 5)
-
-
-/datum/surgery_step/ribcage/fix_chest_internal_robot //For artificial organs
- allowed_tools = list(
- /obj/item/stack/nanopaste = 100, \
- /obj/item/weapon/bonegel = 30, \
- /obj/item/weapon/screwdriver = 70, \
- )
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/is_chest_organ_damaged = 0
- var/obj/item/organ/external/chest/chest = target.get_organ("chest")
- for(var/obj/item/organ/I in chest.internal_organs) if(I.damage > 0)
- is_chest_organ_damaged = 1
- break
- return ..() && is_chest_organ_damaged && target.op_stage.ribcage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
-
- if(heart.damage > 0)
- if(heart.desc == "Mechanical")
- user.visible_message("[user] starts mending the mechanisms on [target]'s heart with \the [tool].", \
- "You start mending the mechanisms on [target]'s heart with \the [tool]." )
- else
- user.visible_message("[user] cannot mend an organic heart with this!")
- return
- target.custom_pain("The pain in your chest is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
- if(heart.damage > 0)
- if(heart.desc == "Mechanical")
- user.visible_message("\blue [user] repairs [target]'s heart with \the [tool].", \
- "\blue You repair [target]'s heart with \the [tool]." )
- heart.damage = 0
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/organ/internal/heart/heart = target.internal_organs_by_name["heart"]
- user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s heart, gumming it up!!" , \
- "\red Your hand slips, smearing [tool] in the incision in [target]'s heart, gumming it up!")
- heart.take_damage(5, 0)
- target.adjustToxLoss(5)
-
-//////////////////////////////////////////////////////////////////
-// HEART SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/ribcage/heart/cut
- allowed_tools = list(
- /obj/item/weapon/scalpel = 100, \
- /obj/item/weapon/kitchenknife = 75, \
- /obj/item/weapon/shard = 50, \
- )
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.ribcage == 2
-
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index 3bbdbf03568..e73fea39d27 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -15,7 +15,7 @@
/datum/disease2/effectholder/proc/getrandomeffect(var/badness = 1)
var/list/datum/disease2/effect/list = list()
- for(var/e in subtypesof(/datum/disease2/effect))
+ for(var/e in subtypesof(/datum/disease2/effect) - /datum/disease2/effect/organs/vampire)
var/datum/disease2/effect/f = new e
if (f.badness > badness) //we don't want such strong effects
continue
@@ -104,6 +104,25 @@
////////////////////////STAGE 4/////////////////////////////////
+/datum/disease2/effect/borg
+ name = "Borgification Disorder"
+ stage = 4
+ badness = 2
+ activate(var/mob/living/carbon/mob,var/multiplier)
+ mob << "You feel like beeping and booping..."
+ mob.adjustBruteLoss(10)
+ mob.updatehealth()
+ if(prob(40))
+ if(mob.client)
+ if(!jobban_isbanned(mob, "Cyborg") && !jobban_isbanned(mob,"nonhumandept"))
+ var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(mob.loc))
+ mob.mind.transfer_to(O)
+ else
+ new/mob/living/silicon/robot(get_turf(mob.loc))
+ var/datum/disease2/disease/D = mob.virus2
+ mob.gib()
+ qdel(D)
+
/datum/disease2/effect/omnizine
name = "Panacea Effect"
stage = 4
diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi
index 5ba7e9decdf..b11cdc50f30 100644
Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index 7978b514703..add4c667b0b 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index c49dbe8cb59..9675d99379b 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/pipe-item.dmi b/icons/obj/pipe-item.dmi
index 06c53e5a68b..1ef48fbad13 100644
Binary files a/icons/obj/pipe-item.dmi and b/icons/obj/pipe-item.dmi differ
diff --git a/nano/templates/pai_bioscan.tmpl b/nano/templates/pai_bioscan.tmpl
index fb5d99b2286..e4dd0046371 100644
--- a/nano/templates/pai_bioscan.tmpl
+++ b/nano/templates/pai_bioscan.tmpl
@@ -13,15 +13,15 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Oxygen Content : {{:data.oxy}}
- Toxin Cotnet : {{:data.tox}}
+ Toxin Content : {{:data.tox}}
Burn Status : {{:data.burn}}
- User Temprature : {{:data.temp}}
+ User Temperature : {{:data.temp}}
{{else}}
Error: No biological host found!
-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/paradise.dme b/paradise.dme
index 61b715656c6..dba397639c5 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -25,6 +25,7 @@
#include "code\__DEFINES\game.dm"
#include "code\__DEFINES\genetics.dm"
#include "code\__DEFINES\hud.dm"
+#include "code\__DEFINES\hydroponics.dm"
#include "code\__DEFINES\language.dm"
#include "code\__DEFINES\lighting.dm"
#include "code\__DEFINES\machines.dm"
@@ -1180,7 +1181,6 @@
#include "code\modules\garbage collection\gc_testing.dm"
#include "code\modules\holiday\christmas.dm"
#include "code\modules\holiday\holiday.dm"
-#include "code\modules\hydroponics\_hydro_setup.dm"
#include "code\modules\hydroponics\grown.dm"
#include "code\modules\hydroponics\grown_inedible.dm"
#include "code\modules\hydroponics\grown_predefined.dm"
@@ -1821,9 +1821,7 @@
#include "code\modules\store\items.dm"
#include "code\modules\store\store.dm"
#include "code\modules\surgery\bones.dm"
-#include "code\modules\surgery\brainrepair.dm"
#include "code\modules\surgery\encased.dm"
-#include "code\modules\surgery\eye.dm"
#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
#include "code\modules\surgery\implant.dm"