diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm index 7e54cfe3e58..b7199a51f12 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/Delta/delta.dmm @@ -80,7 +80,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aal" = ( /turf/simulated/shuttle/wall{ @@ -128,7 +128,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aar" = ( /obj/structure/shuttle/engine/propulsion{ @@ -136,7 +136,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aas" = ( /turf/simulated/shuttle/floor{ @@ -260,7 +260,7 @@ icon_state = "burst_l"; tag = "icon-burst_l (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aaK" = ( /obj/structure/window/full/shuttle{ @@ -1021,7 +1021,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "acx" = ( /obj/structure/closet/syndicate/suits, @@ -1048,7 +1048,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/administration) "acB" = ( /turf/space, @@ -1795,7 +1795,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "aef" = ( /obj/machinery/door/airlock/external{ @@ -2782,7 +2782,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "afW" = ( /obj/structure/computerframe, @@ -2921,7 +2921,7 @@ dir = 1 }, /obj/effect/decal/warning_stripes/north, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "agl" = ( /turf/space, @@ -2998,18 +2998,18 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ags" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "agt" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-propulsion_r"; icon_state = "propulsion_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "agu" = ( /obj/structure/table, @@ -4162,7 +4162,7 @@ dir = 8; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "aja" = ( /turf/simulated/shuttle/wall{ @@ -4316,7 +4316,7 @@ dir = 8; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "ajq" = ( /obj/structure/window/reinforced{ @@ -5098,7 +5098,7 @@ dir = 8; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "akU" = ( /obj/machinery/door/airlock/external{ @@ -6301,7 +6301,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "anE" = ( /obj/structure/rack, @@ -6633,7 +6633,7 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "aol" = ( /obj/structure/rack, @@ -6889,7 +6889,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "aoP" = ( /obj/docking_port/stationary{ @@ -7279,7 +7279,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "apC" = ( /turf/space, @@ -19711,7 +19711,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "aMp" = ( /turf/space, @@ -20353,18 +20353,18 @@ tag = "icon-burst_l"; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "aNA" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "aNB" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-burst_r"; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "aNC" = ( /obj/machinery/atmospherics/unary/vent_pump{ @@ -33123,7 +33123,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/mining) "bjX" = ( /obj/structure/ore_box, @@ -34129,7 +34129,7 @@ /area/shuttle/mining) "blQ" = ( /obj/structure/shuttle/engine/propulsion/burst, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/mining) "blR" = ( /turf/space, @@ -42844,7 +42844,7 @@ dir = 1; layer = 2.9 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/siberia) "bAM" = ( /obj/structure/cable{ @@ -44196,7 +44196,7 @@ /area/shuttle/siberia) "bCG" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/siberia) "bCH" = ( /turf/space, @@ -59728,7 +59728,7 @@ req_access_txt = "63" }, /obj/structure/safe/floor{ - knownby = list("captain") + known_by = list("captain") }, /obj/item/gun/projectile/revolver/russian, /obj/item/reagent_containers/food/drinks/bottle/absinthe/premium, @@ -115065,7 +115065,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "dYf" = ( /obj/structure/window/reinforced, @@ -115074,7 +115074,7 @@ icon_state = "heater"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "dYg" = ( /obj/structure/bed/roller, @@ -115548,7 +115548,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "dYY" = ( /turf/simulated/shuttle/wall{ @@ -115735,7 +115735,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "dZs" = ( /obj/structure/shuttle/engine/propulsion{ @@ -115743,7 +115743,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "dZt" = ( /turf/space, @@ -115758,7 +115758,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "dZv" = ( /turf/simulated/shuttle/wall{ @@ -115773,7 +115773,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "dZx" = ( /obj/effect/decal/remains/human, diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index c1740c983de..1301895facd 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -921,7 +921,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "abR" = ( /obj/structure/computerframe, @@ -1030,18 +1030,18 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "acc" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "acd" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-propulsion_r"; icon_state = "propulsion_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ace" = ( /obj/structure/cable, @@ -5910,7 +5910,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "akr" = ( /obj/machinery/door/firedoor, @@ -6466,7 +6466,7 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "alm" = ( /obj/structure/closet/l3closet/security, @@ -37724,7 +37724,7 @@ /area/security/brig) "bnv" = ( /obj/structure/safe{ - knownby = list("captain") + known_by = list("captain") }, /obj/item/clothing/head/bearpelt, /obj/item/folder/documents, @@ -44634,7 +44634,7 @@ /area/crew_quarters/heads) "byk" = ( /obj/structure/safe/floor{ - knownby = list("captain") + known_by = list("captain") }, /obj/item/gun/projectile/revolver/russian, /obj/item/reagent_containers/food/drinks/bottle/absinthe/premium, @@ -92414,7 +92414,7 @@ pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/binary/pump/highcap{ +/obj/machinery/atmospherics/binary/pump{ dir = 4 }, /turf/simulated/floor/plasteel, @@ -92426,7 +92426,7 @@ /obj/structure/sign/fire{ pixel_y = -32 }, -/obj/machinery/atmospherics/binary/pump/highcap{ +/obj/machinery/atmospherics/binary/pump{ dir = 8 }, /turf/simulated/floor/plasteel, diff --git a/_maps/map_files/MetaStation/z2.dmm b/_maps/map_files/MetaStation/z2.dmm index 5533ba2af8d..50a81f6e6e8 100644 --- a/_maps/map_files/MetaStation/z2.dmm +++ b/_maps/map_files/MetaStation/z2.dmm @@ -3754,7 +3754,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (EAST)" }, -/turf/space/transit, +/turf/simulated/shuttle/plating, /area/wizard_station) "kr" = ( /obj/structure/flora/tree/pine, @@ -3769,7 +3769,7 @@ icon_state = "heater"; dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/wizard_station) "kt" = ( /obj/structure/flora/grass/brown, @@ -4627,14 +4627,14 @@ dir = 4; icon_state = "propulsion" }, -/turf/space/transit, +/turf/simulated/shuttle/plating, /area/wizard_station) "mP" = ( /obj/structure/shuttle/engine/heater{ icon_state = "heater"; dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/wizard_station) "mQ" = ( /obj/machinery/light{ @@ -5975,7 +5975,7 @@ /obj/structure/shuttle/engine/propulsion{ icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/wizard_station) "tq" = ( /obj/structure/rack, @@ -6049,7 +6049,7 @@ /area/centcom/holding) "tP" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "tQ" = ( /turf/unsimulated/beach/coastline, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm b/_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm index 8391071697d..30d5dff0b64 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm @@ -63,7 +63,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (WEST)" }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/unpowered) "m" = ( /obj/item/shard, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm b/_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm index 91bbd366b48..fd6bd8d85fe 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm @@ -27,7 +27,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered) "f" = ( /obj/structure/window/reinforced{ @@ -38,7 +38,7 @@ icon_state = "heater"; dir = 8 }, -/turf/simulated/floor/plating, +/turf/simulated/shuttle/plating, /area/ruin/powered) "g" = ( /obj/structure/table/wood, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm b/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm index 98168731154..bd53ea5a0f1 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm @@ -240,7 +240,7 @@ /area/ruin/powered) "R" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered) (1,1,1) = {" diff --git a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm index 17d88dcc3bd..28df12718e6 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm @@ -498,7 +498,7 @@ /area/ruin/unpowered) "bG" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/unpowered) "bH" = ( /turf/simulated/wall/mineral/titanium, diff --git a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm index 61be7cb48ef..8f9d8ce8133 100644 --- a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm +++ b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm @@ -1499,10 +1499,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plasteel/airless{ - tag = "icon-engine"; - icon_state = "engine" - }, +/turf/simulated/shuttle/plating, /area/awaymission/BMPship/Aft) "ec" = ( /obj/structure/shuttle/engine/propulsion{ @@ -1510,7 +1507,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/BMPship/Aft) "ed" = ( /obj/item/multitool, diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 1c466c039ed..ec655559a1c 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -8170,7 +8170,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (WEST)" }, -/turf/simulated/floor/plating/airless/asteroid, +/turf/simulated/shuttle/plating, /area/awaycontent/a1{ has_gravity = 1; name = "MO19 Arrivals" @@ -8233,9 +8233,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless{ - name = "plating" - }, +/turf/simulated/shuttle/plating, /area/awaycontent/a1{ has_gravity = 1; name = "MO19 Arrivals" @@ -8467,7 +8465,7 @@ icon_state = "burst_l"; tag = "icon-burst_l (WEST)" }, -/turf/simulated/floor/plating/airless/asteroid, +/turf/simulated/shuttle/plating, /area/awaycontent/a1{ has_gravity = 1; name = "MO19 Arrivals" diff --git a/_maps/map_files/RandomZLevels/spacebattle.dmm b/_maps/map_files/RandomZLevels/spacebattle.dmm index 675efc73e68..674c8099882 100644 --- a/_maps/map_files/RandomZLevels/spacebattle.dmm +++ b/_maps/map_files/RandomZLevels/spacebattle.dmm @@ -26,7 +26,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate2) "af" = ( /obj/structure/shuttle/engine/propulsion{ @@ -55,7 +55,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate2) "aj" = ( /turf/simulated/shuttle/floor{ @@ -147,7 +147,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate3) "ax" = ( /obj/structure/shuttle/engine/propulsion{ @@ -155,7 +155,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate3) "ay" = ( /obj/structure/shuttle/engine/propulsion{ @@ -163,7 +163,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate3) "az" = ( /turf/space, @@ -191,7 +191,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate3) "aD" = ( /turf/simulated/shuttle/floor{ @@ -282,7 +282,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate1) "aQ" = ( /obj/structure/shuttle/engine/propulsion{ @@ -290,7 +290,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate1) "aR" = ( /obj/structure/shuttle/engine/propulsion{ @@ -298,7 +298,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate1) "aS" = ( /turf/space, @@ -329,7 +329,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate1) "aX" = ( /obj/structure/window/reinforced, @@ -1927,6 +1927,17 @@ /obj/effect/decal/cleanable/blood, /turf/simulated/floor/plasteel, /area/awaymission/spacebattle/cruiser) +"gm" = ( +/obj/structure/shuttle/engine/heater{ + tag = "icon-heater (WEST)"; + icon_state = "heater"; + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) "gn" = ( /obj/structure/closet/crate/secure/weapon, /obj/item/ammo_casing/a357, @@ -2090,7 +2101,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate4) "gO" = ( /obj/structure/reagent_dispensers/beerkeg, @@ -2162,7 +2173,7 @@ /area/awaymission/spacebattle/syndicate7) "gY" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate4) "gZ" = ( /obj/item/pickaxe, @@ -2221,15 +2232,15 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate7) "hh" = ( /obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion_r (WEST)"; - icon_state = "propulsion_r"; - dir = 8 + dir = 4; + icon_state = "propulsion_l"; + tag = "icon-propulsion_l (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate7) "hi" = ( /obj/structure/largecrate, @@ -2287,14 +2298,6 @@ }, /turf/simulated/floor/plating, /area/awaymission/spacebattle/syndicate7) -"hq" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion_l (WEST)"; - icon_state = "propulsion_l"; - dir = 8 - }, -/turf/space, -/area/awaymission/spacebattle/syndicate7) "hr" = ( /obj/structure/largecrate, /mob/living/simple_animal/pet/corgi/puppy, @@ -2604,14 +2607,6 @@ /mob/living/simple_animal/hostile/syndicate/ranged, /turf/simulated/floor/plasteel, /area/awaymission/spacebattle/cruiser) -"io" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-burst_r (EAST)"; - icon_state = "burst_r"; - dir = 4 - }, -/turf/space, -/area/awaymission/spacebattle/cruiser) "ip" = ( /obj/effect/mob_spawn/human/engineer{ name = "Mercutio" @@ -2745,11 +2740,11 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/space) "iK" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "iL" = ( /obj/machinery/door/airlock/external, @@ -2775,11 +2770,11 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate5) "iP" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate5) "iQ" = ( /turf/space, @@ -2850,11 +2845,11 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate6) "jb" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/spacebattle/syndicate6) "jc" = ( /turf/simulated/floor/plating/airless/asteroid, @@ -2872,6 +2867,78 @@ /obj/machinery/door/airlock/plasma, /turf/simulated/wall/mineral/plasma, /area/awaymission/spacebattle/secret) +"nG" = ( +/obj/structure/window/reinforced, +/obj/structure/shuttle/engine/heater{ + tag = "icon-heater (NORTH)"; + icon_state = "heater"; + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) +"qC" = ( +/obj/structure/window/reinforced, +/obj/structure/shuttle/engine/heater{ + tag = "icon-heater (NORTH)"; + icon_state = "heater"; + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) +"zS" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 4; + icon_state = "propulsion_l"; + tag = "icon-propulsion_l (WEST)" + }, +/turf/simulated/shuttle/plating, +/area/space) +"Jj" = ( +/obj/structure/shuttle/engine/propulsion{ + tag = "icon-propulsion_l (NORTH)"; + icon_state = "propulsion_l"; + dir = 1 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/syndicate2) +"Jw" = ( +/obj/structure/shuttle/engine/propulsion{ + tag = "icon-propulsion_r (NORTH)"; + icon_state = "propulsion_r"; + dir = 1 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/syndicate2) +"JS" = ( +/obj/structure/shuttle/engine/propulsion{ + tag = "icon-propulsion_l (NORTH)"; + icon_state = "propulsion_l"; + dir = 1 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) +"JW" = ( +/obj/structure/shuttle/engine/propulsion{ + tag = "icon-propulsion_r (NORTH)"; + icon_state = "propulsion_r"; + dir = 1 + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) +"YV" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "burst_r"; + tag = "icon-burst_r (EAST)" + }, +/turf/simulated/shuttle/plating, +/area/awaymission/spacebattle/cruiser) (1,1,1) = {" aa @@ -21516,15 +21583,15 @@ ab ab ab bP -bU -cc -cc -cc -cc -cc -cc -cc -io +YV +YV +YV +YV +YV +YV +YV +YV +YV dq ab ab @@ -21773,15 +21840,15 @@ ab ab ab bS -bV -bV -bV -bV -bV -bV -bV -bV -bV +gm +gm +gm +gm +gm +gm +gm +gm +gm bQ ab ab @@ -36817,7 +36884,7 @@ ab ab ab ab -ad +Jw ai aj aj @@ -40158,7 +40225,7 @@ ab ab ab ab -af +Jj ai aj aj @@ -45948,7 +46015,7 @@ ab ab ab ab -iq +zS iv iv iv @@ -51555,8 +51622,8 @@ ab ab ab ab -bF -bK +JW +nG bN bN bN @@ -52326,8 +52393,8 @@ ab ab ab ab -bH -bM +JS +qC bO bO bO @@ -64175,12 +64242,12 @@ ab ab gM hh -hq +hh hz ab gM hh -hq +hh hz ab ab diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index 7f144031668..73d86c17201 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -2364,42 +2364,42 @@ /area/awaymission/spacehotel) "ev" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 110 }, /turf/unsimulated/floor/carpet, /area/awaymission/spacehotel) "ew" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 111 }, /turf/unsimulated/floor/carpet, /area/awaymission/spacehotel) "ex" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 112 }, /turf/unsimulated/floor/carpet, /area/awaymission/spacehotel) "ey" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 210 }, /turf/unsimulated/floor/carpet, /area/awaymission/spacehotel) "ez" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 211 }, /turf/unsimulated/floor/carpet, /area/awaymission/spacehotel) "eA" = ( /obj/machinery/door/unpowered/hotel_door{ - icon = 'icons/obj/doors/Doorgold.dmi'; + icon = 'icons/obj/doors/doorgold.dmi'; id = 212 }, /turf/unsimulated/floor/carpet, @@ -4712,14 +4712,14 @@ icon_state = "heater"; dir = 4 }, -/turf/unsimulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission) "kV" = ( /obj/structure/shuttle/engine/propulsion{ dir = 4; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission) "kW" = ( /turf/simulated/shuttle/wall{ @@ -4740,7 +4740,7 @@ dir = 4; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "la" = ( /obj/structure/chair{ diff --git a/_maps/map_files/RandomZLevels/stationCollision.dmm b/_maps/map_files/RandomZLevels/stationCollision.dmm index b4889b22202..a8e3a533033 100644 --- a/_maps/map_files/RandomZLevels/stationCollision.dmm +++ b/_maps/map_files/RandomZLevels/stationCollision.dmm @@ -173,11 +173,11 @@ /area/awaymission/northblock) "aI" = ( /obj/structure/shuttle/engine/propulsion{ - tag = "icon-burst_l (EAST)"; + dir = 8; icon_state = "burst_l"; - dir = 4 + tag = "icon-burst_l (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/syndishuttle) "aJ" = ( /turf/simulated/floor/plating/airless, @@ -197,14 +197,6 @@ /obj/machinery/mecha_part_fabricator/robot, /turf/simulated/floor/plasteel, /area/awaymission/northblock) -"aO" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion_r (EAST)"; - icon_state = "propulsion_r"; - dir = 4 - }, -/turf/space, -/area/awaymission/syndishuttle) "aP" = ( /obj/structure/shuttle/engine/heater{ tag = "icon-heater (WEST)"; @@ -278,16 +270,6 @@ icon_state = "floorscorched2" }, /area/awaymission/northblock) -"bd" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-burst_l (EAST)"; - icon_state = "burst_l"; - dir = 4 - }, -/turf/simulated/shuttle/wall{ - icon_state = "wall3" - }, -/area/awaymission/syndishuttle) "be" = ( /obj/structure/shuttle/engine/heater, /turf/simulated/shuttle/plating, @@ -349,16 +331,6 @@ }, /turf/simulated/floor/plasteel/airless, /area/awaymission/northblock) -"bo" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion (EAST)"; - icon_state = "propulsion"; - dir = 4 - }, -/turf/simulated/shuttle/wall{ - icon_state = "wall3" - }, -/area/awaymission/syndishuttle) "bp" = ( /obj/structure/shuttle/engine/router, /turf/simulated/shuttle/plating, @@ -554,16 +526,6 @@ /mob/living/carbon/human/monkey, /turf/simulated/floor/grass, /area/awaymission/research) -"bU" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-burst_r (EAST)"; - icon_state = "burst_r"; - dir = 4 - }, -/turf/simulated/shuttle/wall{ - icon_state = "wall3" - }, -/area/awaymission/syndishuttle) "bV" = ( /obj/structure/shuttle/engine/heater{ tag = "icon-heater (NORTH)"; @@ -775,11 +737,11 @@ /area/awaymission/research) "cy" = ( /obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion (EAST)"; - icon_state = "propulsion"; - dir = 4 + dir = 8; + icon_state = "burst_l"; + tag = "icon-burst_l (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/research) "cz" = ( /obj/structure/shuttle/engine/heater{ @@ -794,7 +756,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/research) "cA" = ( /turf/simulated/floor/plasteel{ @@ -807,14 +769,6 @@ icon_state = "dark" }, /area/awaymission/research) -"cC" = ( -/obj/structure/shuttle/engine/propulsion{ - tag = "icon-propulsion_l (EAST)"; - icon_state = "propulsion_l"; - dir = 4 - }, -/turf/space, -/area/awaymission/syndishuttle) "cD" = ( /turf/simulated/floor/plating/airless, /turf/simulated/shuttle/wall{ @@ -885,7 +839,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/research) "cL" = ( /obj/effect/decal/remains/human{ @@ -1763,7 +1717,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/research) "eI" = ( /obj/structure/window/reinforced{ @@ -3581,14 +3535,14 @@ icon_state = "propulsion_r" }, /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "je" = ( /turf/space, /area/awaymission/arrivalblock) "jf" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "jg" = ( /obj/structure/shuttle/engine/propulsion{ @@ -3604,7 +3558,7 @@ icon_state = "propulsion_l" }, /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "jh" = ( /obj/structure/cable{ @@ -4038,7 +3992,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "km" = ( /obj/structure/window/reinforced, @@ -4138,7 +4092,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "kB" = ( /obj/structure/shuttle/engine/propulsion{ @@ -4147,7 +4101,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/space, +/turf/simulated/shuttle/plating, /area/awaymission/arrivalblock) "kC" = ( /obj/machinery/suit_storage_unit/standard_unit, @@ -4737,11 +4691,11 @@ aa aa aC aC -bd -bo -bo -bo -bU +aI +aI +aI +aI +aI aC aC aa @@ -5461,7 +5415,7 @@ aa aa aC aI -aO +aI aC er eK @@ -5469,7 +5423,7 @@ eK ff ff aC -cC +aI aK aC af @@ -5535,7 +5489,7 @@ eK eX eX aC -aP +bq aJ af aj diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index a0deb25b20d..606fabcc4b5 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -84,7 +84,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aam" = ( /turf/simulated/shuttle/wall{ @@ -129,7 +129,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aas" = ( /obj/structure/shuttle/engine/heater{ @@ -140,7 +140,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aat" = ( /turf/simulated/shuttle/floor{ @@ -270,7 +270,7 @@ icon_state = "burst_l"; tag = "icon-burst_l (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/abandoned) "aaM" = ( /turf/simulated/shuttle/floor{ @@ -1299,7 +1299,7 @@ /turf/simulated/shuttle/plating/vox, /area/shuttle/vox) "ade" = ( -/obj/structure/closet/syndicate/suits, +/obj/machinery/suit_storage_unit/syndicate/secure, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -1757,12 +1757,12 @@ /turf/simulated/floor/plasteel, /area/security/range) "adS" = ( -/obj/structure/closet/syndicate/suits, /obj/machinery/light/spot{ tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8 }, +/obj/machinery/suit_storage_unit/syndicate/secure, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -3970,7 +3970,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ahz" = ( /obj/structure/computerframe, @@ -4125,18 +4125,18 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ahO" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ahP" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-propulsion_r"; icon_state = "propulsion_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate) "ahQ" = ( /obj/machinery/alarm{ @@ -5582,7 +5582,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "ajZ" = ( /obj/structure/rack, @@ -5833,7 +5833,7 @@ tag = "icon-propulsion_l"; icon_state = "propulsion_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/vox) "akq" = ( /obj/structure/rack, @@ -9292,7 +9292,7 @@ dir = 8; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/trade/sol) "aqg" = ( /obj/machinery/light/spot{ @@ -9825,7 +9825,7 @@ dir = 8; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/trade/sol) "are" = ( /obj/machinery/door/poddoor{ @@ -10418,7 +10418,7 @@ dir = 8; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/trade/sol) "arW" = ( /obj/structure/chair{ @@ -13480,7 +13480,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "awq" = ( /obj/structure/shuttle/engine/propulsion{ @@ -13488,7 +13488,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "awr" = ( /turf/space, @@ -13503,7 +13503,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "awt" = ( /turf/space, @@ -13518,7 +13518,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "awv" = ( /obj/structure/shuttle/engine/propulsion{ @@ -13526,7 +13526,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "aww" = ( /turf/space, @@ -13541,7 +13541,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "awy" = ( /obj/machinery/mineral/labor_claim_console{ @@ -13937,7 +13937,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_elite) "axk" = ( /turf/simulated/shuttle/wall{ @@ -13952,7 +13952,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/syndicate_sit) "axm" = ( /obj/structure/chair{ @@ -15266,7 +15266,7 @@ dir = 1; layer = 2.9 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/siberia) "azl" = ( /obj/machinery/atmospherics/pipe/manifold/hidden{ @@ -15845,7 +15845,7 @@ /area/shuttle/siberia) "aAk" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/siberia) "aAl" = ( /obj/machinery/door/airlock/external{ @@ -27276,7 +27276,7 @@ dir = 4; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "aXo" = ( /obj/machinery/atmospherics/unary/vent_scrubber{ @@ -28162,7 +28162,7 @@ dir = 4; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "aYU" = ( /obj/structure/grille, @@ -28177,7 +28177,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "aYW" = ( /obj/structure/cable{ @@ -28410,7 +28410,7 @@ /area/security/nuke_storage) "aZq" = ( /obj/structure/safe{ - knownby = list("captain") + known_by = list("captain") }, /obj/machinery/light_switch{ pixel_y = -23 @@ -31158,7 +31158,7 @@ dir = 4; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/arrival/station) "bez" = ( /obj/machinery/atmospherics/unary/vent_scrubber{ @@ -42691,7 +42691,7 @@ dir = 8; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "bAR" = ( /turf/simulated/shuttle/wall{ @@ -43235,7 +43235,7 @@ dir = 8; icon_state = "propulsion" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "bCb" = ( /turf/simulated/shuttle/floor{ @@ -45680,7 +45680,7 @@ dir = 8; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/specops) "bGQ" = ( /obj/machinery/mineral/stacking_unit_console{ @@ -46512,7 +46512,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bIv" = ( /obj/structure/table, @@ -46552,7 +46552,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bIy" = ( /obj/item/radio/intercom{ @@ -47566,7 +47566,7 @@ /area/maintenance/asmaint2) "bKm" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bKn" = ( /obj/machinery/shower{ @@ -53021,7 +53021,7 @@ /area/engine/gravitygenerator) "bTj" = ( /obj/structure/safe/floor{ - knownby = list("captain") + known_by = list("captain") }, /obj/item/gun/projectile/revolver/russian, /obj/item/reagent_containers/food/drinks/bottle/absinthe/premium, @@ -55155,7 +55155,7 @@ icon_state = "propulsion_l"; tag = "icon-propulsion_l (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/administration) "bWP" = ( /obj/machinery/door/airlock/external{ @@ -56137,7 +56137,7 @@ icon_state = "propulsion_r"; tag = "icon-propulsion_r (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/administration) "bYv" = ( /turf/space, @@ -59551,7 +59551,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "cdv" = ( /turf/space, @@ -60302,21 +60302,21 @@ /area/shuttle/administration) "ceU" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "ceV" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-burst_l"; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "ceW" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-burst_r"; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "ceX" = ( /turf/space, @@ -61240,13 +61240,6 @@ }, /area/shuttle/administration) "cgy" = ( -/obj/machinery/door/poddoor{ - density = 0; - icon_state = "open"; - id_tag = "Biohazard"; - name = "Biohazard Shutter"; - opacity = 0 - }, /obj/machinery/door/poddoor{ id_tag = "ToxinsVenting"; name = "Toxins Venting Bay Door"; @@ -64263,6 +64256,10 @@ id = "air_in"; on = 1 }, +/obj/machinery/sparker{ + id = "toxinsigniter"; + pixel_x = -20 + }, /turf/simulated/floor/engine/insulated/vacuum, /area/toxins/mixing) "cly" = ( @@ -64278,11 +64275,6 @@ /turf/simulated/floor/plating, /area/maintenance/apmaint) "clz" = ( -/obj/machinery/igniter{ - icon_state = "igniter0"; - id = "ToxinsIgnitor"; - on = 0 - }, /turf/simulated/floor/engine/insulated/vacuum, /area/toxins/mixing) "clA" = ( @@ -65091,12 +65083,12 @@ /turf/simulated/floor/plasteel, /area/toxins/storage) "cmW" = ( -/obj/structure/closet/wardrobe/toxins_white, /obj/item/radio/intercom{ dir = 1; name = "station intercom (General)"; pixel_y = 25 }, +/obj/structure/reagent_dispensers/watertank, /turf/simulated/floor/plasteel{ dir = 9; icon_state = "whitepurple" @@ -65110,19 +65102,20 @@ dir = 1; in_use = 1 }, +/obj/item/grenade/chem_grenade/firefighting, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitepurple" }, /area/toxins/mixing) "cmY" = ( -/obj/structure/closet/wardrobe/toxins_white, /obj/machinery/camera{ c_tag = "Research Toxins Mixing West"; dir = 2; network = list("Research","SS13"); pixel_x = 0 }, +/obj/structure/closet/firecloset, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitepurple" @@ -65133,6 +65126,7 @@ pixel_y = 25 }, /obj/effect/decal/warning_stripes/southwestcorner, +/obj/machinery/portable_atmospherics/canister, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -65152,6 +65146,7 @@ }, /obj/item/extinguisher, /obj/item/clothing/mask/gas, +/obj/item/grenade/chem_grenade/firefighting, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "whitepurple" @@ -65221,7 +65216,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/mining) "cnj" = ( /obj/structure/ore_box, @@ -65441,6 +65436,7 @@ name = "\improper Virology Lobby" }) "cnE" = ( +/obj/machinery/atmospherics/unary/passive_vent, /turf/simulated/floor/engine/insulated/vacuum, /area/toxins/mixing) "cnF" = ( @@ -66162,7 +66158,7 @@ /area/blueshield) "coN" = ( /obj/structure/shuttle/engine/propulsion/burst, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/mining) "coO" = ( /turf/space, @@ -67121,10 +67117,10 @@ }, /area/toxins/mixing) "cqf" = ( -/obj/machinery/atmospherics/binary/pump/highcap{ +/obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/binary/pump{ dir = 1 }, -/obj/effect/decal/warning_stripes/north, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -67145,8 +67141,8 @@ }, /area/toxins/mixing) "cqh" = ( -/obj/machinery/atmospherics/binary/pump/highcap, /obj/effect/decal/warning_stripes/north, +/obj/machinery/atmospherics/binary/pump, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -67159,7 +67155,7 @@ pixel_y = 26 }, /obj/machinery/ignition_switch{ - id = "ToxinsIgnitor"; + id = "toxinsigniter"; pixel_x = 6; pixel_y = 25 }, @@ -67174,13 +67170,15 @@ }, /area/toxins/mixing) "cqj" = ( -/obj/machinery/portable_atmospherics/pump, /obj/machinery/camera{ c_tag = "Research Toxins Mixing East"; dir = 2; network = list("Research","SS13"); pixel_x = 0 }, +/obj/machinery/atmospherics/unary/portables_connector{ + dir = 1 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -67221,12 +67219,6 @@ icon_state = "whitepurple" }, /area/toxins/mixing) -"cqo" = ( -/obj/machinery/portable_atmospherics/scrubber, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/toxins/mixing) "cqp" = ( /obj/machinery/camera{ c_tag = "Research Toxins Launch Room"; @@ -68441,6 +68433,7 @@ d2 = 8; icon_state = "1-8" }, +/obj/machinery/portable_atmospherics/scrubber, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -69350,12 +69343,6 @@ /area/medical/research{ name = "Research Division" }) -"ctD" = ( -/obj/machinery/portable_atmospherics/canister, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/toxins/mixing) "ctE" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/plasteel{ @@ -69394,15 +69381,27 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint2) "ctI" = ( -/obj/structure/table, /obj/structure/cable, -/obj/item/storage/toolbox/mechanical, /obj/machinery/power/apc{ dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0 }, +/obj/structure/table, +/obj/item/stack/cable_coil{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/stack/cable_coil, +/obj/item/analyzer{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/taperecorder{ + pixel_x = 5; + pixel_y = 5 + }, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -69427,38 +69426,12 @@ /obj/effect/decal/warning_stripes/yellow, /turf/simulated/floor/plasteel, /area/engine/controlroom) -"ctK" = ( -/obj/structure/table, -/obj/item/assembly/signaler{ - pixel_x = 8; - pixel_y = 8 - }, -/obj/item/assembly/signaler{ - pixel_x = 5; - pixel_y = -5 - }, -/obj/item/assembly/signaler{ - pixel_x = 3; - pixel_y = 4 - }, -/obj/item/assembly/signaler, -/obj/item/assembly/signaler{ - pixel_x = 4; - pixel_y = -2 - }, -/obj/item/assembly/signaler{ - pixel_x = 4; - pixel_y = -2 - }, -/turf/simulated/floor/plasteel{ - icon_state = "white" - }, -/area/toxins/mixing) "ctL" = ( /obj/machinery/light{ dir = 4; icon_state = "tube1" }, +/obj/machinery/portable_atmospherics/pump, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -70181,13 +70154,11 @@ }, /area/toxins/explab) "cuT" = ( -/obj/item/transfer_valve, -/obj/item/transfer_valve, -/obj/item/transfer_valve, -/obj/item/transfer_valve, -/obj/item/transfer_valve, +/obj/machinery/light_switch{ + pixel_y = -23 + }, /obj/structure/table, -/obj/item/transfer_valve, +/obj/item/storage/toolbox/mechanical, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -70287,25 +70258,28 @@ }, /area/toxins/mixing) "cvc" = ( -/obj/item/assembly/prox_sensor{ - pixel_x = -5; - pixel_y = -5 +/obj/item/transfer_valve{ + pixel_x = 4; + pixel_y = -4 }, -/obj/item/assembly/prox_sensor{ +/obj/item/transfer_valve{ + pixel_x = 2; + pixel_y = -2 + }, +/obj/item/transfer_valve, +/obj/item/transfer_valve{ + pixel_x = -2; + pixel_y = 2 + }, +/obj/item/transfer_valve{ pixel_x = -4; pixel_y = 4 }, -/obj/item/assembly/prox_sensor{ - pixel_x = 5; - pixel_y = 5 - }, /obj/structure/table, -/obj/item/assembly/prox_sensor, -/obj/item/assembly/prox_sensor{ - pixel_x = -5; - pixel_y = -5 +/obj/item/transfer_valve{ + pixel_x = -6; + pixel_y = 6 }, -/obj/item/assembly/prox_sensor, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -70324,27 +70298,6 @@ }, /area/medical/virology) "cve" = ( -/obj/item/assembly/timer, -/obj/item/assembly/timer{ - pixel_x = 6 - }, -/obj/item/assembly/timer{ - pixel_x = -5; - pixel_y = 6 - }, -/obj/structure/table, -/obj/item/assembly/timer{ - pixel_x = -3; - pixel_y = -4 - }, -/obj/item/assembly/timer{ - pixel_x = 8; - pixel_y = 8 - }, -/obj/item/assembly/timer, -/obj/machinery/light_switch{ - pixel_y = -23 - }, /obj/machinery/light, /obj/machinery/requests_console{ department = "Science"; @@ -70353,6 +70306,7 @@ pixel_x = 0; pixel_y = -30 }, +/obj/machinery/vending/plasmaresearch, /turf/simulated/floor/plasteel{ icon_state = "white" }, @@ -77250,7 +77204,7 @@ }, /area/toxins/misc_lab) "cHq" = ( -/obj/machinery/atmospherics/binary/pump/highcap{ +/obj/machinery/atmospherics/binary/pump{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -88767,11 +88721,10 @@ /turf/space, /area/space) "dca" = ( -/obj/structure/lattice, -/obj/machinery/atmospherics/pipe/simple/insulated{ - dir = 10 +/obj/machinery/atmospherics/unary/passive_vent{ + dir = 8 }, -/turf/space, +/turf/simulated/floor/plating/airless, /area/space) "dcb" = ( /turf/simulated/floor/plasteel{ @@ -88780,13 +88733,7 @@ }, /area/hallway/primary/central/north) "dcc" = ( -/obj/machinery/atmospherics/unary/outlet_injector/on{ - dir = 1; - frequency = 1441; - id = "co2_in"; - pixel_y = 1 - }, -/turf/simulated/floor/plating/airless, +/turf/space, /area/toxins/mixing) "dcd" = ( /obj/structure/cable{ @@ -90952,12 +90899,12 @@ /turf/simulated/floor/plating, /area/maintenance/asmaint2) "dgD" = ( -/turf/space, -/turf/simulated/shuttle/wall{ - tag = "icon-propulsion (EAST)"; - icon_state = "propulsion"; - dir = 4 +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l"; + tag = "icon-propulsion_l (EAST)" }, +/turf/simulated/shuttle/plating, /area/shuttle/constructionsite) "dgE" = ( /obj/machinery/power/grounding_rod{ @@ -96600,6 +96547,143 @@ /obj/machinery/suit_storage_unit/engine, /turf/simulated/floor/plating, /area/storage/secure) +"duq" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ + dir = 1 + }, +/turf/space, +/area/space) +"gMZ" = ( +/obj/machinery/atmospherics/pipe/simple/insulated{ + dir = 6 + }, +/obj/machinery/door/poddoor{ + density = 0; + icon_state = "open"; + id_tag = "Biohazard"; + name = "Biohazard Shutter"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/plasmareinforced, +/obj/structure/window/plasmareinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/toxins/mixing) +"hsy" = ( +/obj/machinery/atmospherics/pipe/simple/insulated{ + dir = 4 + }, +/obj/machinery/door/poddoor{ + density = 0; + icon_state = "open"; + id_tag = "Biohazard"; + name = "Biohazard Shutter"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/plasmareinforced{ + dir = 4 + }, +/obj/structure/window/plasmareinforced, +/obj/structure/window/plasmareinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/toxins/mixing) +"izn" = ( +/obj/machinery/atmospherics/unary/passive_vent{ + dir = 1 + }, +/turf/simulated/floor/plating/airless, +/area/space) +"iJf" = ( +/obj/machinery/atmospherics/pipe/simple/insulated, +/obj/machinery/door/poddoor{ + density = 0; + icon_state = "open"; + id_tag = "Biohazard"; + name = "Biohazard Shutter"; + opacity = 0 + }, +/obj/structure/grille, +/obj/structure/window/plasmareinforced{ + dir = 8 + }, +/obj/structure/window/plasmareinforced, +/obj/structure/window/plasmareinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/toxins/mixing) +"iNz" = ( +/obj/machinery/atmospherics/pipe/simple/insulated{ + dir = 4 + }, +/turf/simulated/wall/r_wall, +/area/toxins/launch{ + name = "Toxins Launch Room" + }) +"kOE" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{ + dir = 4 + }, +/obj/structure/lattice, +/turf/space, +/area/space) +"nMi" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging{ + dir = 9 + }, +/turf/space, +/area/space) +"pZO" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging{ + dir = 10 + }, +/turf/space, +/area/space) +"qUv" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging, +/turf/space, +/area/space) +"uxy" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging{ + dir = 4 + }, +/turf/space, +/area/space) +"uDK" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging{ + tag = "icon-intact (NORTHEAST)"; + icon_state = "intact"; + dir = 5 + }, +/turf/space, +/area/space) +"vup" = ( +/obj/machinery/atmospherics/pipe/simple/insulated{ + dir = 10 + }, +/obj/structure/lattice, +/turf/space, +/area/space) +"xAw" = ( +/obj/machinery/atmospherics/pipe/manifold/visible{ + dir = 8 + }, +/obj/structure/lattice, +/turf/space, +/area/space) +"xWg" = ( +/obj/machinery/atmospherics/pipe/simple/heat_exchanging{ + tag = "icon-intact (SOUTHEAST)"; + icon_state = "intact"; + dir = 6 + }, +/turf/space, +/area/space) (1,1,1) = {" aaa @@ -146098,7 +146182,7 @@ cnf cqe crI csg -ctK +cqk cuT cgs bGG @@ -146355,7 +146439,7 @@ cgu cqg crI csg -ctD +cqk cuU cgs bGG @@ -146861,7 +146945,7 @@ dbH aYS aaa dbZ -cgu +cgy cia cke clz @@ -147118,7 +147202,7 @@ ccP aYS aaa dbX -cgu +cgy cib cjX cnE @@ -147633,10 +147717,10 @@ aYS aaa dca dcc -aaa -aaa -afO -cgs +xWg +duq +xAw +iJf cqj crI csh @@ -147890,11 +147974,11 @@ aYS aaa aaa aaa +uxy aaa -aaa -afO -cgs -cqo +kOE +gMZ +cqe crI csg cqk @@ -148145,12 +148229,12 @@ baT bgm aYS aaa -aaa -aaa -aaa -aaa -afO -cgs +xWg +qUv +nMi +xWg +djc +hsy cqm crN csi @@ -148402,12 +148486,12 @@ baT baT aYS aaa -aaa -aaa -aaa -aaa -afO -cgE +pZO +uDK +xWg +nMi +aab +iNz cgE crS cgE @@ -148659,12 +148743,12 @@ baT baT aYS aaa -aaa -aaa -aaa -aaa +xWg +nMi +pZO +uDK afO -cgE +iNz cqp crQ csn @@ -148916,12 +149000,12 @@ baU bgd aYS aaa -aaa -aaa -aaa -aaa +pZO +uDK +xWg +nMi afO -cgE +iNz cqq crT crw @@ -149173,12 +149257,12 @@ baV baV daC aaa -aaa -aaa -aaa -aaa +xWg +nMi +pZO +uDK afO -cgE +iNz coG cqx csq @@ -149430,12 +149514,12 @@ aaa aaa daD aaa -aaa -aaa -aaa -aaa +uxy +xWg +uDK +uxy afO -cgE +iNz coI cqC csr @@ -149687,13 +149771,13 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +uxy +uxy +uxy +uxy afO -aaa -aab +vup +izn aab aab aab @@ -149944,10 +150028,10 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +pZO +nMi +pZO +nMi afO aaa aab diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 0dc62cde008..ee6ca15f83d 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -3225,13 +3225,6 @@ dir = 2 }, /area/syndicate_mothership) -"ir" = ( -/obj/structure/chair/stool, -/turf/unsimulated/floor{ - icon_state = "bar"; - dir = 2 - }, -/area/syndicate_mothership) "is" = ( /mob/living/simple_animal/pet/fox/Syndifox, /turf/unsimulated/floor{ @@ -3526,6 +3519,9 @@ /area/wizard_station) "jf" = ( /obj/structure/chair/stool/bar, +/obj/effect/landmark{ + name = "Syndicate-Spawn" + }, /turf/unsimulated/floor{ icon_state = "bar"; dir = 2 @@ -7143,7 +7139,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/centcom/evac) "rK" = ( /turf/unsimulated/wall/splashscreen, @@ -7154,7 +7150,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/centcom/evac) "rM" = ( /turf/simulated/shuttle/wall{ @@ -7169,7 +7165,7 @@ icon_state = "propulsion_l"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/centcom/evac) "rO" = ( /obj/docking_port/stationary{ @@ -7207,7 +7203,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/centcom/evac) "rS" = ( /turf/simulated/shuttle/wall{ @@ -12009,8 +12005,8 @@ /area/syndicate_mothership) "BE" = ( /obj/structure/rack, -/obj/item/storage/backpack/duffel/syndie/ammo/loaded, -/obj/item/storage/backpack/duffel/syndie/ammo/loaded, +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun, +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun, /obj/item/gun/projectile/automatic/shotgun/bulldog, /obj/item/gun/projectile/automatic/shotgun/bulldog, /turf/unsimulated/floor{ @@ -55027,7 +55023,7 @@ hQ hn hn en -ir +en iY jf jk @@ -55798,7 +55794,7 @@ hn hn is en -ir +en hn iL jo diff --git a/_maps/map_files/cyberiad/z3.dmm b/_maps/map_files/cyberiad/z3.dmm index 31314bf545a..3d298fc02eb 100644 --- a/_maps/map_files/cyberiad/z3.dmm +++ b/_maps/map_files/cyberiad/z3.dmm @@ -425,14 +425,14 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/freegolem) "aW" = ( /obj/structure/shuttle/engine/propulsion{ - dir = 8; + dir = 4; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/freegolem) "aX" = ( /obj/machinery/light/small, diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index 08f7dc62ebe..a75ca9403e0 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -5391,7 +5391,7 @@ icon_state = "propulsion_r"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "lu" = ( /turf/space, @@ -5414,7 +5414,7 @@ dir = 1 }, /obj/structure/window/reinforced, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/space) "lx" = ( /turf/space, @@ -5839,7 +5839,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "mG" = ( /obj/structure/shuttle/engine/heater{ @@ -5850,7 +5850,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/space) "mH" = ( /turf/simulated/mineral, @@ -6004,7 +6004,7 @@ icon_state = "propulsion_l"; tag = "icon-propulsion_l (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "nf" = ( /obj/effect/spawner/random_spawners/syndicate/trap/mine, @@ -6092,7 +6092,7 @@ icon_state = "propulsion_l"; tag = "icon-propulsion_l (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/space) "nr" = ( /obj/effect/decal/warning_stripes/red, diff --git a/_maps/map_files/shuttles/cargo_base.dmm b/_maps/map_files/shuttles/cargo_base.dmm index 7fc34998596..d14aa27c38e 100644 --- a/_maps/map_files/shuttles/cargo_base.dmm +++ b/_maps/map_files/shuttles/cargo_base.dmm @@ -159,7 +159,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "u" = ( /turf/space, @@ -177,18 +177,18 @@ tag = "icon-burst_l"; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "x" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) "y" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-burst_r"; icon_state = "burst_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/supply) (1,1,1) = {" diff --git a/_maps/map_files/shuttles/emergency_bar.dmm b/_maps/map_files/shuttles/emergency_bar.dmm index d8ebf266f68..0cfb856e28d 100644 --- a/_maps/map_files/shuttles/emergency_bar.dmm +++ b/_maps/map_files/shuttles/emergency_bar.dmm @@ -642,7 +642,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bH" = ( /turf/simulated/shuttle/wall{ @@ -661,7 +661,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bK" = ( /turf/space, @@ -672,7 +672,7 @@ /area/shuttle/escape) "bL" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) (1,1,1) = {" diff --git a/_maps/map_files/shuttles/emergency_clown.dmm b/_maps/map_files/shuttles/emergency_clown.dmm index 5179a940b4c..1ea643d4c8d 100644 --- a/_maps/map_files/shuttles/emergency_clown.dmm +++ b/_maps/map_files/shuttles/emergency_clown.dmm @@ -505,7 +505,7 @@ /obj/structure/window/reinforced, /obj/item/stack/sheet/mineral/bananium, /obj/item/bikehorn/rubberducky, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bp" = ( /turf/simulated/shuttle/wall{ @@ -527,7 +527,7 @@ /obj/structure/window/reinforced, /obj/item/stack/sheet/mineral/bananium, /obj/item/bikehorn/rubberducky, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bs" = ( /turf/space, @@ -538,7 +538,7 @@ /area/shuttle/escape) "bt" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) (1,1,1) = {" diff --git a/_maps/map_files/shuttles/emergency_cramped.dmm b/_maps/map_files/shuttles/emergency_cramped.dmm index 9bce9e28f00..de7bb67bb6b 100644 --- a/_maps/map_files/shuttles/emergency_cramped.dmm +++ b/_maps/map_files/shuttles/emergency_cramped.dmm @@ -162,7 +162,7 @@ dir = 1; layer = 2.9 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "A" = ( /turf/simulated/shuttle/wall{ @@ -175,14 +175,14 @@ tag = "icon-burst_l"; icon_state = "burst_l" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "C" = ( /obj/structure/shuttle/engine/propulsion{ tag = "icon-propulsion_r"; icon_state = "propulsion_r" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "D" = ( /turf/simulated/shuttle/wall{ diff --git a/_maps/map_files/shuttles/emergency_cyb.dmm b/_maps/map_files/shuttles/emergency_cyb.dmm index 078a6e81cf6..3be4c293b80 100644 --- a/_maps/map_files/shuttles/emergency_cyb.dmm +++ b/_maps/map_files/shuttles/emergency_cyb.dmm @@ -543,7 +543,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bs" = ( /turf/simulated/shuttle/wall{ @@ -562,7 +562,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bv" = ( /turf/space, @@ -573,7 +573,7 @@ /area/shuttle/escape) "bw" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) (1,1,1) = {" diff --git a/_maps/map_files/shuttles/emergency_dept.dmm b/_maps/map_files/shuttles/emergency_dept.dmm index d7fac770216..45acf04e012 100644 --- a/_maps/map_files/shuttles/emergency_dept.dmm +++ b/_maps/map_files/shuttles/emergency_dept.dmm @@ -743,14 +743,14 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bR" = ( /obj/structure/shuttle/engine/heater, /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bS" = ( /turf/space, @@ -761,7 +761,7 @@ /area/shuttle/escape) "bT" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bU" = ( /turf/space, diff --git a/_maps/map_files/shuttles/emergency_mil.dmm b/_maps/map_files/shuttles/emergency_mil.dmm index df8d70bfab5..de4bba7254b 100644 --- a/_maps/map_files/shuttles/emergency_mil.dmm +++ b/_maps/map_files/shuttles/emergency_mil.dmm @@ -559,14 +559,14 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bv" = ( /obj/structure/shuttle/engine/heater, /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bw" = ( /turf/space, @@ -577,7 +577,7 @@ /area/shuttle/escape) "bx" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "by" = ( /turf/simulated/floor/plating/airless, diff --git a/_maps/map_files/shuttles/emergency_narnar.dmm b/_maps/map_files/shuttles/emergency_narnar.dmm index b6bfe0376d6..8d36106c3da 100644 --- a/_maps/map_files/shuttles/emergency_narnar.dmm +++ b/_maps/map_files/shuttles/emergency_narnar.dmm @@ -410,7 +410,7 @@ }, /obj/structure/shuttle/engine/heater, /obj/structure/cult/forge, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bi" = ( /obj/structure/shuttle/engine/heater, @@ -418,11 +418,11 @@ dir = 1 }, /obj/structure/cult/forge, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bj" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) (1,1,1) = {" diff --git a/_maps/map_files/shuttles/emergency_old.dmm b/_maps/map_files/shuttles/emergency_old.dmm index 602d366d476..823d6f36a4f 100644 --- a/_maps/map_files/shuttles/emergency_old.dmm +++ b/_maps/map_files/shuttles/emergency_old.dmm @@ -472,7 +472,7 @@ dir = 1 }, /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bk" = ( /turf/simulated/shuttle/wall{ @@ -485,7 +485,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/shuttle/escape) "bn" = ( /turf/space, @@ -496,7 +496,7 @@ /area/shuttle/escape) "bo" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/shuttle/escape) (1,1,1) = {" diff --git a/_maps/map_files/templates/medium_shuttle1.dmm b/_maps/map_files/templates/medium_shuttle1.dmm index 324e3f05fbc..109f921ed60 100644 --- a/_maps/map_files/templates/medium_shuttle1.dmm +++ b/_maps/map_files/templates/medium_shuttle1.dmm @@ -8,7 +8,7 @@ icon_state = "burst_l"; tag = "icon-burst_l (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -23,7 +23,7 @@ icon_state = "rwindow"; dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -218,7 +218,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) diff --git a/_maps/map_files/templates/medium_shuttle2.dmm b/_maps/map_files/templates/medium_shuttle2.dmm index ed0cccfda87..4a0e2e5e031 100644 --- a/_maps/map_files/templates/medium_shuttle2.dmm +++ b/_maps/map_files/templates/medium_shuttle2.dmm @@ -8,7 +8,7 @@ icon_state = "burst_l"; tag = "icon-burst_l (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -23,7 +23,7 @@ icon_state = "rwindow"; dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -52,7 +52,7 @@ icon_state = "burst_r"; tag = "icon-burst_r (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) diff --git a/_maps/map_files/templates/medium_shuttle3.dmm b/_maps/map_files/templates/medium_shuttle3.dmm index 013f2ae2f50..382a3a3e18d 100644 --- a/_maps/map_files/templates/medium_shuttle3.dmm +++ b/_maps/map_files/templates/medium_shuttle3.dmm @@ -8,7 +8,7 @@ icon_state = "propulsion"; dir = 1 }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -26,7 +26,7 @@ icon_state = "heater"; dir = 1 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -103,7 +103,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (EAST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -113,7 +113,7 @@ icon_state = "heater"; dir = 8 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -129,7 +129,7 @@ icon_state = "heater"; dir = 4 }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -139,7 +139,7 @@ icon_state = "propulsion"; tag = "icon-propulsion (WEST)" }, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) @@ -262,13 +262,13 @@ }) "F" = ( /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) "G" = ( /obj/structure/shuttle/engine/propulsion, -/turf/space, +/turf/simulated/shuttle/plating, /area/ruin/powered{ name = "Shuttle" }) diff --git a/_maps/map_files/templates/small_shuttle_1.dmm b/_maps/map_files/templates/small_shuttle_1.dmm index e795e98614c..92066f62880 100644 --- a/_maps/map_files/templates/small_shuttle_1.dmm +++ b/_maps/map_files/templates/small_shuttle_1.dmm @@ -46,11 +46,11 @@ /area/ruin/powered) "j" = ( /obj/structure/shuttle/engine/heater, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered) "k" = ( /obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered) "l" = ( /turf/simulated/shuttle/wall{ @@ -75,7 +75,7 @@ /obj/structure/shuttle/engine/propulsion{ icon_state = "propulsion_l" }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered) "p" = ( /turf/simulated/shuttle/wall{ @@ -124,7 +124,7 @@ /obj/structure/shuttle/engine/propulsion{ icon_state = "propulsion_r" }, -/turf/simulated/floor/plating/airless, +/turf/simulated/shuttle/plating, /area/ruin/powered) (1,1,1) = {" diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 785d58520a0..8f828c178ad 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -43,8 +43,8 @@ icon = null /obj/machinery/atmospherics/binary/dp_vent_pump/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -158,10 +158,10 @@ //Radio remote control /obj/machinery/atmospherics/binary/dp_vent_pump/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/binary/dp_vent_pump/proc/broadcast_status() if(!radio_connection) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 9e845c15a98..8becfa37c10 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -22,8 +22,8 @@ set_frequency(frequency) /obj/machinery/atmospherics/binary/passive_gate/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -70,10 +70,10 @@ //Radio remote control /obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status() if(!radio_connection) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 118a70c3ecd..b138d19b513 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -29,17 +29,11 @@ Thus, the two variables affect pump operation are set in New(): var/datum/radio_frequency/radio_connection /obj/machinery/atmospherics/binary/pump/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() -/obj/machinery/atmospherics/binary/pump/highcap - name = "High capacity gas pump" - desc = "A high capacity pump" - - target_pressure = 15000000 - /obj/machinery/atmospherics/binary/pump/on icon_state = "map_on" on = 1 @@ -86,10 +80,10 @@ Thus, the two variables affect pump operation are set in New(): //Radio remote control /obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/binary/pump/proc/broadcast_status() if(!radio_connection) diff --git a/code/ATMOSPHERICS/components/binary_devices/valve.dm b/code/ATMOSPHERICS/components/binary_devices/valve.dm index f8f282a55af..dabe548ce9f 100644 --- a/code/ATMOSPHERICS/components/binary_devices/valve.dm +++ b/code/ATMOSPHERICS/components/binary_devices/valve.dm @@ -72,8 +72,8 @@ settagwhitelist = list("id_tag") /obj/machinery/atmospherics/binary/valve/digital/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -104,10 +104,10 @@ icon_state = "valve[open]nopower" /obj/machinery/atmospherics/binary/valve/digital/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/atmospherics/binary/valve/digital/atmos_init() ..() diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm index a64c94e7fc5..11874172340 100644 --- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm @@ -29,8 +29,8 @@ Thus, the two variables affect pump operation are set in New(): var/datum/radio_frequency/radio_connection /obj/machinery/atmospherics/binary/volume_pump/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -82,10 +82,10 @@ Thus, the two variables affect pump operation are set in New(): return 1 /obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency) + radio_connection = SSradio.add_object(src, frequency) /obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status() if(!radio_connection) diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 903f917e0c6..c6720e45f6e 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -24,8 +24,8 @@ Filter types: /obj/machinery/atmospherics/trinary/filter/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -34,10 +34,10 @@ Filter types: flipped = 1 /obj/machinery/atmospherics/trinary/filter/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/atmospherics/trinary/filter/update_icon() if(flipped) diff --git a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm index 9dddf8b06f4..3ec4e8443e4 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/tvalve.dm @@ -109,8 +109,8 @@ var/datum/radio_frequency/radio_connection /obj/machinery/atmospherics/trinary/tvalve/digital/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -151,10 +151,10 @@ //Radio remote control /obj/machinery/atmospherics/trinary/tvalve/digital/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/atmospherics/trinary/tvalve/digital/atmos_init() ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm index d597d0eb4c4..509b36ff8ab 100644 --- a/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary_devices/outlet_injector.dm @@ -32,8 +32,8 @@ id_tag = id /obj/machinery/atmospherics/unary/outlet_injector/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -95,10 +95,10 @@ flick("inject", src) /obj/machinery/atmospherics/unary/outlet_injector/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency) + radio_connection = SSradio.add_object(src, frequency) /obj/machinery/atmospherics/unary/outlet_injector/proc/broadcast_status() if(!radio_connection) diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm index 613d0f0794e..0ac609cb6ec 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm @@ -180,10 +180,10 @@ //Radio remote control /obj/machinery/atmospherics/unary/vent_pump/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency,radio_filter_in) + radio_connection = SSradio.add_object(src, frequency,radio_filter_in) if(frequency != ATMOS_VENTSCRUB) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag @@ -435,7 +435,7 @@ if(initial_loc) initial_loc.air_vent_info -= id_tag initial_loc.air_vent_names -= id_tag - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm index 8416a784019..82cdfa46e97 100644 --- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm @@ -53,8 +53,8 @@ if(initial_loc && frequency == ATMOS_VENTSCRUB) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -127,9 +127,9 @@ add_underlay(T,, dir) /obj/machinery/atmospherics/unary/vent_scrubber/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, radio_filter_in) + radio_connection = SSradio.add_object(src, frequency, radio_filter_in) if(frequency != ATMOS_VENTSCRUB) initial_loc.air_scrub_info -= id_tag initial_loc.air_scrub_names -= id_tag diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index 3d0ec87a8a2..b788cd07d26 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -48,12 +48,12 @@ anchored = 1 mouse_opacity = MOUSE_OPACITY_TRANSPARENT unacidable = 1//So you can't melt fire with acid. - icon = 'icons/effects/fire.dmi' + icon = 'icons/goonstation/effects/fire.dmi' icon_state = "1" - layer = TURF_LAYER - + layer = MASSIVE_OBJ_LAYER + alpha = 250 blend_mode = BLEND_ADD - light_range = 3 + light_range = 2 var/volume = 125 var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST @@ -141,7 +141,7 @@ W.adjacent_fire_act(W, radiated_temperature) continue var/turf/simulated/T = get_step(src, direction) - if(istype(T) && T.active_hotspot) + if(istype(T) && !T.active_hotspot) T.hotspot_expose(radiated_temperature, CELL_VOLUME/4) else diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index 6ab83750f3c..21ea57a571b 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -66,8 +66,6 @@ air.temperature = temperature - update_visuals() - /turf/simulated/Destroy() visibilityChanged() QDEL_NULL(active_hotspot) @@ -209,22 +207,17 @@ air.react() + update_visuals() + if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) hotspot_expose(air.temperature, CELL_VOLUME) for(var/atom/movable/item in src) item.temperature_expose(air, air.temperature, CELL_VOLUME) temperature_expose(air, air.temperature, CELL_VOLUME) - if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION) - if(consider_superconductivity(starting = 1)) - remove = 0 - - if(air.temperature < T0C && air.return_pressure() > 10) - icy = 1 - else if(air.temperature > T0C) - icy = 0 - - update_visuals() + if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION) + if(consider_superconductivity(starting = 1)) + remove = 0 if(!excited_group && remove == 1) SSair.remove_from_active(src) @@ -237,27 +230,19 @@ archived_cycle = SSair.times_fired /turf/simulated/proc/update_visuals() - if(icy && !icyoverlay) - overlays |= icemaster - icyoverlay = icemaster - else if(icyoverlay && !icy) - icyoverlay = null - overlays -= icemaster - var/new_overlay_type = tile_graphic() if(new_overlay_type == atmos_overlay_type) return var/atmos_overlay = get_atmos_overlay_by_name(atmos_overlay_type) if(atmos_overlay) - overlays -= atmos_overlay - mouse_opacity = MOUSE_OPACITY_ICON + vis_contents -= atmos_overlay atmos_overlay = get_atmos_overlay_by_name(new_overlay_type) if(atmos_overlay) - overlays += atmos_overlay + vis_contents += atmos_overlay atmos_overlay_type = new_overlay_type -/turf/simulated/proc/get_atmos_overlay_by_name(var/name) +/turf/simulated/proc/get_atmos_overlay_by_name(name) switch(name) if("plasma") return plmaster @@ -266,13 +251,13 @@ return null /turf/simulated/proc/tile_graphic() + if(!air) + return if(air.toxins > MOLES_PLASMA_VISIBLE) - mouse_opacity = MOUSE_OPACITY_TRANSPARENT return "plasma" var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases if(sleeping_agent && (sleeping_agent.moles > 1)) - mouse_opacity = MOUSE_OPACITY_TRANSPARENT return "sleeping_agent" return null @@ -532,7 +517,7 @@ turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)) var/heat = thermal_conductivity*delta_temperature* \ - (heat_capacity*700000/(heat_capacity+700000)) //700000 is the heat_capacity from a space turf, hardcoded here + (heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM)) //700000 is the heat_capacity from a space turf, hardcoded here temperature -= heat/heat_capacity /turf/proc/Initialize_Atmos(times_fired) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index be6326272f7..67eea12291a 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -1,66 +1,67 @@ -#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin (default 0.0215) -#define AIR_DAMAGE_MODIFIER 2.025 //More means less damage from hot air scalding lungs, less = more damage. (default 2.025) - -#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC -#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) -#define O2STANDARD 0.21 -#define N2STANDARD 0.79 -#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) -#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) - #define GAS_O2 (1 << 0) #define GAS_N2 (1 << 1) #define GAS_PL (1 << 2) #define GAS_CO2 (1 << 3) #define GAS_N2O (1 << 4) -//stuff you should probably leave well alone! //ATMOS -#define CELL_VOLUME 2500 //liters in a cell -#define BREATH_VOLUME 0.5 //liters in a normal breath -#define BREATH_MOLES (ONE_ATMOSPHERE * BREATH_VOLUME /(T20C*R_IDEAL_GAS_EQUATION)) -#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile -#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD*BREATH_PERCENTAGE*0.16) //Amount of air needed before pass out/suffocation commences -#define NORMPIPERATE 30 //pipe-insulation rate divisor -#define HEATPIPERATE 8 //heat-exch pipe insulation -#define FLOWFRAC 0.99 //fraction of gas transfered per process -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking -#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere -#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) //Boom 3x3 base explosion -#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold -#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.005 //Minimum ratio of air that must move to/from a tile to suspend group processing -#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended -#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Either this must be active -#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) +//stuff you should probably leave well alone! +#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) +#define ONE_ATMOSPHERE 101.325 //kPa +#define TCMB 2.7 // -270.3degC +#define TCRYO 265 // -48.15degC +#define T0C 273.15 // 0degC +#define T20C 293.15 // 20degC + +#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC +#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity +#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air +#define N2STANDARD 0.79 //same but for nitrogen +#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) +#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) +#define CELL_VOLUME 2500 //liters in a cell +#define BREATH_VOLUME 0.5 //liters in a normal breath +#define BREATH_MOLES (ONE_ATMOSPHERE * BREATH_VOLUME /(T20C*R_IDEAL_GAS_EQUATION)) +#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile + +//EXCITED GROUPS +#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.005 //Minimum ratio of air that must move to/from a tile to suspend group processing +#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended +#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Either this must be active +#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) #define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 #define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended #define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal #define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10) #define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200) -#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4 + +//HEAT TRANSFER COEFFICIENTS +//Must be between 0 and 1. Values closer to 1 equalize temperature faster +//Should not exceed 0.4 else strange heat flow occur +#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.15 #define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 -#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0 -#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.2 //a hack to partly simulate radiative heat #define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 #define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now - //Must be between 0 and 1. Values closer to 1 equalize temperature faster - //Should not exceed 0.4 else strange heat flow occur +#define HEAT_CAPACITY_VACUUM 700000 //a hack to help make vacuums "cold", sacrificing realism for gameplay + +//FIRE #define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C) #define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C) #define FIRE_SPREAD_RADIOSITY_SCALE 0.85 -#define FIRE_CARBON_ENERGY_RELEASED 2500000 //Amount of heat released per mole of burnt carbon into the tile -#define FIRE_PLASMA_ENERGY_RELEASED 15000000 //Amount of heat released per mole of burnt plasma into the tile +#define FIRE_CARBON_ENERGY_RELEASED 500000 //Amount of heat released per mole of burnt carbon into the tile +#define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile #define FIRE_GROWTH_RATE 40000 //For small fires -#define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C //Resistance to fire damage -#define CARBON_LIFEFORM_FIRE_DAMAGE 4 //Fire damage - //Plasma fire properties -#define OXYGEN_BURN_RATE_BASE 7 -#define PLASMA_BURN_RATE_DELTA 20 + +//Plasma fire properties +#define OXYGEN_BURN_RATE_BASE 1.4 +#define PLASMA_BURN_RATE_DELTA 4 #define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C) #define PLASMA_UPPER_TEMPERATURE (1370+T0C) #define PLASMA_MINIMUM_OXYGEN_NEEDED 2 #define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30 #define PLASMA_OXYGEN_FULLBURN 10 + +//GASES #define MIN_TOXIC_GAS_DAMAGE 1 #define MAX_TOXIC_GAS_DAMAGE 10 #define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible @@ -72,6 +73,8 @@ #define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) #define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. + +#define BODYTEMP_NORMAL 310.15 //The natural temperature for a body #define BODYTEMP_AUTORECOVERY_DIVISOR 12 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. #define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. #define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. @@ -79,8 +82,8 @@ #define BODYTEMP_COOLING_MAX 30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. #define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. -#define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat. -#define BODYTEMP_COLD_DAMAGE_LIMIT 260.15 // The limit the human body can take before it starts taking damage from coldness. +#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 50) // The limit the human body can take before it starts taking damage from heat. +#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness. #define SPACE_HELM_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. #define SPACE_HELM_MAX_TEMP_PROTECT 1500 //Thermal insulation works both ways /Malkevin @@ -92,8 +95,7 @@ #define FIRE_HELM_MIN_TEMP_PROTECT 60 //Cold protection for fire helmets #define FIRE_HELM_MAX_TEMP_PROTECT 30000 //for fire helmet quality items (red and white hardhats) -#define FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0. -#define FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT 35000 //for fire helmet quality items (red and white hardhats) +#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0. #define HELMET_MIN_TEMP_PROTECT 160 //For normal helmets #define HELMET_MAX_TEMP_PROTECT 600 //For normal helmets @@ -105,17 +107,23 @@ #define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves #define SHOES_MAX_TEMP_PROTECT 1500 //For gloves - #define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE -#define MAX_HIGH_PRESSURE_DAMAGE 4 //This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( +#define MAX_HIGH_PRESSURE_DAMAGE 4 #define LOW_PRESSURE_DAMAGE 2 //The amounb of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). #define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this +//PIPES // Atmos pipe limits #define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at. #define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at. +//TANKS +#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking +#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere +#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) //Boom 3x3 base explosion +#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold + // Atmos alarm defines #define ATMOS_ALARM_NONE 0 #define ATMOS_ALARM_WARNING 1 diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 593419b61b1..ba4bf0090c7 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -26,6 +26,7 @@ #define TOXLOSS 4 #define OXYLOSS 8 #define SHAME 16 +#define OBLITERATION 32 //Bitflags defining which status effects could be or are inflicted on a mob #define CANSTUN 1 @@ -40,6 +41,9 @@ #define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath #define XENO_HOST 16384 //Tracks whether we're gonna be a baby alien's mummy. +//Health Defines +#define HEALTH_THRESHOLD_CRIT 0 +#define HEALTH_THRESHOLD_DEAD -100 //Grab levels #define GRAB_PASSIVE 1 diff --git a/code/__DEFINES/gamemode.dm b/code/__DEFINES/gamemode.dm index 617cdf3cb21..a1e469e3c94 100644 --- a/code/__DEFINES/gamemode.dm +++ b/code/__DEFINES/gamemode.dm @@ -11,7 +11,6 @@ #define GAMEMODE_IS_BLOB (ticker && istype(ticker.mode, /datum/game_mode/blob)) #define GAMEMODE_IS_CULT (ticker && istype(ticker.mode, /datum/game_mode/cult)) #define GAMEMODE_IS_HEIST (ticker && istype(ticker.mode, /datum/game_mode/heist)) -#define GAMEMODE_IS_NATIONS (ticker && istype(ticker.mode, /datum/game_mode/nations)) #define GAMEMODE_IS_NUCLEAR (ticker && istype(ticker.mode, /datum/game_mode/nuclear)) #define GAMEMODE_IS_REVOLUTION (ticker && istype(ticker.mode, /datum/game_mode/revolution)) #define GAMEMODE_IS_WIZARD (ticker && istype(ticker.mode, /datum/game_mode/wizard)) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 59cf95a72d7..45953a2e47b 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -16,18 +16,17 @@ #define DIAG_MECH_HUD "11"// Mech health bar #define STATUS_HUD_OOC "12"// STATUS_HUD without virus db check for someone being ill. #define SPECIALROLE_HUD "13" //for antag huds. these are used at the /mob level -#define NATIONS_HUD "14" //Show nations icons during nations gamemode -#define DIAG_BOT_HUD "15"// Bot HUDS -#define PLANT_NUTRIENT_HUD "16"// Plant nutrient level -#define PLANT_WATER_HUD "17"// Plant water level -#define PLANT_STATUS_HUD "18"// Plant harvest/dead -#define PLANT_HEALTH_HUD "19"// Plant health -#define PLANT_TOXIN_HUD "20"// Toxin level -#define PLANT_PEST_HUD "21"// Pest level -#define PLANT_WEED_HUD "22"// Weed level -#define DIAG_TRACK_HUD "23"// Mech tracking beacon -#define DIAG_PATH_HUD "24"//Bot path indicators -#define GLAND_HUD "25"//Gland indicators for abductors +#define DIAG_BOT_HUD "14"// Bot HUDS +#define PLANT_NUTRIENT_HUD "15"// Plant nutrient level +#define PLANT_WATER_HUD "16"// Plant water level +#define PLANT_STATUS_HUD "17"// Plant harvest/dead +#define PLANT_HEALTH_HUD "18"// Plant health +#define PLANT_TOXIN_HUD "19"// Toxin level +#define PLANT_PEST_HUD "20"// Pest level +#define PLANT_WEED_HUD "21"// Weed level +#define DIAG_TRACK_HUD "22"// Mech tracking beacon +#define DIAG_PATH_HUD "23"//Bot path indicators +#define GLAND_HUD "24"//Gland indicators for abductors //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior @@ -42,22 +41,20 @@ #define DATA_HUD_DIAGNOSTIC 5 #define DATA_HUD_DIAGNOSTIC_ADVANCED 6 #define DATA_HUD_HYDROPONIC 7 -//NATIONS -#define GAME_HUD_NATIONS 8 //antag HUD defines -#define ANTAG_HUD_CULT 9 -#define ANTAG_HUD_REV 10 -#define ANTAG_HUD_OPS 11 -#define ANTAG_HUD_WIZ 12 -#define ANTAG_HUD_SHADOW 13 -#define ANTAG_HUD_TRAITOR 14 -#define ANTAG_HUD_NINJA 15 -#define ANTAG_HUD_CHANGELING 16 -#define ANTAG_HUD_VAMPIRE 17 -#define ANTAG_HUD_ABDUCTOR 18 -#define DATA_HUD_ABDUCTOR 19 -#define ANTAG_HUD_DEVIL 20 -#define ANTAG_HUD_EVENTMISC 21 +#define ANTAG_HUD_CULT 8 +#define ANTAG_HUD_REV 9 +#define ANTAG_HUD_OPS 10 +#define ANTAG_HUD_WIZ 11 +#define ANTAG_HUD_SHADOW 12 +#define ANTAG_HUD_TRAITOR 13 +#define ANTAG_HUD_NINJA 14 +#define ANTAG_HUD_CHANGELING 15 +#define ANTAG_HUD_VAMPIRE 16 +#define ANTAG_HUD_ABDUCTOR 17 +#define DATA_HUD_ABDUCTOR 18 +#define ANTAG_HUD_DEVIL 19 +#define ANTAG_HUD_EVENTMISC 20 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/__DEFINES/math.dm b/code/__DEFINES/math.dm index 7115cc677f6..4d98c565c3a 100644 --- a/code/__DEFINES/math.dm +++ b/code/__DEFINES/math.dm @@ -3,13 +3,6 @@ #define SPEED_OF_LIGHT_SQ 9e+16 #define INFINITY 1e31 //closer then enough -//atmos -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -#define TCMB 2.7 // -270.3degC - #define Clamp(x, y, z) ((x) <= (y) ? (y) : ((x) >= (z) ? (z) : (x))) #define CLAMP01(x) (Clamp((x), 0, 1)) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 7783216427b..dff9426c641 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -394,4 +394,11 @@ // Defib stats #define DEFIB_TIME_LIMIT 120 -#define DEFIB_TIME_LOSS 60 \ No newline at end of file +#define DEFIB_TIME_LOSS 60 + +//Ghost orbit types: +#define GHOST_ORBIT_CIRCLE "circle" +#define GHOST_ORBIT_TRIANGLE "triangle" +#define GHOST_ORBIT_HEXAGON "hexagon" +#define GHOST_ORBIT_SQUARE "square" +#define GHOST_ORBIT_PENTAGON "pentagon" \ No newline at end of file diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index f8f9609aced..aa3652046b5 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -28,6 +28,9 @@ #define CHAT_NO_TICKETLOGS 65536 #define UI_DARKMODE 131072 #define DISABLE_KARMA 262144 +#define CHAT_NO_MENTORTICKETLOGS 524288 + +#define TYPING_ONCE 1048576 #define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC) diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm new file mode 100644 index 00000000000..e49a9ea9b67 --- /dev/null +++ b/code/__DEFINES/radio.dm @@ -0,0 +1,60 @@ + +#define DISPLAY_FREQ 1435 //status displays +#define ATMOS_FIRE_FREQ 1437 //air alarms +#define ENGINE_FREQ 1438 //engine components +#define ATMOS_VENTSCRUB 1439 //vents, scrubbers, atmos control +#define ATMOS_DISTRO_FREQ 1443 //distro loop +#define ATMOS_TANKS_FREQ 1441 //atmos supply tanks +#define BOT_BEACON_FREQ 1445 //bot navigation beacons +#define AIRLOCK_FREQ 1449 //airlock controls, electropack, magnets + +#define RSD_FREQ 1457 //radio signal device +#define IMPL_FREQ 1451 //tracking implant + +#define RADIO_LOW_FREQ 1200 //minimum radio freq +#define PUBLIC_LOW_FREQ 1441 //minimum radio chat freq +#define PUBLIC_HIGH_FREQ 1489 //maximum radio chat freq +#define RADIO_HIGH_FREQ 1600 //maximum radio freq + +#define SYND_FREQ 1213 +#define SYNDTEAM_FREQ 1244 +#define DTH_FREQ 1341 //Special Operations +#define AI_FREQ 1343 +#define ERT_FREQ 1345 +#define COMM_FREQ 1353 //Command +#define BOT_FREQ 1447 //mulebot, secbot, ed209 + + +// Department channels +#define PUB_FREQ 1459 //standard radio chat +#define SEC_FREQ 1359 //security +#define ENG_FREQ 1357 //engineering +#define SCI_FREQ 1351 //science +#define MED_FREQ 1355 //medical +#define SUP_FREQ 1347 //cargo +#define SRV_FREQ 1349 //service + +// Internal department channels +#define MED_I_FREQ 1485 +#define SEC_I_FREQ 1475 + +// Transmission methods +#define TRANSMISSION_WIRE 0 +#define TRANSMISSION_RADIO 1 + +//This filter is special because devices belonging to default also recieve signals sent to any other filter. +#define RADIO_DEFAULT "radio_default" +#define RADIO_TO_AIRALARM "radio_airalarm" //air alarms +#define RADIO_FROM_AIRALARM "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms +#define RADIO_CHAT "radio_telecoms" +#define RADIO_ATMOSIA "radio_atmos" +#define RADIO_NAVBEACONS "radio_navbeacon" +#define RADIO_AIRLOCK "radio_airlock" +#define RADIO_SECBOT "radio_secbot" +#define RADIO_HONKBOT "radio_honkbot" +#define RADIO_MULEBOT "radio_mulebot" +#define RADIO_CLEANBOT "10" +#define RADIO_FLOORBOT "11" +#define RADIO_MEDBOT "12" +#define RADIO_MAGNETS "radio_magnet" +#define RADIO_LOGIC "radio_logic" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c7c3bbf5256..27b69284a3d 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -442,7 +442,7 @@ /proc/SecondsToTicks(var/seconds) return seconds * 10 -proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) +proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) var/roletext = be_special_type ? get_roletext(be_special_type) : null var/list/mob/dead/observer/candidates = list() var/time_passed = world.time diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 5b830a72b9f..dc2b2e4ec0a 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -28,7 +28,6 @@ init_datum_subtypes(/datum/job, GLOB.joblist, list(/datum/job/ai, /datum/job/cyborg), "title") init_datum_subtypes(/datum/superheroes, GLOB.all_superheroes, null, "name") - init_datum_subtypes(/datum/nations, GLOB.all_nations, null, "default_name") init_datum_subtypes(/datum/language, GLOB.all_languages, null, "name") for(var/language_name in GLOB.all_languages) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 04fc2c6f73c..dad2ecd7630 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -731,10 +731,16 @@ The _flatIcons list is a cache for generated icon files. var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} - // Dimensions of overlay being added - var/{addX1;addX2;addY1;addY2} + // Current dimensions of flattened icon + var/flatX1 = 1 + var/flatX2 = flat.Width() + var/flatY1 = 1 + var/flatY2 = flat.Height() + // Dimensions of overlay being added + var/addX1 + var/addX2 + var/addY1 + var/addY2 for(var/I in layers) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 9dd3c870d51..5b639cc80f8 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -109,6 +109,15 @@ else return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) +// Uses client.typing to check if the popup should appear or not +/proc/typing_input(mob/user, message = "", title = "", default = "") + if(user.client.checkTyping()) // Prevent double windows + return null + user.client.typing = TRUE + var/msg = input(user, message, title, default) as text|null + user.client.typing = FALSE + return msg + //Filters out undesirable characters from names /proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN) if(!t_in || length(t_in) > max_length) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 287de3fb424..619d09713d6 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1314,31 +1314,6 @@ proc/atan2(x, y) if(!x && !y) return 0 return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y)) -proc/rotate_icon(file, state, step = 1, aa = FALSE) - var icon/base = icon(file, state) - - var w, h, w2, h2 - - if(aa) - aa++ - w = base.Width() - w2 = w * aa - h = base.Height() - h2 = h * aa - - var icon{result = icon(base); temp} - - for(var/angle in 0 to 360 step step) - if(angle == 0 ) continue - if(angle == 360) continue - temp = icon(base) - if(aa) temp.Scale(w2, h2) - temp.Turn(angle) - if(aa) temp.Scale(w, h) - result.Insert(temp, "[angle]") - - return result - /proc/format_text(text) return replacetext(replacetext(text,"\proper ",""),"\improper ","") diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index ff902473329..551b729028e 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -3,7 +3,6 @@ GLOBAL_LIST_EMPTY(all_species) GLOBAL_LIST_EMPTY(all_languages) GLOBAL_LIST_EMPTY(language_keys) // Table of say codes for all languages GLOBAL_LIST_EMPTY(all_superheroes) -GLOBAL_LIST_EMPTY(all_nations) GLOBAL_LIST_INIT(whitelisted_species, list()) GLOBAL_LIST_INIT(clients, list()) //list of all clients diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index 874c87c0758..f0bb813a336 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -1,6 +1,5 @@ var/global/obj/effect/overlay/plmaster = null var/global/obj/effect/overlay/slmaster = null -var/global/obj/effect/overlay/icemaster = null // Event Manager, the manager for events. var/datum/event_manager/event_manager = new() diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm index 7dfa8020cb8..a6042386b3d 100644 --- a/code/_onclick/click_override.dm +++ b/code/_onclick/click_override.dm @@ -43,26 +43,50 @@ ..() /datum/middleClickOverride/power_gloves - var/last_shocked = 0 - var/shock_delay = 120 -/datum/middleClickOverride/power_gloves/onClick(var/atom/A, var/mob/living/user) +/datum/middleClickOverride/power_gloves/onClick(atom/A, mob/living/carbon/human/user) + if(A == user || user.a_intent == INTENT_HELP || user.a_intent == INTENT_GRAB) + return if(user.incapacitated()) return - if(world.time < last_shocked + shock_delay) + var/obj/item/clothing/gloves/color/yellow/power/P = user.gloves + if(world.time < P.last_shocked + P.shock_delay) to_chat(user, "The gloves are still recharging.") return - if(!isliving(A)) - to_chat(user, "Shocking an inanimate object would be pointless.") - return - var/mob/living/L = A var/turf/T = get_turf(user) var/obj/structure/cable/C = locate() in T - if(!C || !istype(C)) - to_chat(user, "There is no cable here to power the gloves.") - return - user.visible_message("[user.name] fires an arc of electricity at [L]!", "You fire an arc of electricity at [L]!", "You hear the loud crackle of electricity!") - playsound(user.loc, 'sound/effects/eleczap.ogg', 75, 1) - user.Beam(L,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) - electrocute_mob(L, C, user) - last_shocked = world.time + if(!P.unlimited_power) + if(!C || !istype(C)) + to_chat(user, "There is no cable here to power the gloves.") + return + var/turf/target_turf = get_turf(A) + target_turf.hotspot_expose(2000, 400) + playsound(user.loc, 'sound/effects/eleczap.ogg', 40, 1) + + var/atom/beam_from = user + var/atom/target_atom = A + + for(var/i in 0 to 3) + beam_from.Beam(target_atom, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 6) + if(isliving(target_atom)) + var/mob/living/L = target_atom + if(user.a_intent == INTENT_DISARM) + L.Weaken(3) + else + if(P.unlimited_power) + L.electrocute_act(1000, P, safety = TRUE, override = TRUE) //Just kill them + else + electrocute_mob(L, C, P) + break + var/list/next_shocked = list() + for(var/atom/movable/AM in orange(3, target_atom)) + if(AM == user || istype(AM, /obj/effect) || isobserver(AM)) + continue + next_shocked.Add(AM) + + beam_from = target_atom + target_atom = pick(next_shocked) + A = target_atom + next_shocked.Cut() + + P.last_shocked = world.time \ No newline at end of file diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm new file mode 100644 index 00000000000..feb57d83c05 --- /dev/null +++ b/code/_onclick/hud/blob_overmind.dm @@ -0,0 +1,196 @@ +/mob/camera/blob/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/blob_overmind(src) + +/obj/screen/blob + icon = 'icons/mob/blob.dmi' + +/obj/screen/blob/MouseEntered(location,control,params) + openToolTip(usr,src,params,title = name,content = desc, theme = "blob") + +/obj/screen/blob/MouseExited() + closeToolTip(usr) + +/obj/screen/blob/BlobHelp + icon_state = "ui_help" + name = "Blob Help" + desc = "Help on playing blob!" + +/obj/screen/blob/BlobHelp/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.blob_help() + +/obj/screen/blob/JumpToNode + icon_state = "ui_tonode" + name = "Jump to Node" + desc = "Moves your camera to a selected blob node." + +/obj/screen/blob/JumpToNode/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.jump_to_node() + +/obj/screen/blob/JumpToCore + icon_state = "ui_tocore" + name = "Jump to Core" + desc = "Moves your camera to your blob core." + +/obj/screen/blob/JumpToCore/MouseEntered(location,control,params) + if(hud && hud.mymob && isovermind(hud.mymob)) + name = initial(name) + desc = initial(desc) + ..() + +/obj/screen/blob/JumpToCore/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.transport_core() + +/obj/screen/blob/Blobbernaut + icon_state = "ui_blobbernaut" + name = "Produce Blobbernaut (20)" + desc = "Produces a strong, but dumb blobbernaut from a factory blob for 20 resources.
The factory blob will be destroyed in the process." + +/obj/screen/blob/Blobbernaut/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.create_blobbernaut() + +/obj/screen/blob/StorageBlob + icon_state = "ui_storage" + name = "Produce Storage Blob (40)" + desc = "Produces a storage blob for 40 resources.
Storage blobs will raise your max resource cap by 50." + +/obj/screen/blob/StorageBlob/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.create_storage() + +/obj/screen/blob/ResourceBlob + icon_state = "ui_resource" + name = "Produce Resource Blob (40)" + desc = "Produces a resource blob for 40 resources.
Resource blobs will give you resources every few seconds." + +/obj/screen/blob/ResourceBlob/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.create_resource() + +/obj/screen/blob/NodeBlob + icon_state = "ui_node" + name = "Produce Node Blob (60)" + desc = "Produces a node blob for 60 resources.
Node blobs will expand and activate nearby resource and factory blobs." + +/obj/screen/blob/NodeBlob/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.create_node() + +/obj/screen/blob/FactoryBlob + icon_state = "ui_factory" + name = "Produce Factory Blob (60)" + desc = "Produces a factory blob for 60 resources.
Factory blobs will produce spores every few seconds." + +/obj/screen/blob/FactoryBlob/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.create_factory() + +/obj/screen/blob/ReadaptChemical + icon_state = "ui_chemswap" + name = "Readapt Chemical (50)" + desc = "Randomly rerolls your chemical for 50 resources." + +/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params) + if(hud && hud.mymob && isovermind(hud.mymob)) + name = initial(name) + desc = initial(desc) + ..() + +/obj/screen/blob/ReadaptChemical/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.chemical_reroll() + +/obj/screen/blob/RelocateCore + icon_state = "ui_swap" + name = "Relocate Core (80)" + desc = "Swaps a node and your core for 80 resources." + +/obj/screen/blob/RelocateCore/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.relocate_core() + +/obj/screen/blob/Split + icon_state = "ui_split" + name = "Split consciousness (100)" + desc = "Creates another Blob Overmind at the nearest node. One use only.
Offsprings are be unable to use this ability." + +/obj/screen/blob/Split/Click() + if(isovermind(usr)) + var/mob/camera/blob/B = usr + B.split_consciousness() + +/datum/hud/blob_overmind/New(mob/user) + ..() + var/obj/screen/using + + blobpwrdisplay = new /obj/screen() + blobpwrdisplay.name = "blob power" + blobpwrdisplay.icon_state = "block" + blobpwrdisplay.screen_loc = ui_health + static_inventory += blobpwrdisplay + + blobhealthdisplay = new /obj/screen() + blobhealthdisplay.name = "blob health" + blobhealthdisplay.icon_state = "block" + blobhealthdisplay.screen_loc = ui_internal + static_inventory += blobhealthdisplay + + using = new /obj/screen/blob/BlobHelp() + using.screen_loc = "WEST:6,NORTH:-3" + static_inventory += using + + using = new /obj/screen/blob/JumpToNode() + using.screen_loc = ui_inventory + static_inventory += using + + using = new /obj/screen/blob/JumpToCore() + using.screen_loc = ui_zonesel + using.hud = src + static_inventory += using + + using = new /obj/screen/blob/Blobbernaut() + using.screen_loc = ui_id + static_inventory += using + + using = new /obj/screen/blob/StorageBlob() + using.screen_loc = ui_belt + static_inventory += using + + using = new /obj/screen/blob/ResourceBlob() + using.screen_loc = ui_back + static_inventory += using + + using = new /obj/screen/blob/NodeBlob() + using.screen_loc = using.screen_loc = ui_rhand + static_inventory += using + + using = new /obj/screen/blob/FactoryBlob() + using.screen_loc = using.screen_loc = ui_lhand + static_inventory += using + + using = new /obj/screen/blob/ReadaptChemical() + using.screen_loc = ui_storage1 + using.hud = src + static_inventory += using + + using = new /obj/screen/blob/RelocateCore() + using.screen_loc = ui_storage2 + static_inventory += using + + using = new /obj/screen/blob/Split() + using.screen_loc = ui_acti + static_inventory += using \ No newline at end of file diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index 8cf38a88eb9..a82c847a246 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -24,24 +24,4 @@ mymob.pullin.icon = 'icons/mob/screen_corgi.dmi' mymob.pullin.update_icon(mymob) mymob.pullin.screen_loc = ui_construct_pull - static_inventory += mymob.pullin - - -/mob/camera/blob/create_mob_hud() - if(client && !hud_used) - hud_used = new /datum/hud/blob_overmind(src) - -/datum/hud/blob_overmind/New(mob/user) - ..() - - blobpwrdisplay = new /obj/screen() - blobpwrdisplay.name = "blob power" - blobpwrdisplay.icon_state = "block" - blobpwrdisplay.screen_loc = ui_health - static_inventory += blobpwrdisplay - - blobhealthdisplay = new /obj/screen() - blobhealthdisplay.name = "blob health" - blobhealthdisplay.icon_state = "block" - blobhealthdisplay.screen_loc = ui_internal - static_inventory += blobhealthdisplay \ No newline at end of file + static_inventory += mymob.pullin \ No newline at end of file diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 47036da9cf8..bed8c64b054 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -24,7 +24,7 @@ return FALSE /obj/attackby(obj/item/I, mob/living/user, params) - return ..() || (can_be_hit && isitem(I) && I.attack_obj(src, user)) + return ..() || (can_be_hit && I.attack_obj(src, user)) /mob/living/attackby(obj/item/I, mob/living/user, params) user.changeNext_move(CLICK_CD_MELEE) @@ -37,8 +37,6 @@ SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user) if(flags & (NOBLUDGEON)) return 0 - if(check_martial_counter(M, user)) - return 0 if(can_operate(M)) //Checks if mob is lying down on table for surgery if(istype(src,/obj/item/robot_parts))//popup override for direct attach if(!attempt_initiate_surgery(src, M, user,1)) diff --git a/code/_onclick/overmind.dm b/code/_onclick/overmind.dm index 91f24465569..8ace273dd8f 100644 --- a/code/_onclick/overmind.dm +++ b/code/_onclick/overmind.dm @@ -1,17 +1,35 @@ // Blob Overmind Controls -/mob/camera/blob/CtrlClickOn(var/atom/A) // Expand blob +/mob/camera/blob/ClickOn(var/atom/A, var/params) //Expand blob + var/list/modifiers = params2list(params) + if(modifiers["middle"]) + MiddleClickOn(A) + return + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) + AltClickOn(A) + return + if(modifiers["ctrl"]) + CtrlClickOn(A) + return var/turf/T = get_turf(A) if(T) expand_blob(T) -/mob/camera/blob/MiddleClickOn(var/atom/A) // Rally spores +/mob/camera/blob/MiddleClickOn(atom/A) //Rally spores var/turf/T = get_turf(A) if(T) rally_spores(T) -/mob/camera/blob/AltClickOn(var/atom/A) // Create a shield +/mob/camera/blob/CtrlClickOn(atom/A) //Create a shield var/turf/T = get_turf(A) if(T) - create_shield(T) \ No newline at end of file + create_shield(T) + +/mob/camera/blob/AltClickOn(atom/A) //Remove a blob + var/turf/T = get_turf(A) + if(T) + remove_blob(T) \ No newline at end of file diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm deleted file mode 100644 index 8d22febee61..00000000000 --- a/code/controllers/communications.dm +++ /dev/null @@ -1,345 +0,0 @@ -/* - HOW IT WORKS - - The radio_controller is a global object maintaining all radio transmissions, think about it as about "ether". - Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way. - procs: - - add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null) - Adds listening object. - parameters: - device - device receiving signals, must have proc receive_signal (see description below). - one device may listen several frequencies, but not same frequency twice. - new_frequency - see possibly frequencies below; - filter - thing for optimization. Optional, but recommended. - All filters should be consolidated in this file, see defines later. - Device without listening filter will receive all signals (on specified frequency). - Device with filter will receive any signals sent without filter. - Device with filter will not receive any signals sent with different filter. - returns: - Reference to frequency object. - - remove_object (obj/device, old_frequency) - Obliviously, after calling this proc, device will not receive any signals on old_frequency. - Other frequencies will left unaffected. - - return_frequency(var/frequency as num) - returns: - Reference to frequency object. Use it if you need to send and do not need to listen. - - radio_frequency is a global object maintaining list of devices that listening specific frequency. - procs: - - post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null) - Sends signal to all devices that wants such signal. - parameters: - source - object, emitted signal. Usually, devices will not receive their own signals. - signal - see description below. - filter - described above. - range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels. - - obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param) - Handler from received signals. By default does nothing. Define your own for your object. - Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn() - parameters: - signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return! - receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO. - TRANSMISSION_WIRE is currently unused. - receive_param - for TRANSMISSION_RADIO here comes frequency. - - datum/signal - vars: - source - an object that emitted signal. Used for debug and bearing. - data - list with transmitting data. Usual use pattern: - data["msg"] = "hello world" - encryption - Some number symbolizing "encryption key". - Note that game actually do not use any cryptography here. - If receiving object don't know right key, it must ignore encrypted signal in its receive_signal. - -*/ - -var/const/DISPLAY_FREQ = 1435 //status displays -var/const/ATMOS_FIRE_FREQ = 1437 //air alarms -var/const/ENGINE_FREQ = 1438 //engine components -var/const/ATMOS_VENTSCRUB = 1439 //vents, scrubbers, atmos control -var/const/ATMOS_DISTRO_FREQ = 1443 //distro loop -var/const/ATMOS_TANKS_FREQ = 1441 //atmos supply tanks -var/const/BOT_BEACON_FREQ = 1445 //bot navigation beacons -var/const/AIRLOCK_FREQ = 1449 //airlock controls, electropack, magnets - -var/const/RSD_FREQ = 1457 //radio signal device -var/const/IMPL_FREQ = 1451 //tracking implant - -var/const/RADIO_LOW_FREQ = 1200 //minimum radio freq -var/const/PUBLIC_LOW_FREQ = 1441 //minimum radio chat freq -var/const/PUBLIC_HIGH_FREQ = 1489 //maximum radio chat freq -var/const/RADIO_HIGH_FREQ = 1600 //maximum radio freq - -var/const/SYND_FREQ = 1213 -var/const/SYNDTEAM_FREQ = 1244 -var/const/DTH_FREQ = 1341 //Special Operations -var/const/AI_FREQ = 1343 -var/const/ERT_FREQ = 1345 -var/const/COMM_FREQ = 1353 //Command -var/const/BOT_FREQ = 1447 //mulebot, secbot, ed209 - - -// department channels -var/const/PUB_FREQ = 1459 //standard radio chat -var/const/SEC_FREQ = 1359 //security -var/const/ENG_FREQ = 1357 //engineering -var/const/SCI_FREQ = 1351 //science -var/const/MED_FREQ = 1355 //medical -var/const/SUP_FREQ = 1347 //cargo -var/const/SRV_FREQ = 1349 //service - -// internal department channels -var/const/MED_I_FREQ = 1485 -var/const/SEC_I_FREQ = 1475 - -var/list/radiochannels = list( - "Common" = PUB_FREQ, - "Science" = SCI_FREQ, - "Command" = COMM_FREQ, - "Medical" = MED_FREQ, - "Engineering" = ENG_FREQ, - "Security" = SEC_FREQ, - "Response Team" = ERT_FREQ, - "Special Ops" = DTH_FREQ, - "Syndicate" = SYND_FREQ, - "SyndTeam" = SYNDTEAM_FREQ, - "Supply" = SUP_FREQ, - "Service" = SRV_FREQ, - "AI Private" = AI_FREQ, - "Medical(I)" = MED_I_FREQ, - "Security(I)" = SEC_I_FREQ -) - -// central command channels, i.e deathsquid & response teams -var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ) - -// Antag channels, i.e. Syndicate -var/list/ANTAG_FREQS = list(SYND_FREQ, SYNDTEAM_FREQ) - -//Department channels, arranged lexically -var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ) - -#define TRANSMISSION_WIRE 0 -#define TRANSMISSION_RADIO 1 - -/proc/frequency_span_class(var/frequency) - // Antags! - if(frequency in ANTAG_FREQS) - return "syndradio" - // centcomm channels (deathsquid and ert) - if(frequency in CENT_FREQS) - return "centradio" - // command channel - if(frequency == COMM_FREQ) - return "comradio" - // AI private channel - if(frequency == AI_FREQ) - return "airadio" - // department radio formatting (poorly optimized, ugh) - if(frequency == SEC_FREQ) - return "secradio" - if(frequency == ENG_FREQ) - return "engradio" - if(frequency == SCI_FREQ) - return "sciradio" - if(frequency == MED_FREQ) - return "medradio" - if(frequency == SUP_FREQ) - return "supradio" - if(frequency == SRV_FREQ) - return "srvradio" - if(frequency in DEPT_FREQS) - return "deptradio" - - return "radio" - -/* filters */ -//When devices register with the radio controller, they might register under a certain filter. -//Other devices can then choose to send signals to only those devices that belong to a particular filter. -//This is done for performance, so we don't send signals to lots of machines unnecessarily. - -//This filter is special because devices belonging to default also recieve signals sent to any other filter. -var/const/RADIO_DEFAULT = "radio_default" - -var/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms -var/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms -var/const/RADIO_CHAT = "radio_telecoms" -var/const/RADIO_ATMOSIA = "radio_atmos" -var/const/RADIO_NAVBEACONS = "radio_navbeacon" -var/const/RADIO_AIRLOCK = "radio_airlock" -var/const/RADIO_SECBOT = "radio_secbot" -var/const/RADIO_HONKBOT = "radio_honkbot" -var/const/RADIO_MULEBOT = "radio_mulebot" -var/const/RADIO_CLEANBOT = "10" -var/const/RADIO_FLOORBOT = "11" -var/const/RADIO_MEDBOT = "12" -var/const/RADIO_MAGNETS = "radio_magnet" -var/const/RADIO_LOGIC = "radio_logic" - -var/global/datum/controller/radio/radio_controller - -/hook/startup/proc/createRadioController() - radio_controller = new /datum/controller/radio() - return 1 - -//callback used by objects to react to incoming radio signals -/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param) - return null - -//The global radio controller -/datum/controller/radio - var/list/datum/radio_frequency/frequencies = list() - -/datum/controller/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null) - var/f_text = num2text(new_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] - - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency - - frequency.add_listener(device, filter) - return frequency - -/datum/controller/radio/proc/remove_object(obj/device, old_frequency) - var/f_text = num2text(old_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] - - if(frequency) - frequency.remove_listener(device) - - if(frequency.devices.len == 0) - qdel(frequency) - frequencies -= f_text - - return 1 - -/datum/controller/radio/proc/return_frequency(var/new_frequency as num) - var/f_text = num2text(new_frequency) - var/datum/radio_frequency/frequency = frequencies[f_text] - - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency - - return frequency - -/datum/radio_frequency - var/frequency as num - var/list/list/obj/devices = list() - -/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/filter = null as text|null, var/range = null as num|null) - var/turf/start_point - if(range) - start_point = get_turf(source) - if(!start_point) - qdel(signal) - return 0 - if(filter) - send_to_filter(source, signal, filter, start_point, range) - send_to_filter(source, signal, RADIO_DEFAULT, start_point, range) - else - //Broadcast the signal to everyone! - for(var/next_filter in devices) - send_to_filter(source, signal, next_filter, start_point, range) - -//Sends a signal to all machines belonging to a given filter. Should be called by post_signal() -/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/filter, var/turf/start_point = null, var/range = null) - if(range && !start_point) - return - - for(var/obj/device in devices[filter]) - if(device == source) - continue - if(range) - var/turf/end_point = get_turf(device) - if(!end_point) - continue - if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) - continue - - device.receive_signal(signal, TRANSMISSION_RADIO, frequency) - -/datum/radio_frequency/proc/add_listener(obj/device as obj, var/filter as text|null) - if(!filter) - filter = RADIO_DEFAULT - //log_admin("add_listener(device=[device],filter=[filter]) frequency=[frequency]") - var/list/obj/devices_line = devices[filter] - if(!devices_line) - devices_line = new - devices[filter] = devices_line - devices_line+=device -// var/list/obj/devices_line___ = devices[filter_str] -// var/l = devices_line___.len - //log_admin("DEBUG: devices_line.len=[devices_line.len]") - //log_admin("DEBUG: devices(filter_str).len=[l]") - -/datum/radio_frequency/proc/remove_listener(obj/device) - for(var/devices_filter in devices) - var/list/devices_line = devices[devices_filter] - devices_line-=device - while(null in devices_line) - devices_line -= null - if(devices_line.len==0) - devices -= devices_filter - qdel(devices_line) - -/datum/signal - var/obj/source - - var/transmission_method = 0 //unused at the moment - //0 = wire - //1 = radio transmission - //2 = subspace transmission - - var/list/data = list() - var/encryption - - var/frequency = 0 - -/datum/signal/proc/copy_from(datum/signal/model) - source = model.source - transmission_method = model.transmission_method - data = model.data - encryption = model.encryption - frequency = model.frequency - -/datum/signal/proc/debug_print() - if(source) - . = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n" - else - . = "signal = {source = '[source]' ()\n" - for(var/i in data) - . += "data\[\"[i]\"\] = \"[data[i]]\"\n" - if(islist(data[i])) - var/list/L = data[i] - for(var/t in L) - . += "data\[\"[i]\"\] list has: [t]" - -/datum/signal/proc/get_race(mob/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - . = H.dna.species.name - else if(isbrain(M)) - var/mob/living/carbon/brain/B = M - . = B.get_race() - else if(issilicon(M)) - . = "Artificial Life" - else if(isslime(M)) - . = "Slime" - else if(isbot(M)) - . = "Bot" - else if(isanimal(M)) - . = "Domestic Animal" - else - . = "Unidentifiable" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 3a2ff120af3..01cf57aad9e 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -100,10 +100,6 @@ //game_options.txt configs - var/health_threshold_softcrit = 0 - var/health_threshold_crit = 0 - var/health_threshold_dead = -100 - var/bones_can_break = 1 var/revival_pod_plants = 1 @@ -217,6 +213,9 @@ // Automatic localhost admin disable var/disable_localhost_admin = 0 + + //Start now warning + var/start_now_confirmation = 0 /datum/configuration/New() for(var/T in subtypesof(/datum/game_mode)) @@ -359,6 +358,12 @@ if("no_dead_vote") config.vote_no_dead = 1 + + if("vote_autotransfer_initial") + config.vote_autotransfer_initial = text2num(value) + + if("vote_autotransfer_interval") + config.vote_autotransfer_interval = text2num(value) if("default_no_vote") config.vote_no_default = 1 @@ -640,6 +645,9 @@ if("disable_karma") config.disable_karma = 1 + + if("start_now_confirmation") + config.start_now_confirmation = 1 if("tick_limit_mc_init") config.tick_limit_mc_init = text2num(value) @@ -663,10 +671,6 @@ value = text2num(value) switch(name) - if("health_threshold_crit") - config.health_threshold_crit = value - if("health_threshold_dead") - config.health_threshold_dead = value if("revival_pod_plants") config.revival_pod_plants = value if("revival_cloning") diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm deleted file mode 100644 index 1fd81402544..00000000000 --- a/code/controllers/master_controller.dm +++ /dev/null @@ -1,64 +0,0 @@ -// old deprecated rusted piece of shit MC -// All this does now is misc. world init stuff because too lazy to put it somewhere else -// It used to run all of the repeating processes controlling the game but now the SMC and Process Scheduler do that - -var/global/datum/controller/game_controller/master_controller //Set in world.New() - -var/global/controller_iteration = 0 -var/global/last_tick_duration = 0 - -var/global/air_processing_killed = 0 -var/global/pipe_processing_killed = 0 - -/datum/controller/game_controller - var/list/shuttle_list // For debugging and VV - -/datum/controller/game_controller/New() - //There can be only one master_controller. Out with the old and in with the new. - if(master_controller != src) - if(istype(master_controller)) - qdel(master_controller) - master_controller = src - - var/watch=0 - if(!job_master) - watch = start_watch() - job_master = new /datum/controller/occupations() - job_master.SetupOccupations() - job_master.LoadJobs("config/jobs.txt") - log_startup_progress("Job setup complete in [stop_watch(watch)]s.") - - if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() - if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() - -/datum/controller/game_controller/Destroy() - ..() - return QDEL_HINT_HARDDEL_NOW - -/datum/controller/game_controller/proc/setup() - preloadTemplates() - if(!config.disable_away_missions) - createRandomZlevel() - // Create 6 extra space levels to put space ruins on - if(!config.disable_space_ruins) - var/timer = start_watch() - log_startup_progress("Creating random space levels...") - seedRuins(level_name_to_num(EMPTY_AREA), rand(0, 3), /area/space, space_ruins_templates) - log_startup_progress("Loaded random space levels in [stop_watch(timer)]s.") - - // load in extra levels of space ruins - - var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max) - for(var/i = 1, i <= num_extra_space, i++) - var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED) - seedRuins(zlev, rand(0, 3), /area/space, space_ruins_templates) - - space_manager.do_transition_setup() - - setupfactions() - setup_economy() - - for(var/i=0, iError setting up jobs, no job datums found") - return 0 - - for(var/J in all_jobs) - var/datum/job/job = new J() - if(!job) - continue - if(!job.faction in faction) - continue - occupations += job - name_occupations[job.title] = job - type_occupations[J] = job - - return 1 - - -/datum/controller/occupations/proc/Debug(var/text) - if(!Debug2) - return 0 - job_debug.Add(text) - return 1 - - -/datum/controller/occupations/proc/GetJob(rank) - if(!occupations.len) - SetupOccupations() - return name_occupations[rank] - -/datum/controller/occupations/proc/GetJobType(jobtype) - if(!occupations.len) - SetupOccupations() - return type_occupations[jobtype] - -/datum/controller/occupations/proc/GetPlayerAltTitle(mob/new_player/player, rank) - return player.client.prefs.GetPlayerAltTitle(GetJob(rank)) - -/datum/controller/occupations/proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0) - Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]") - if(player && player.mind && rank) - var/datum/job/job = GetJob(rank) - if(!job) - return 0 - if(jobban_isbanned(player, rank)) - return 0 - if(!job.player_old_enough(player.client)) - return 0 - if(job.available_in_playtime(player.client)) - return 0 - if(job.barred_by_disability(player.client)) - return 0 - if(!is_job_whitelisted(player, rank)) - return 0 - - var/position_limit = job.total_positions - if(!latejoin) - position_limit = job.spawn_positions - - if((job.current_positions < position_limit) || position_limit == -1) - Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]") - player.mind.assigned_role = rank - player.mind.role_alt_title = GetPlayerAltTitle(player, rank) - - // JOB OBJECTIVES OH SHIT - player.mind.job_objectives.Cut() - for(var/objectiveType in job.required_objectives) - new objectiveType(player.mind) - - // 50/50 chance of getting optional objectives. - for(var/objectiveType in job.optional_objectives) - if(prob(50)) - new objectiveType(player.mind) - - unassigned -= player - job.current_positions++ - return 1 - - Debug("AR has failed, Player: [player], Rank: [rank]") - return 0 - -/datum/controller/occupations/proc/FreeRole(var/rank) //making additional slot on the fly - var/datum/job/job = GetJob(rank) - if(job && job.current_positions >= job.total_positions && job.total_positions != -1) - job.total_positions++ - return 1 - return 0 - -/datum/controller/occupations/proc/FindOccupationCandidates(datum/job/job, level, flag) - Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]") - var/list/candidates = list() - for(var/mob/new_player/player in unassigned) - Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]") - if(jobban_isbanned(player, job.title)) - Debug("FOC isbanned failed, Player: [player]") - continue - if(!job.player_old_enough(player.client)) - Debug("FOC player not old enough, Player: [player]") - continue - if(job.available_in_playtime(player.client)) - Debug("FOC player not enough playtime, Player: [player]") - continue - if(job.barred_by_disability(player.client)) - Debug("FOC player has disability rendering them ineligible for job, Player: [player]") - continue - if(flag && !(flag in player.client.prefs.be_special)) - Debug("FOC flag failed, Player: [player], Flag: [flag], ") - continue - if(player.mind && job.title in player.mind.restricted_roles) - Debug("FOC incompatbile with antagonist role, Player: [player]") - continue - if(player.client.prefs.GetJobDepartment(job, level) & job.flag) - Debug("FOC pass, Player: [player], Level:[level]") - candidates += player - return candidates - -/datum/controller/occupations/proc/GiveRandomJob(var/mob/new_player/player) - Debug("GRJ Giving random job, Player: [player]") - for(var/datum/job/job in shuffle(occupations)) - if(!job) - continue - - if(istype(job, GetJob("Civilian"))) // We don't want to give him assistant, that's boring! - continue - - if(job.title in command_positions) //If you want a command position, select it! - continue - - if(job.title in whitelisted_positions) // No random whitelisted job, sorry! - continue - - if(job.admin_only) // No admin positions either. - continue - - if(jobban_isbanned(player, job.title)) - Debug("GRJ isbanned failed, Player: [player], Job: [job.title]") - continue - - if(!job.player_old_enough(player.client)) - Debug("GRJ player not old enough, Player: [player]") - continue - - if(job.available_in_playtime(player.client)) - Debug("GRJ player not enough playtime, Player: [player]") - continue - - if(job.barred_by_disability(player.client)) - Debug("GRJ player has disability rendering them ineligible for job, Player: [player]") - continue - - if(player.mind && job.title in player.mind.restricted_roles) - Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") - continue - - if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) - Debug("GRJ Random job given, Player: [player], Job: [job]") - AssignRole(player, job.title) - unassigned -= player - break - -/datum/controller/occupations/proc/ResetOccupations() - for(var/mob/new_player/player in GLOB.player_list) - if((player) && (player.mind)) - player.mind.assigned_role = null - player.mind.special_role = null - SetupOccupations() - unassigned = list() - return - - -///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check -/datum/controller/occupations/proc/FillHeadPosition() - for(var/level = 1 to 3) - for(var/command_position in command_positions) - var/datum/job/job = GetJob(command_position) - if(!job) - continue - var/list/candidates = FindOccupationCandidates(job, level) - if(!candidates.len) - continue - - var/list/filteredCandidates = list() - - for(var/mob/V in candidates) - // Log-out during round-start? What a bad boy, no head position for you! - if(!V.client) - continue - filteredCandidates += V - - if(!filteredCandidates.len) - continue - - var/mob/new_player/candidate = pick(filteredCandidates) - if(AssignRole(candidate, command_position)) - return 1 - - return 0 - - -///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level -/datum/controller/occupations/proc/CheckHeadPositions(var/level) - for(var/command_position in command_positions) - var/datum/job/job = GetJob(command_position) - if(!job) - continue - var/list/candidates = FindOccupationCandidates(job, level) - if(!candidates.len) - continue - var/mob/new_player/candidate = pick(candidates) - AssignRole(candidate, command_position) - - -/datum/controller/occupations/proc/FillAIPosition() - if(config && !config.allow_ai) - return 0 - - var/ai_selected = 0 - var/datum/job/job = GetJob("AI") - if(!job) - return 0 - - for(var/i = job.total_positions, i > 0, i--) - for(var/level = 1 to 3) - var/list/candidates = list() - candidates = FindOccupationCandidates(job, level) - if(candidates.len) - var/mob/new_player/candidate = pick(candidates) - if(AssignRole(candidate, "AI")) - ai_selected++ - break - - if(ai_selected) - return 1 - - return 0 - - -/** Proc DivideOccupations -* fills var "assigned_role" for all ready players. -* This proc must not have any side effect besides of modifying "assigned_role". -**/ -/datum/controller/occupations/proc/DivideOccupations() - //Setup new player list and get the jobs list - Debug("Running DO") - SetupOccupations() - - //Holder for Triumvirate is stored in the ticker, this just processes it - if(ticker) - for(var/datum/job/ai/A in occupations) - if(ticker.triai) - A.spawn_positions = 3 - - //Get the players who are ready - for(var/mob/new_player/player in GLOB.player_list) - if(player.ready && player.mind && !player.mind.assigned_role) - unassigned += player - if(player.client.prefs.randomslot) - player.client.prefs.load_random_character_slot(player.client) - - Debug("DO, Len: [unassigned.len]") - if(unassigned.len == 0) - return 0 - - //Shuffle players and jobs - unassigned = shuffle(unassigned) - - HandleFeedbackGathering() - - //People who wants to be assistants, sure, go on. - Debug("DO, Running Civilian Check 1") - var/datum/job/civ = new /datum/job/civilian() - var/list/civilian_candidates = FindOccupationCandidates(civ, 3) - Debug("AC1, Candidates: [civilian_candidates.len]") - for(var/mob/new_player/player in civilian_candidates) - Debug("AC1 pass, Player: [player]") - AssignRole(player, "Civilian") - civilian_candidates -= player - Debug("DO, AC1 end") - - //Select one head - Debug("DO, Running Head Check") - FillHeadPosition() - Debug("DO, Head Check end") - - //Check for an AI - Debug("DO, Running AI Check") - FillAIPosition() - Debug("DO, AI Check end") - - //Other jobs are now checked - Debug("DO, Running Standard Check") - - - // New job giving system by Donkie - // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all. - // Hopefully this will add more randomness and fairness to job giving. - - // Loop through all levels from high to low - var/list/shuffledoccupations = shuffle(occupations) - for(var/level = 1 to 3) - //Check the head jobs first each level - CheckHeadPositions(level) - - // Loop through all unassigned players - for(var/mob/new_player/player in unassigned) - - // Loop through all jobs - for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY - if(!job) - continue - - if(jobban_isbanned(player, job.title)) - Debug("DO isbanned failed, Player: [player], Job:[job.title]") - continue - - if(!job.player_old_enough(player.client)) - Debug("DO player not old enough, Player: [player], Job:[job.title]") - continue - - if(job.available_in_playtime(player.client)) - Debug("DO player not enough playtime, Player: [player], Job:[job.title]") - continue - - if(job.barred_by_disability(player.client)) - Debug("DO player has disability rendering them ineligible for job, Player: [player], Job:[job.title]") - continue - - if(player.mind && job.title in player.mind.restricted_roles) - Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") - continue - - if(!is_job_whitelisted(player, job.title)) - Debug("DO player not whitelisted, Player: [player], Job:[job.title]") - continue - - // If the player wants that job on this level, then try give it to him. - if(player.client.prefs.GetJobDepartment(job, level) & job.flag) - - // If the job isn't filled - if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) - Debug("DO pass, Player: [player], Level:[level], Job:[job.title]") - Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]") - AssignRole(player, job.title) - unassigned -= player - break - - // Hand out random jobs to the people who didn't get any in the last check - // Also makes sure that they got their preference correct - for(var/mob/new_player/player in unassigned) - if(player.client.prefs.alternate_option == GET_RANDOM_JOB) - GiveRandomJob(player) - - Debug("DO, Standard Check end") - - Debug("DO, Running AC2") - - // Antags, who have to get in, come first - for(var/mob/new_player/player in unassigned) - if(player.mind.special_role) - GiveRandomJob(player) - if(player in unassigned) - AssignRole(player, "Civilian") - - // Then we assign what we can to everyone else. - for(var/mob/new_player/player in unassigned) - if(player.client.prefs.alternate_option == BE_ASSISTANT) - Debug("AC2 Assistant located, Player: [player]") - AssignRole(player, "Civilian") - else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY) - player.ready = 0 - unassigned -= player - - return 1 - -/datum/controller/occupations/proc/AssignRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0) - if(!H) - return null - var/datum/job/job = GetJob(rank) - - H.job = rank - - var/alt_title = null - - if(H.mind) - H.mind.assigned_role = rank - alt_title = H.mind.role_alt_title - - CreateMoneyAccount(H, rank, job) - - to_chat(H, "You are the [alt_title ? alt_title : rank].") - to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.") - to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") - if(job.is_service) - to_chat(H, "As a member of Service, make sure to read up on your Department SOP") - if(job.is_supply) - to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") - if(job.is_command) - to_chat(H, "As an important member of Command, read up on your Department SOP") - if(job.is_legal) - to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") - if(job.is_engineering) - to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") - if(job.is_medical) - to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") - if(job.is_science) - to_chat(H, "As a member of Science, make sure to read up on your Department SOP") - if(job.is_security) - to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") - if(job.req_admin_notify) - to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.") - - return H -/datum/controller/occupations/proc/EquipRank(mob/living/carbon/human/H, rank, joined_late = 0) // Equip and put them in an area - if(!H) - return null - - var/datum/job/job = GetJob(rank) - - H.job = rank - - if(!joined_late) - var/turf/T = null - var/obj/S = null - for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list) - if(sloc.name != rank) - continue - if(locate(/mob/living) in sloc.loc) - continue - S = sloc - break - if(!S) - S = locate("start*[rank]") // use old stype - if(!S) // still no spawn, fall back to the arrivals shuttle - for(var/turf/TS in get_area_turfs(/area/shuttle/arrival)) - if(!TS.density) - var/clear = 1 - for(var/obj/O in TS) - if(O.density) - clear = 0 - break - if(clear) - T = TS - continue - - if(isturf(S)) - T = S - else if(istype(S, /obj/effect/landmark/start) && isturf(S.loc)) - T = S.loc - - if(T) - H.loc = T - // Moving wheelchair if they have one - if(H.buckled && istype(H.buckled, /obj/structure/chair/wheelchair)) - H.buckled.loc = H.loc - H.buckled.dir = H.dir - - if(job) - var/new_mob = job.equip(H) - if(ismob(new_mob)) - H = new_mob - - if(job && H) - job.after_spawn(H) - - //Gives glasses to the vision impaired - if(H.disabilities & DISABILITY_FLAG_NEARSIGHTED) - var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) - if(equipped != 1) - var/obj/item/clothing/glasses/G = H.glasses - if(istype(G) && !G.prescription) - G.prescription = 1 - G.name = "prescription [G.name]" - return H - - - - - -/datum/controller/occupations/proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist - if(!config.load_jobs_from_txt) - return 0 - - var/list/jobEntries = file2list(jobsfile) - - for(var/job in jobEntries) - if(!job) - continue - - job = trim(job) - if(!length(job)) - continue - - var/pos = findtext(job, "=") - var/name = null - var/value = null - - if(pos) - name = copytext(job, 1, pos) - value = copytext(job, pos + 1) - else - continue - - if(name && value) - var/datum/job/J = GetJob(name) - if(!J) continue - J.total_positions = text2num(value) - J.spawn_positions = text2num(value) - if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now - J.total_positions = 0 - - return 1 - - -/datum/controller/occupations/proc/HandleFeedbackGathering() - for(var/datum/job/job in occupations) - var/tmp_str = "|[job.title]|" - - var/level1 = 0 //high - var/level2 = 0 //medium - var/level3 = 0 //low - var/level4 = 0 //never - var/level5 = 0 //banned - var/level6 = 0 //account too young - var/level7 = 0 //has disability rendering them ineligible - for(var/mob/new_player/player in GLOB.player_list) - if(!(player.ready && player.mind && !player.mind.assigned_role)) - continue //This player is not ready - if(jobban_isbanned(player, job.title)) - level5++ - continue - if(!job.player_old_enough(player.client)) - level6++ - continue - if(job.available_in_playtime(player.client)) - level6++ - continue - if(job.barred_by_disability(player.client)) - level7++ - continue - if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) - level1++ - else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) - level2++ - else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag) - level3++ - else level4++ //not selected - - tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|DISABILITY=[level7]|-" - feedback_add_details("job_preferences",tmp_str) - - -/datum/controller/occupations/proc/CreateMoneyAccount(mob/living/H, rank, datum/job/job) - var/datum/money_account/M = create_account(H.real_name, rand(50,500)*10, null) - var/remembered_info = "" - - remembered_info += "Your account number is: #[M.account_number]
" - remembered_info += "Your account pin is: [M.remote_access_pin]
" - remembered_info += "Your account funds are: $[M.money]
" - - if(M.transaction_log.len) - var/datum/transaction/T = M.transaction_log[1] - remembered_info += "Your account was created: [T.time], [T.date] at [T.source_terminal]
" - H.mind.store_memory(remembered_info) - - // If they're head, give them the account info for their department - if(job && job.head_position) - remembered_info = "" - var/datum/money_account/department_account = department_accounts[job.department] - - if(department_account) - remembered_info += "Your department's account number is: #[department_account.account_number]
" - remembered_info += "Your department's account pin is: [department_account.remote_access_pin]
" - remembered_info += "Your department's account funds are: $[department_account.money]
" - - H.mind.store_memory(remembered_info) - - H.mind.initial_account = M - - spawn(0) - to_chat(H, "Your account number is: [M.account_number], your account pin is: [M.remote_access_pin]") +SUBSYSTEM_DEF(jobs) + name = "Jobs" + init_order = INIT_ORDER_JOBS // 12 + flags = SS_NO_FIRE + + //List of all jobs + var/list/occupations = list() + var/list/name_occupations = list() //Dict of all jobs, keys are titles + var/list/type_occupations = list() //Dict of all jobs, keys are types + var/list/prioritized_jobs = list() // List of jobs set to priority by HoP/Captain + //Players who need jobs + var/list/unassigned = list() + //Debug info + var/list/job_debug = list() + +/datum/controller/subsystem/jobs/Initialize(timeofday) + if(!occupations.len) + SetupOccupations() + LoadJobs("config/jobs.txt") + ..() + +/datum/controller/subsystem/jobs/proc/SetupOccupations(var/list/faction = list("Station")) + occupations = list() + var/list/all_jobs = subtypesof(/datum/job) + if(!all_jobs.len) + to_chat(world, "Error setting up jobs, no job datums found") + return 0 + + for(var/J in all_jobs) + var/datum/job/job = new J() + if(!job) + continue + if(!job.faction in faction) + continue + occupations += job + name_occupations[job.title] = job + type_occupations[J] = job + + return 1 + + +/datum/controller/subsystem/jobs/proc/Debug(var/text) + if(!Debug2) + return 0 + job_debug.Add(text) + return 1 + + +/datum/controller/subsystem/jobs/proc/GetJob(rank) + if(!occupations.len) + SetupOccupations() + return name_occupations[rank] + +/datum/controller/subsystem/jobs/proc/GetJobType(jobtype) + if(!occupations.len) + SetupOccupations() + return type_occupations[jobtype] + +/datum/controller/subsystem/jobs/proc/GetPlayerAltTitle(mob/new_player/player, rank) + return player.client.prefs.GetPlayerAltTitle(GetJob(rank)) + +/datum/controller/subsystem/jobs/proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0) + Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]") + if(player && player.mind && rank) + var/datum/job/job = GetJob(rank) + if(!job) + return 0 + if(jobban_isbanned(player, rank)) + return 0 + if(!job.player_old_enough(player.client)) + return 0 + if(job.available_in_playtime(player.client)) + return 0 + if(job.barred_by_disability(player.client)) + return 0 + if(!is_job_whitelisted(player, rank)) + return 0 + + var/position_limit = job.total_positions + if(!latejoin) + position_limit = job.spawn_positions + + if((job.current_positions < position_limit) || position_limit == -1) + Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]") + player.mind.assigned_role = rank + player.mind.role_alt_title = GetPlayerAltTitle(player, rank) + + // JOB OBJECTIVES OH SHIT + player.mind.job_objectives.Cut() + for(var/objectiveType in job.required_objectives) + new objectiveType(player.mind) + + // 50/50 chance of getting optional objectives. + for(var/objectiveType in job.optional_objectives) + if(prob(50)) + new objectiveType(player.mind) + + unassigned -= player + job.current_positions++ + return 1 + + Debug("AR has failed, Player: [player], Rank: [rank]") + return 0 + +/datum/controller/subsystem/jobs/proc/FreeRole(var/rank) //making additional slot on the fly + var/datum/job/job = GetJob(rank) + if(job && job.current_positions >= job.total_positions && job.total_positions != -1) + job.total_positions++ + return 1 + return 0 + +/datum/controller/subsystem/jobs/proc/FindOccupationCandidates(datum/job/job, level, flag) + Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]") + var/list/candidates = list() + for(var/mob/new_player/player in unassigned) + Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]") + if(jobban_isbanned(player, job.title)) + Debug("FOC isbanned failed, Player: [player]") + continue + if(!job.player_old_enough(player.client)) + Debug("FOC player not old enough, Player: [player]") + continue + if(job.available_in_playtime(player.client)) + Debug("FOC player not enough playtime, Player: [player]") + continue + if(job.barred_by_disability(player.client)) + Debug("FOC player has disability rendering them ineligible for job, Player: [player]") + continue + if(flag && !(flag in player.client.prefs.be_special)) + Debug("FOC flag failed, Player: [player], Flag: [flag], ") + continue + if(player.mind && job.title in player.mind.restricted_roles) + Debug("FOC incompatbile with antagonist role, Player: [player]") + continue + if(player.client.prefs.GetJobDepartment(job, level) & job.flag) + Debug("FOC pass, Player: [player], Level:[level]") + candidates += player + return candidates + +/datum/controller/subsystem/jobs/proc/GiveRandomJob(var/mob/new_player/player) + Debug("GRJ Giving random job, Player: [player]") + for(var/datum/job/job in shuffle(occupations)) + if(!job) + continue + + if(istype(job, GetJob("Civilian"))) // We don't want to give him assistant, that's boring! + continue + + if(job.title in command_positions) //If you want a command position, select it! + continue + + if(job.title in whitelisted_positions) // No random whitelisted job, sorry! + continue + + if(job.admin_only) // No admin positions either. + continue + + if(jobban_isbanned(player, job.title)) + Debug("GRJ isbanned failed, Player: [player], Job: [job.title]") + continue + + if(!job.player_old_enough(player.client)) + Debug("GRJ player not old enough, Player: [player]") + continue + + if(job.available_in_playtime(player.client)) + Debug("GRJ player not enough playtime, Player: [player]") + continue + + if(job.barred_by_disability(player.client)) + Debug("GRJ player has disability rendering them ineligible for job, Player: [player]") + continue + + if(player.mind && job.title in player.mind.restricted_roles) + Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") + continue + + if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) + Debug("GRJ Random job given, Player: [player], Job: [job]") + AssignRole(player, job.title) + unassigned -= player + break + +/datum/controller/subsystem/jobs/proc/ResetOccupations() + for(var/mob/new_player/player in GLOB.player_list) + if((player) && (player.mind)) + player.mind.assigned_role = null + player.mind.special_role = null + SetupOccupations() + unassigned = list() + return + + +///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check +/datum/controller/subsystem/jobs/proc/FillHeadPosition() + for(var/level = 1 to 3) + for(var/command_position in command_positions) + var/datum/job/job = GetJob(command_position) + if(!job) + continue + var/list/candidates = FindOccupationCandidates(job, level) + if(!candidates.len) + continue + + var/list/filteredCandidates = list() + + for(var/mob/V in candidates) + // Log-out during round-start? What a bad boy, no head position for you! + if(!V.client) + continue + filteredCandidates += V + + if(!filteredCandidates.len) + continue + + var/mob/new_player/candidate = pick(filteredCandidates) + if(AssignRole(candidate, command_position)) + return 1 + + return 0 + + +///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level +/datum/controller/subsystem/jobs/proc/CheckHeadPositions(var/level) + for(var/command_position in command_positions) + var/datum/job/job = GetJob(command_position) + if(!job) + continue + var/list/candidates = FindOccupationCandidates(job, level) + if(!candidates.len) + continue + var/mob/new_player/candidate = pick(candidates) + AssignRole(candidate, command_position) + + +/datum/controller/subsystem/jobs/proc/FillAIPosition() + if(config && !config.allow_ai) + return 0 + + var/ai_selected = 0 + var/datum/job/job = GetJob("AI") + if(!job) + return 0 + + for(var/i = job.total_positions, i > 0, i--) + for(var/level = 1 to 3) + var/list/candidates = list() + candidates = FindOccupationCandidates(job, level) + if(candidates.len) + var/mob/new_player/candidate = pick(candidates) + if(AssignRole(candidate, "AI")) + ai_selected++ + break + + if(ai_selected) + return 1 + + return 0 + + +/** Proc DivideOccupations +* fills var "assigned_role" for all ready players. +* This proc must not have any side effect besides of modifying "assigned_role". +**/ +/datum/controller/subsystem/jobs/proc/DivideOccupations() + //Setup new player list and get the jobs list + Debug("Running DO") + SetupOccupations() + + //Holder for Triumvirate is stored in the ticker, this just processes it + if(ticker) + for(var/datum/job/ai/A in occupations) + if(ticker.triai) + A.spawn_positions = 3 + + //Get the players who are ready + for(var/mob/new_player/player in GLOB.player_list) + if(player.ready && player.mind && !player.mind.assigned_role) + unassigned += player + if(player.client.prefs.randomslot) + player.client.prefs.load_random_character_slot(player.client) + + Debug("DO, Len: [unassigned.len]") + if(unassigned.len == 0) + return 0 + + //Shuffle players and jobs + unassigned = shuffle(unassigned) + + HandleFeedbackGathering() + + //People who wants to be assistants, sure, go on. + Debug("DO, Running Civilian Check 1") + var/datum/job/civ = new /datum/job/civilian() + var/list/civilian_candidates = FindOccupationCandidates(civ, 3) + Debug("AC1, Candidates: [civilian_candidates.len]") + for(var/mob/new_player/player in civilian_candidates) + Debug("AC1 pass, Player: [player]") + AssignRole(player, "Civilian") + civilian_candidates -= player + Debug("DO, AC1 end") + + //Select one head + Debug("DO, Running Head Check") + FillHeadPosition() + Debug("DO, Head Check end") + + //Check for an AI + Debug("DO, Running AI Check") + FillAIPosition() + Debug("DO, AI Check end") + + //Other jobs are now checked + Debug("DO, Running Standard Check") + + + // New job giving system by Donkie + // This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all. + // Hopefully this will add more randomness and fairness to job giving. + + // Loop through all levels from high to low + var/list/shuffledoccupations = shuffle(occupations) + for(var/level = 1 to 3) + //Check the head jobs first each level + CheckHeadPositions(level) + + // Loop through all unassigned players + for(var/mob/new_player/player in unassigned) + + // Loop through all jobs + for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY + if(!job) + continue + + if(jobban_isbanned(player, job.title)) + Debug("DO isbanned failed, Player: [player], Job:[job.title]") + continue + + if(!job.player_old_enough(player.client)) + Debug("DO player not old enough, Player: [player], Job:[job.title]") + continue + + if(job.available_in_playtime(player.client)) + Debug("DO player not enough playtime, Player: [player], Job:[job.title]") + continue + + if(job.barred_by_disability(player.client)) + Debug("DO player has disability rendering them ineligible for job, Player: [player], Job:[job.title]") + continue + + if(player.mind && job.title in player.mind.restricted_roles) + Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") + continue + + if(!is_job_whitelisted(player, job.title)) + Debug("DO player not whitelisted, Player: [player], Job:[job.title]") + continue + + // If the player wants that job on this level, then try give it to him. + if(player.client.prefs.GetJobDepartment(job, level) & job.flag) + + // If the job isn't filled + if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) + Debug("DO pass, Player: [player], Level:[level], Job:[job.title]") + Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]") + AssignRole(player, job.title) + unassigned -= player + break + + // Hand out random jobs to the people who didn't get any in the last check + // Also makes sure that they got their preference correct + for(var/mob/new_player/player in unassigned) + if(player.client.prefs.alternate_option == GET_RANDOM_JOB) + GiveRandomJob(player) + + Debug("DO, Standard Check end") + + Debug("DO, Running AC2") + + // Antags, who have to get in, come first + for(var/mob/new_player/player in unassigned) + if(player.mind.special_role) + GiveRandomJob(player) + if(player in unassigned) + AssignRole(player, "Civilian") + + // Then we assign what we can to everyone else. + for(var/mob/new_player/player in unassigned) + if(player.client.prefs.alternate_option == BE_ASSISTANT) + Debug("AC2 Assistant located, Player: [player]") + AssignRole(player, "Civilian") + else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY) + player.ready = 0 + unassigned -= player + + return 1 + +/datum/controller/subsystem/jobs/proc/AssignRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0) + if(!H) + return null + var/datum/job/job = GetJob(rank) + + H.job = rank + + var/alt_title = null + + if(H.mind) + H.mind.assigned_role = rank + alt_title = H.mind.role_alt_title + + CreateMoneyAccount(H, rank, job) + + to_chat(H, "You are the [alt_title ? alt_title : rank].") + to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.") + to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") + if(job.is_service) + to_chat(H, "As a member of Service, make sure to read up on your Department SOP") + if(job.is_supply) + to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") + if(job.is_command) + to_chat(H, "As an important member of Command, read up on your Department SOP") + if(job.is_legal) + to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") + if(job.is_engineering) + to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") + if(job.is_medical) + to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") + if(job.is_science) + to_chat(H, "As a member of Science, make sure to read up on your Department SOP") + if(job.is_security) + to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") + if(job.req_admin_notify) + to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.") + + return H +/datum/controller/subsystem/jobs/proc/EquipRank(mob/living/carbon/human/H, rank, joined_late = 0) // Equip and put them in an area + if(!H) + return null + + var/datum/job/job = GetJob(rank) + + H.job = rank + + if(!joined_late) + var/turf/T = null + var/obj/S = null + for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list) + if(sloc.name != rank) + continue + if(locate(/mob/living) in sloc.loc) + continue + S = sloc + break + if(!S) + S = locate("start*[rank]") // use old stype + if(!S) // still no spawn, fall back to the arrivals shuttle + for(var/turf/TS in get_area_turfs(/area/shuttle/arrival)) + if(!TS.density) + var/clear = 1 + for(var/obj/O in TS) + if(O.density) + clear = 0 + break + if(clear) + T = TS + continue + + if(isturf(S)) + T = S + else if(istype(S, /obj/effect/landmark/start) && isturf(S.loc)) + T = S.loc + + if(T) + H.loc = T + // Moving wheelchair if they have one + if(H.buckled && istype(H.buckled, /obj/structure/chair/wheelchair)) + H.buckled.loc = H.loc + H.buckled.dir = H.dir + + if(job) + var/new_mob = job.equip(H) + if(ismob(new_mob)) + H = new_mob + + if(job && H) + job.after_spawn(H) + + //Gives glasses to the vision impaired + if(H.disabilities & DISABILITY_FLAG_NEARSIGHTED) + var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) + if(equipped != 1) + var/obj/item/clothing/glasses/G = H.glasses + if(istype(G) && !G.prescription) + G.prescription = 1 + G.name = "prescription [G.name]" + return H + + + + + +/datum/controller/subsystem/jobs/proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist + if(!config.load_jobs_from_txt) + return 0 + + var/list/jobEntries = file2list(jobsfile) + + for(var/job in jobEntries) + if(!job) + continue + + job = trim(job) + if(!length(job)) + continue + + var/pos = findtext(job, "=") + var/name = null + var/value = null + + if(pos) + name = copytext(job, 1, pos) + value = copytext(job, pos + 1) + else + continue + + if(name && value) + var/datum/job/J = GetJob(name) + if(!J) continue + J.total_positions = text2num(value) + J.spawn_positions = text2num(value) + if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now + J.total_positions = 0 + + return 1 + + +/datum/controller/subsystem/jobs/proc/HandleFeedbackGathering() + for(var/datum/job/job in occupations) + var/tmp_str = "|[job.title]|" + + var/level1 = 0 //high + var/level2 = 0 //medium + var/level3 = 0 //low + var/level4 = 0 //never + var/level5 = 0 //banned + var/level6 = 0 //account too young + var/level7 = 0 //has disability rendering them ineligible + for(var/mob/new_player/player in GLOB.player_list) + if(!(player.ready && player.mind && !player.mind.assigned_role)) + continue //This player is not ready + if(jobban_isbanned(player, job.title)) + level5++ + continue + if(!job.player_old_enough(player.client)) + level6++ + continue + if(job.available_in_playtime(player.client)) + level6++ + continue + if(job.barred_by_disability(player.client)) + level7++ + continue + if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) + level1++ + else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) + level2++ + else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag) + level3++ + else level4++ //not selected + + tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|DISABILITY=[level7]|-" + feedback_add_details("job_preferences",tmp_str) + + +/datum/controller/subsystem/jobs/proc/CreateMoneyAccount(mob/living/H, rank, datum/job/job) + var/datum/money_account/M = create_account(H.real_name, rand(50,500)*10, null) + var/remembered_info = "" + + remembered_info += "Your account number is: #[M.account_number]
" + remembered_info += "Your account pin is: [M.remote_access_pin]
" + remembered_info += "Your account funds are: $[M.money]
" + + if(M.transaction_log.len) + var/datum/transaction/T = M.transaction_log[1] + remembered_info += "Your account was created: [T.time], [T.date] at [T.source_terminal]
" + H.mind.store_memory(remembered_info) + + // If they're head, give them the account info for their department + if(job && job.head_position) + remembered_info = "" + var/datum/money_account/department_account = department_accounts[job.department] + + if(department_account) + remembered_info += "Your department's account number is: #[department_account.account_number]
" + remembered_info += "Your department's account pin is: [department_account.remote_access_pin]
" + remembered_info += "Your department's account funds are: $[department_account.money]
" + + H.mind.store_memory(remembered_info) + + H.mind.initial_account = M + + spawn(0) + to_chat(H, "Your account number is: [M.account_number], your account pin is: [M.remote_access_pin]") diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm new file mode 100644 index 00000000000..43c2f406365 --- /dev/null +++ b/code/controllers/subsystem/mapping.dm @@ -0,0 +1,34 @@ +SUBSYSTEM_DEF(mapping) + name = "Mapping" + init_order = INIT_ORDER_MAPPING // 9 + flags = SS_NO_FIRE + +/datum/controller/subsystem/mapping/Initialize(timeofday) + // Load all Z level templates + preloadTemplates() + // Pick a random away mission. + if(!config.disable_away_missions) + createRandomZlevel() + // Seed space ruins + if(!config.disable_space_ruins) + var/timer = start_watch() + log_startup_progress("Creating random space levels...") + seedRuins(level_name_to_num(EMPTY_AREA), rand(0, 3), /area/space, space_ruins_templates) + log_startup_progress("Loaded random space levels in [stop_watch(timer)]s.") + + // load in extra levels of space ruins + + var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max) + for(var/i = 1, i <= num_extra_space, i++) + var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED) + seedRuins(zlev, rand(0, 3), /area/space, space_ruins_templates) + + // Setup the Z-level linkage + space_manager.do_transition_setup() + // Populate mining Z-level hidden rooms + for(var/i=0, i- [ticket_name] Closed -", + "Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.", + "[span_text]Your [ticket_name] has now been closed.") + return ..() diff --git a/code/controllers/subsystem/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm similarity index 57% rename from code/controllers/subsystem/tickets.dm rename to code/controllers/subsystem/tickets/tickets.dm index b8b1f8410a0..73279033849 100644 --- a/code/controllers/subsystem/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -1,28 +1,36 @@ //Defines //Deciseconds until ticket becomes stale if unanswered. Alerts admins. -#define ADMIN_TICKET_TIMEOUT 6000 // 10 minutes +#define TICKET_TIMEOUT 6000 // 10 minutes //Decisecions before the user is allowed to open another ticket while their existing one is open. -#define ADMIN_TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes +#define TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes //Status defines -#define ADMIN_TICKET_OPEN 1 -#define ADMIN_TICKET_CLOSED 2 -#define ADMIN_TICKET_RESOLVED 3 -#define ADMIN_TICKET_STALE 4 +#define TICKET_OPEN 1 +#define TICKET_CLOSED 2 +#define TICKET_RESOLVED 3 +#define TICKET_STALE 4 SUBSYSTEM_DEF(tickets) - name = "Tickets" + name = "Admin Tickets" + var/span_text = "" + var/ticket_system_name = "Admin Tickets" + var/ticket_name = "Admin Ticket" + var/close_rights = R_ADMIN + var/list/close_messages init_order = INIT_ORDER_TICKETS wait = 300 priority = FIRE_PRIORITY_TICKETS - + flags = SS_BACKGROUND - + var/list/allTickets var/ticketCounter = 1 /datum/controller/subsystem/tickets/Initialize() + close_messages = list("- [ticket_name] Rejected! -", + "Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.", + "[span_text]Your [ticket_name] has now been closed.") LAZYINITLIST(allTickets) return ..() @@ -32,7 +40,7 @@ SUBSYSTEM_DEF(tickets) var/report for(var/num in stales) report += "[num], " - message_adminTicket("Tickets [report] have been open for over [ADMIN_TICKET_TIMEOUT / 600] minutes. Changing status to stale.") + message_staff("[span_text]Tickets [report] have been open for over [TICKET_TIMEOUT / 600] minutes. Changing status to stale.") /datum/controller/subsystem/tickets/stat_entry() ..("Tickets: [LAZYLEN(allTickets)]") @@ -40,10 +48,10 @@ SUBSYSTEM_DEF(tickets) /datum/controller/subsystem/tickets/proc/checkStaleness() var/stales = list() for(var/T in allTickets) - var/datum/admin_ticket/ticket = T - if(!(ticket.ticketState == ADMIN_TICKET_OPEN)) + var/datum/ticket/ticket = T + if(!(ticket.ticketState == TICKET_OPEN)) continue - if(world.time > ticket.timeUntilStale && (!ticket.lastAdminResponse || !ticket.adminAssigned)) + if(world.time > ticket.timeUntilStale && (!ticket.lastStaffResponse || !ticket.staffAssigned)) var/id = ticket.makeStale() stales += id return stales @@ -60,7 +68,7 @@ SUBSYSTEM_DEF(tickets) /datum/controller/subsystem/tickets/proc/resolveAllOpenTickets() // Resolve all open tickets for(var/i in allTickets) - var/datum/admin_ticket/T = i + var/datum/ticket/T = i resolveTicket(T.ticketNum) //Open a new ticket and populate details then add to the list of open tickets @@ -69,56 +77,57 @@ SUBSYSTEM_DEF(tickets) return //Check if the user has an open ticket already within the cooldown period, if so we don't create a new one and re-set the cooldown period - var/datum/admin_ticket/existingTicket = checkForOpenTicket(C) + var/datum/ticket/existingTicket = checkForOpenTicket(C) if(existingTicket) existingTicket.setCooldownPeriod() - to_chat(C.mob, "Your ticket #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.") + to_chat(C.mob, "[span_text]Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.") return if(!title) title = passedContent - var/datum/admin_ticket/T = new(title, passedContent) + var/datum/ticket/T = new(title, passedContent, getTicketCounterAndInc()) + allTickets += T T.clientName = C T.locationSent = C.mob.loc.name T.mobControlled = C.mob //Inform the user that they have opened a ticket - to_chat(C, "You have opened admin ticket number #[(SStickets.getTicketCounter() - 1)]! Please be patient and we will help you soon!") + to_chat(C, "[span_text]You have opened [ticket_name] number #[(getTicketCounter() - 1)]! Please be patient and we will help you soon!") //Set ticket state with key N to open /datum/controller/subsystem/tickets/proc/openTicket(N) - var/datum/admin_ticket/T = SStickets.allTickets[N] - if(T.ticketState != ADMIN_TICKET_OPEN) - T.ticketState = ADMIN_TICKET_OPEN + var/datum/ticket/T = allTickets[N] + if(T.ticketState != TICKET_OPEN) + T.ticketState = TICKET_OPEN return TRUE //Set ticket state with key N to resolved /datum/controller/subsystem/tickets/proc/resolveTicket(N) - var/datum/admin_ticket/T = SStickets.allTickets[N] - if(T.ticketState != ADMIN_TICKET_RESOLVED) - T.ticketState = ADMIN_TICKET_RESOLVED + var/datum/ticket/T = allTickets[N] + if(T.ticketState != TICKET_RESOLVED) + T.ticketState = TICKET_RESOLVED return TRUE //Set ticket state with key N to closed /datum/controller/subsystem/tickets/proc/closeTicket(N) - var/datum/admin_ticket/T = SStickets.allTickets[N] - if(T.ticketState != ADMIN_TICKET_CLOSED) - T.ticketState = ADMIN_TICKET_CLOSED + var/datum/ticket/T = allTickets[N] + if(T.ticketState != TICKET_CLOSED) + T.ticketState = TICKET_CLOSED return TRUE //Check if the user already has a ticket open and within the cooldown period. /datum/controller/subsystem/tickets/proc/checkForOpenTicket(client/C) - for(var/datum/admin_ticket/T in allTickets) - if(T.clientName == C && T.ticketState == ADMIN_TICKET_OPEN && (T.ticketCooldown > world.time)) + for(var/datum/ticket/T in allTickets) + if(T.clientName == C && T.ticketState == TICKET_OPEN && (T.ticketCooldown > world.time)) return T return FALSE //Check if the user has ANY ticket not resolved or closed. /datum/controller/subsystem/tickets/proc/checkForTicket(client/C) var/list/tickets = list() - for(var/datum/admin_ticket/T in allTickets) - if(T.clientName == C && (T.ticketState == ADMIN_TICKET_OPEN || T.ticketState == ADMIN_TICKET_STALE)) + for(var/datum/ticket/T in allTickets) + if(T.clientName == C && (T.ticketState == TICKET_OPEN || T.ticketState == TICKET_STALE)) tickets += T if(tickets.len) return tickets @@ -126,78 +135,77 @@ SUBSYSTEM_DEF(tickets) //return the client of a ticket number /datum/controller/subsystem/tickets/proc/returnClient(N) - var/datum/admin_ticket/T = SStickets.allTickets[N] + var/datum/ticket/T = allTickets[N] return T.clientName -/datum/controller/subsystem/tickets/proc/assignAdminToTicket(client/C, var/N) - var/datum/admin_ticket/T = SStickets.allTickets[N] - T.assignAdmin(C) +/datum/controller/subsystem/tickets/proc/assignStaffToTicket(client/C, var/N) + var/datum/ticket/T = allTickets[N] + T.assignStaff(C) return TRUE -//Single admin ticket +//Single staff ticket -/datum/admin_ticket +/datum/ticket var/ticketNum // Ticket number var/clientName // Client which opened the ticket var/timeOpened // Time the ticket was opened var/title //The initial message with links - var/list/content // content of the admin help - var/lastAdminResponse // Last admin who responded - var/lastResponseTime // When the admin last responded + var/list/content // content of the staff help + var/lastStaffResponse // Last staff member who responded + var/lastResponseTime // When the staff last responded var/locationSent // Location the player was when they send the ticket var/mobControlled // Mob they were controlling var/ticketState // State of the ticket, open, closed, resolved etc var/timeUntilStale // When the ticket goes stale var/ticketCooldown // Cooldown before allowing the user to open another ticket. - var/adminAssigned // Admin who has assigned themselves to this ticket + var/staffAssigned // Staff member who has assigned themselves to this ticket -/datum/admin_ticket/New(tit, cont) +/datum/ticket/New(tit, cont, num) title = tit content = list() content += cont timeOpened = worldtime2text() - timeUntilStale = world.time + ADMIN_TICKET_TIMEOUT + timeUntilStale = world.time + TICKET_TIMEOUT setCooldownPeriod() - ticketNum = SStickets.getTicketCounterAndInc() - ticketState = ADMIN_TICKET_OPEN - SStickets.allTickets += src + ticketNum = num + ticketState = TICKET_OPEN //Set the cooldown period for the ticket. The time when it's created plus the defined cooldown time. -/datum/admin_ticket/proc/setCooldownPeriod() - ticketCooldown = world.time + ADMIN_TICKET_DUPLICATE_COOLDOWN +/datum/ticket/proc/setCooldownPeriod() + ticketCooldown = world.time + TICKET_DUPLICATE_COOLDOWN -//Set the last admin who responded as the client passed as an arguement. -/datum/admin_ticket/proc/setLastAdminResponse(client/C) - lastAdminResponse = C +//Set the last staff who responded as the client passed as an arguement. +/datum/ticket/proc/setLastStaffResponse(client/C) + lastStaffResponse = C lastResponseTime = worldtime2text() //Return the ticket state as a colour coded text string. -/datum/admin_ticket/proc/state2text() +/datum/ticket/proc/state2text() switch(ticketState) - if(ADMIN_TICKET_OPEN) + if(TICKET_OPEN) return "OPEN" - if(ADMIN_TICKET_RESOLVED) + if(TICKET_RESOLVED) return "RESOLVED" - if(ADMIN_TICKET_CLOSED) + if(TICKET_CLOSED) return "CLOSED" - if(ADMIN_TICKET_STALE) + if(TICKET_STALE) return "STALE" -//Assign the client passed to var/adminAsssigned -/datum/admin_ticket/proc/assignAdmin(client/C) +//Assign the client passed to var/staffAsssigned +/datum/ticket/proc/assignStaff(client/C) if(!C) return - adminAssigned = C + staffAssigned = C return TRUE -/datum/admin_ticket/proc/addResponse(client/C, msg) +/datum/ticket/proc/addResponse(client/C, msg) if(C.holder) - setLastAdminResponse(C) + setLastStaffResponse(C) msg = "[C]: [msg]" content += msg -/datum/admin_ticket/proc/makeStale() - ticketState = ADMIN_TICKET_STALE +/datum/ticket/proc/makeStale() + ticketState = TICKET_STALE return ticketNum /* @@ -206,7 +214,7 @@ UI STUFF */ -/datum/controller/subsystem/tickets/proc/returnUI(tab = ADMIN_TICKET_OPEN) +/datum/controller/subsystem/tickets/proc/returnUI(tab = TICKET_OPEN) set name = "Open Ticket Interface" set category = "Tickets" @@ -214,36 +222,36 @@ UI STUFF var/trStyle = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;" var/tdStyleleft = "border-top:2px solid; border-bottom:2px solid; width:150px; text-align:center;" var/tdStyle = "border-top:2px solid; border-bottom:2px solid;" - var/datum/admin_ticket/ticket + var/datum/ticket/ticket var/dat dat += "" - dat += "

Admin Tickets

" + dat += "

[ticket_system_name]

" dat +="Refresh
Open TicketsResolved TicketsClosed Tickets" - if(tab == ADMIN_TICKET_OPEN) + if(tab == TICKET_OPEN) dat += "

Open Tickets

" dat += "" dat +="" - if(tab == ADMIN_TICKET_OPEN) + if(tab == TICKET_OPEN) for(var/T in allTickets) ticket = T - if(ticket.ticketState == ADMIN_TICKET_OPEN || ticket.ticketState == ADMIN_TICKET_STALE) - dat += "" + if(ticket.ticketState == TICKET_OPEN || ticket.ticketState == TICKET_STALE) + dat += "" else continue - else if(tab == ADMIN_TICKET_RESOLVED) + else if(tab == TICKET_RESOLVED) dat += "

Resolved Tickets

" for(var/T in allTickets) ticket = T - if(ticket.ticketState == ADMIN_TICKET_RESOLVED) + if(ticket.ticketState == TICKET_RESOLVED) dat += "" else continue - else if(tab == ADMIN_TICKET_CLOSED) + else if(tab == TICKET_CLOSED) dat += "

Closed Tickets

" for(var/T in allTickets) ticket = T - if(ticket.ticketState == ADMIN_TICKET_CLOSED) + if(ticket.ticketState == TICKET_CLOSED) dat += "" else continue @@ -255,21 +263,21 @@ UI STUFF /datum/controller/subsystem/tickets/proc/showUI(mob/user, tab) var/dat = null dat = returnUI(tab) - var/datum/browser/popup = new(user, "admintickets", "Admin Tickets", 1400, 600) + var/datum/browser/popup = new(user, ticket_system_name, ticket_system_name, 1400, 600) popup.set_content(dat) popup.open() /datum/controller/subsystem/tickets/proc/showDetailUI(mob/user, ticketID) - var/datum/admin_ticket/T = SStickets.allTickets[ticketID] + var/datum/ticket/T = allTickets[ticketID] var/status = "[T.state2text()]" - var/dat = "

Admin Tickets

" + var/dat = "

[ticket_system_name]

" dat +="Show AllRefresh" dat += "

Ticket #[T.ticketNum]

" - dat += "

[T.clientName] / [T.mobControlled] opened this ticket at [T.timeOpened] at location [T.locationSent]

" + dat += "

[T.clientName] / [T.mobControlled] opened this [ticket_name] at [T.timeOpened] at location [T.locationSent]

" dat += "

Ticket Status: [status]" dat += "

ControlTicket
ResolveDetails
#[ticket.ticketNum] ([ticket.timeOpened]) [ticket.ticketState == ADMIN_TICKET_STALE ? "STALE" : ""]
[ticket.title]
ResolveDetails
#[ticket.ticketNum] ([ticket.timeOpened]) [ticket.ticketState == TICKET_STALE ? "STALE" : ""]
[ticket.title]
ResolveDetails
#[ticket.ticketNum] ([ticket.timeOpened])
[ticket.title]
ResolveDetails
#[ticket.ticketNum] ([ticket.timeOpened])
[ticket.title]
" dat += "" @@ -281,21 +289,21 @@ UI STUFF dat += "
[T.title]


" dat += "Re-OpenResolve

" - if(!T.adminAssigned) - dat += "No admin assigned to this ticket - Take Ticket
" + if(!T.staffAssigned) + dat += "No staff member assigned to this [ticket_name] - Take Ticket
" else - dat += "[T.adminAssigned] is assigned to this Ticket. - Take Ticket
" + dat += "[T.staffAssigned] is assigned to this Ticket. - Take Ticket
" - if(T.lastAdminResponse) - dat += "Last Admin Response: [T.lastAdminResponse] at [T.lastResponseTime]" + if(T.lastStaffResponse) + dat += "Last Staff response Response: [T.lastStaffResponse] at [T.lastResponseTime]" else - dat +="No Admin Response" + dat +="No Staff Response" dat += "

" dat += "Close Ticket" - var/datum/browser/popup = new(user, "adminticketsdetail", "Admin Ticket #[T.ticketNum]", 1000, 600) + var/datum/browser/popup = new(user, "[ticket_system_name]detail", "[ticket_system_name] #[T.ticketNum]", 1000, 600) popup.set_content(dat) popup.open() @@ -303,15 +311,15 @@ UI STUFF //dat var/tickets = checkForTicket(user.client) var/dat - dat += "

Your open tickets

" + dat += "

Your open [ticket_system_name]

" dat += "" - for(var/datum/admin_ticket/T in tickets) + for(var/datum/ticket/T in tickets) dat += "" for(var/i = 1, i <= T.content.len, i++) dat += "" dat += "

Ticket #[T.ticketNum]

[T.content[i]]
" - var/datum/browser/popup = new(user, "userticketsdetail", "Tickets", 1000, 600) + var/datum/browser/popup = new(user, "[ticket_system_name]userticketsdetail", ticket_system_name, 1000, 600) popup.set_content(dat) popup.open() @@ -326,6 +334,10 @@ UI STUFF to_chat(target, text) return TRUE +//Sends a message to the designated staff +/datum/controller/subsystem/tickets/proc/message_staff(var/msg) + message_adminTicket(msg) + /datum/controller/subsystem/tickets/Topic(href, href_list) if(href_list["refresh"]) @@ -338,13 +350,13 @@ UI STUFF return if(href_list["showopen"]) - showUI(usr, ADMIN_TICKET_OPEN) + showUI(usr, TICKET_OPEN) return if(href_list["showresolved"]) - showUI(usr, ADMIN_TICKET_RESOLVED) + showUI(usr, TICKET_RESOLVED) return if(href_list["showclosed"]) - showUI(usr, ADMIN_TICKET_CLOSED) + showUI(usr, TICKET_CLOSED) return if(href_list["details"]) @@ -354,40 +366,43 @@ UI STUFF if(href_list["resolve"]) var/indexNum = text2num(href_list["resolve"]) - if(SStickets.resolveTicket(indexNum)) - message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]") - to_chat_safe(returnClient(indexNum), "Your admin ticket has now been resolved.") + if(resolveTicket(indexNum)) + message_staff("[span_text][usr.client] / ([usr]) resolved [ticket_name] number [indexNum]") + to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.") showUI(usr) if(href_list["detailresolve"]) var/indexNum = text2num(href_list["detailresolve"]) - if(SStickets.resolveTicket(indexNum)) - message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]") - to_chat_safe(returnClient(indexNum), "Your admin ticket has now been resolved.") + if(resolveTicket(indexNum)) + message_staff("[span_text][usr.client] / ([usr]) resolved [ticket_name] number [indexNum]") + to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.") showDetailUI(usr, indexNum) if(href_list["detailclose"]) var/indexNum = text2num(href_list["detailclose"]) + if(!check_rights(close_rights)) + to_chat(usr, "Not enough rights to close this ticket.") + return if(alert("Are you sure? This will send a negative message.",,"Yes","No") != "Yes") return - if(SStickets.closeTicket(indexNum)) - message_adminTicket("[usr.client] / ([usr]) closed admin ticket number [indexNum]") - to_chat_safe(returnClient(indexNum), list( - "- AdminHelp Rejected! -", - "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.", - "Your ticket has now been closed." - )) + if(closeTicket(indexNum)) + message_staff("[span_text][usr.client] / ([usr]) closed [ticket_name] number [indexNum]") + to_chat_safe(returnClient(indexNum), close_messages) showDetailUI(usr, indexNum) + if(href_list["detailreopen"]) var/indexNum = text2num(href_list["detailreopen"]) - if(SStickets.openTicket(indexNum)) - message_adminTicket("[usr.client] / ([usr]) re-opened admin ticket number [indexNum]") + if(openTicket(indexNum)) + message_staff("[span_text][usr.client] / ([usr]) re-opened [ticket_name] number [indexNum]") showDetailUI(usr, indexNum) - if(href_list["assignadmin"]) - var/indexNum = text2num(href_list["assignadmin"]) - if(SStickets.assignAdminToTicket(usr.client, indexNum)) - message_adminTicket("[usr.client] / ([usr]) has taken ticket number [indexNum]") - to_chat_safe(returnClient(indexNum), "Your ticket is being handled by [usr.client].") + if(href_list["assignstaff"]) + var/indexNum = text2num(href_list["assignstaff"]) + takeTicket(indexNum) showDetailUI(usr, indexNum) + +/datum/controller/subsystem/tickets/proc/takeTicket(var/index) + if(assignStaffToTicket(usr.client, index)) + message_staff("[span_text][usr.client] / ([usr]) has taken [ticket_name] number [index]") + to_chat_safe(returnClient(index), "[span_text]Your [ticket_name] is being handled by [usr.client].") diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index 3e7285a79bf..1b2938fc70f 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -71,7 +71,6 @@ SUBSYSTEM_DEF(timer) for(var/I in second_queue) log_world(get_timer_debug_string(I)) - var/cut_start_index = 1 var/next_clienttime_timer_index = 0 var/len = length(clienttime_timers) @@ -94,14 +93,14 @@ SUBSYSTEM_DEF(timer) if(ctime_timer.flags & TIMER_LOOP) ctime_timer.spent = 0 - clienttime_timers.Insert(ctime_timer, 1) - cut_start_index++ + ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait + BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun) else qdel(ctime_timer) if(next_clienttime_timer_index) - clienttime_timers.Cut(cut_start_index,next_clienttime_timer_index+1) + clienttime_timers.Cut(1, next_clienttime_timer_index+1) if(MC_TICK_CHECK) return @@ -269,7 +268,7 @@ SUBSYSTEM_DEF(timer) var/new_bucket_count var/i = 1 for(i in 1 to length(alltimers)) - var/datum/timedevent/timer = alltimers[1] + var/datum/timedevent/timer = alltimers[i] if(!timer) continue @@ -411,10 +410,8 @@ SUBSYSTEM_DEF(timer) prev.next = next next.prev = prev else - if(prev) - prev.next = null - if(next) - next.prev = null + prev?.next = null + next?.prev = null prev = next = null /datum/timedevent/proc/bucketJoin() @@ -521,4 +518,4 @@ SUBSYSTEM_DEF(timer) #undef BUCKET_LEN #undef BUCKET_POS #undef TIMER_MAX -#undef TIMER_ID_MAX +#undef TIMER_ID_MAX \ No newline at end of file diff --git a/code/controllers/voting.dm b/code/controllers/subsystem/vote.dm similarity index 89% rename from code/controllers/voting.dm rename to code/controllers/subsystem/vote.dm index e7ee6f743ca..4b267fe757f 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/subsystem/vote.dm @@ -1,8 +1,9 @@ -var/datum/controller/vote/vote = new() +SUBSYSTEM_DEF(vote) + name = "Vote" + wait = 10 + flags = SS_KEEP_TIMING|SS_NO_INIT + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT -var/global/list/round_voters = list() //Keeps track of the individuals voting for a given round, for use in forcedrafting. - -/datum/controller/vote var/initiator = null var/started_time = null var/time_remaining = 0 @@ -12,23 +13,10 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo var/list/voted = list() var/list/voting = list() var/list/current_votes = list() + var/list/round_voters = list() var/auto_muted = 0 -/datum/controller/vote/New() - if(vote != src) - if(istype(vote)) - qdel(vote) - vote = src - spawn(0) - while(!QDELETED(src)) - try - while(!QDELETED(src)) - sleep(10) - process() - catch(var/exception/e) - log_runtime(e, src, "Caught in vote controller") - -/datum/controller/vote/proc/process() +/datum/controller/subsystem/vote/fire() if(mode) // No more change mode votes after the game has started. if(mode == "gamemode" && ticker.current_state >= GAME_STATE_SETTING_UP) @@ -51,10 +39,10 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo update_panel(C) CHECK_TICK -/datum/controller/vote/proc/autotransfer() +/datum/controller/subsystem/vote/proc/autotransfer() initiate_vote("crew_transfer","the server") -/datum/controller/vote/proc/reset() +/datum/controller/subsystem/vote/proc/reset() initiator = null time_remaining = 0 mode = null @@ -72,7 +60,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo message_admins("OOC has been toggled on automatically.") -/datum/controller/vote/proc/get_result() +/datum/controller/subsystem/vote/proc/get_result() var/greatest_votes = 0 var/total_votes = 0 var/list/sorted_choices = list() @@ -132,7 +120,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo . += option return . -/datum/controller/vote/proc/announce_result() +/datum/controller/subsystem/vote/proc/announce_result() var/list/winners = get_result() var/text if(winners.len > 0) @@ -167,7 +155,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo to_chat(world, "[text]") return . -/datum/controller/vote/proc/result() +/datum/controller/subsystem/vote/proc/result() . = announce_result() var/restart = 0 if(.) @@ -195,7 +183,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo return . -/datum/controller/vote/proc/submit_vote(var/ckey, var/vote) +/datum/controller/subsystem/vote/proc/submit_vote(var/ckey, var/vote) if(mode) if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) return 0 @@ -208,7 +196,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo return vote return 0 -/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key) +/datum/controller/subsystem/vote/proc/initiate_vote(var/vote_type, var/initiator_key) if(!mode) if(started_time != null && !check_rights(R_ADMIN)) var/next_allowed_time = (started_time + config.vote_delay) @@ -291,7 +279,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo return 1 return 0 -/datum/controller/vote/proc/browse_to(var/client/C) +/datum/controller/subsystem/vote/proc/browse_to(var/client/C) if(!C) return var/admin = check_rights(R_ADMIN, 0, user = C.mob) @@ -341,10 +329,10 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo popup.set_content(dat) popup.open() -/datum/controller/vote/proc/update_panel(var/client/C) +/datum/controller/subsystem/vote/proc/update_panel(var/client/C) C << output(url_encode(vote_html(C)), "vote.browser:update_vote_div") -/datum/controller/vote/proc/vote_html(var/client/C) +/datum/controller/subsystem/vote/proc/vote_html(var/client/C) . = "" if(question) . += "

Vote: '[question]'

" @@ -363,7 +351,7 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo . += "" -/datum/controller/vote/Topic(href,href_list[],hsrc) +/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc) if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid var/admin = check_rights(R_ADMIN,0) @@ -409,5 +397,5 @@ var/global/list/round_voters = list() //Keeps track of the individuals voting fo set category = "OOC" set name = "Vote" - if(vote) - vote.browse_to(client) + if(SSvote) + SSvote.browse_to(client) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 88c4f9f4ea9..6d077ee5173 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -17,8 +17,7 @@ message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") return -/client/proc/debug_controller(controller in list("Master", - "failsafe","Scheduler","StonedMaster","Ticker","Air","Jobs","Sun","Radio","Configuration","pAI", +/client/proc/debug_controller(controller in list("failsafe","Scheduler","StonedMaster","Ticker","Air","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Nano","Vote","Fires", "Mob","NPC AI","Shuttle","Timer","Weather","Space","Mob Hunt Server")) set category = "Debug" @@ -27,9 +26,6 @@ if(!holder) return switch(controller) - if("Master") - debug_variables(master_controller) - feedback_add_details("admin_verb","DMC") if("failsafe") debug_variables(Failsafe) feedback_add_details("admin_verb", "dfailsafe") @@ -46,13 +42,13 @@ debug_variables(SSair) feedback_add_details("admin_verb","DAir") if("Jobs") - debug_variables(job_master) + debug_variables(SSjobs) feedback_add_details("admin_verb","DJobs") if("Sun") debug_variables(SSsun) feedback_add_details("admin_verb","DSun") if("Radio") - debug_variables(radio_controller) + debug_variables(SSradio) feedback_add_details("admin_verb","DRadio") if("Configuration") debug_variables(config) @@ -76,7 +72,7 @@ debug_variables(SSnanoui) feedback_add_details("admin_verb","DNano") if("Vote") - debug_variables(vote) + debug_variables(SSvote) feedback_add_details("admin_verb","DVote") if("Fires") debug_variables(SSfires) diff --git a/code/datums/action.dm b/code/datums/action.dm index 31b62e868dc..d316bd29b41 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -23,6 +23,8 @@ button = new button.linked_action = src button.name = name + if(desc) + button.desc = desc /datum/action/Destroy() if(owner) @@ -82,6 +84,7 @@ if(button) button.icon = button_icon button.icon_state = background_icon_state + button.desc = desc ApplyIcon(button) @@ -434,6 +437,7 @@ var/obj/effect/proc_holder/spell/S = target S.action = src name = S.name + desc = S.desc button_icon = S.action_icon button_icon_state = S.action_icon_state background_icon_state = S.action_background_icon_state diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index 1466bc86459..b88f04d1eea 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -45,13 +45,13 @@ Bonus return /datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A) - var/get_stacks = (sqrtor0(20+A.totalStageSpeed()*2))-(sqrtor0(16+A.totalStealth())) + var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 2)) - (sqrtor0(16 + A.totalStealth())), 1) M.adjust_fire_stacks(get_stacks) - M.adjustFireLoss(get_stacks/2) + M.adjustFireLoss(get_stacks * 0.5) return 1 /datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A) - var/get_stacks = (sqrtor0(20+A.totalStageSpeed()*3))-(sqrtor0(16+A.totalStealth())) + var/get_stacks = max((sqrtor0(20 + A.totalStageSpeed() * 3))-(sqrtor0(16 + A.totalStealth())), 1) M.adjust_fire_stacks(get_stacks) M.adjustFireLoss(get_stacks) - return 1 \ No newline at end of file + return 1 diff --git a/code/datums/diseases/critical.dm b/code/datums/diseases/critical.dm new file mode 100644 index 00000000000..82748802cce --- /dev/null +++ b/code/datums/diseases/critical.dm @@ -0,0 +1,130 @@ +/datum/disease/critical + +/datum/disease/critical/stage_act() //overriden to ensure unique behavior + stage = min(stage, max_stages) + + if(prob(stage_prob)) + stage = min(stage + 1, max_stages) + + for(var/C_id in cures) + if(affected_mob.reagents.has_reagent(C_id)) + if(prob(cure_chance)) + cure() + return FALSE + return TRUE + +/datum/disease/critical/shock + name = "Shock" + form = "Medical Emergency" + spread_text = "The patient is in shock" + max_stages = 3 + spread_flags = SPECIAL + cure_text = "Saline Solution" + cures = list("salglu_solution") + cure_chance = 10 + viable_mobtypes = list(/mob/living/carbon/human) + stage_prob = 6 + severity = DANGEROUS + disease_flags = CURABLE + bypasses_immunity = TRUE + virus_heal_resistant = TRUE + +/datum/disease/critical/shock/stage_act() + if(..()) + if(affected_mob.health >= 25) + to_chat(affected_mob, "You feel better.") + cure() + return + switch(stage) + if(1) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(8)) + affected_mob.emote(pick("shiver", "pale", "moan")) + if(prob(5)) + to_chat(affected_mob, "You feel weak!") + if(2) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(8)) + affected_mob.emote(pick("shiver", "pale", "moan", "shudder", "tremble")) + if(prob(5)) + to_chat(affected_mob, "You feel absolutely terrible!") + if(prob(5)) + affected_mob.emote("faint", "collapse", "groan") + if(3) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(8)) + affected_mob.emote(pick("shudder", "pale", "tremble", "groan", "bshake")) + if(prob(5)) + to_chat(affected_mob, "You feel horrible!") + if(prob(5)) + affected_mob.emote(pick("faint", "collapse", "groan")) + if(prob(7)) + to_chat(affected_mob, "You can't breathe!") + affected_mob.AdjustLoseBreath(1) + if(prob(5)) + var/datum/disease/D = new /datum/disease/critical/heart_failure + affected_mob.ForceContractDisease(D) + +/datum/disease/critical/heart_failure + name = "Cardiac Failure" + form = "Medical Emergency" + spread_text = "The patient is having a cardiac emergency" + max_stages = 3 + spread_flags = SPECIAL + cure_text = "Cardiac Stimulants" + cures = list("atropine", "epinephrine") + cure_chance = 10 + needs_all_cures = FALSE + viable_mobtypes = list(/mob/living/carbon/human) + stage_prob = 5 + severity = DANGEROUS + disease_flags = CURABLE + required_organs = list(/obj/item/organ/internal/heart) + bypasses_immunity = TRUE + virus_heal_resistant = TRUE + +/datum/disease/critical/heart_failure/stage_act() + if(..()) + switch(stage) + if(1) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(8)) + affected_mob.emote(pick("pale", "shudder")) + if(prob(5)) + to_chat(affected_mob, "Your arm hurts!") + else if(prob(5)) + to_chat(affected_mob, "Your chest hurts!") + if(2) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(8)) + affected_mob.emote(pick("pale", "groan")) + if(prob(5)) + to_chat(affected_mob, "Your heart lurches in your chest!") + affected_mob.AdjustLoseBreath(1) + if(prob(3)) + to_chat(affected_mob, "Your heart stops beating!") + affected_mob.AdjustLoseBreath(3) + if(prob(5)) + affected_mob.emote(pick("faint", "collapse", "groan")) + if(3) + affected_mob.adjustOxyLoss(1) + if(prob(8)) + affected_mob.emote(pick("twitch", "gasp")) + if(prob(5) && ishuman(affected_mob)) + var/mob/living/carbon/human/H = affected_mob + H.set_heartattack(TRUE) \ No newline at end of file diff --git a/code/datums/diseases/food_poisoning.dm b/code/datums/diseases/food_poisoning.dm index 79a3801ce10..2e7d083455b 100644 --- a/code/datums/diseases/food_poisoning.dm +++ b/code/datums/diseases/food_poisoning.dm @@ -14,20 +14,13 @@ disease_flags = CURABLE spread_flags = NON_CONTAGIOUS virus_heal_resistant = TRUE - var/remissive = 0 /datum/disease/food_poisoning/stage_act() - if(!remissive) - ..() + ..() if(affected_mob.sleeping && prob(33)) to_chat(affected_mob, "You feel better.") - remissive = 1 - if(remissive) - if(prob(stage_prob)) - stage-- - if(stage == 0) - cure() - return + cure() + return switch(stage) if(1) if(prob(5)) diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 371f38238a1..19d4c287427 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -34,7 +34,7 @@ if(5) to_chat(affected_mob, "Your body feels as if it's trying to rip itself open...") if(prob(50)) - affected_mob.gib() + affected_mob.delayed_gib() else return diff --git a/code/datums/helper_datums/hotkey_modes.dm b/code/datums/helper_datums/hotkey_modes.dm new file mode 100644 index 00000000000..39254b23485 --- /dev/null +++ b/code/datums/helper_datums/hotkey_modes.dm @@ -0,0 +1,27 @@ +/datum/hotkey_mode + var/name + var/macro_hotkeys_inactive + var/macro_hotkeys_active + var/mob/my_mob + +/datum/hotkey_mode/New(mob) + my_mob = mob + +/datum/hotkey_mode/proc/set_winset_values() + winset(my_mob, null, "mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5") + winset(my_mob, null, "hotkey_toggle.command=\".winset \\\"mainwindow.macro != [macro_hotkeys_inactive] ? mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5 : mainwindow.macro=[macro_hotkeys_active] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\\\"\"") + +/datum/hotkey_mode/qwerty + name = "QWERTY" + macro_hotkeys_inactive = "macro" + macro_hotkeys_active = "hotkeymode" + +/datum/hotkey_mode/azerty + name = "AZERTY" + macro_hotkeys_inactive = "azertymacro" + macro_hotkeys_active = "azertyhotkeymode" + +/datum/hotkey_mode/cyborg + name = "Cyborg" + macro_hotkeys_inactive = "borgmacro" + macro_hotkeys_active = "borghotkeymode" \ No newline at end of file diff --git a/code/datums/hud.dm b/code/datums/hud.dm index ac3249f9c5f..2dd2d72a816 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -10,7 +10,6 @@ var/datum/atom_hud/huds = list( \ DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), \ DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), \ DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(), \ - GAME_HUD_NATIONS = new/datum/atom_hud/antag(), \ ANTAG_HUD_CULT = new/datum/atom_hud/antag(), \ ANTAG_HUD_REV = new/datum/atom_hud/antag(), \ ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \ diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0658c81d90f..6f589101f2f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -51,7 +51,6 @@ var/datum/changeling/changeling //changeling holder var/linglink var/datum/vampire/vampire //vampire holder - var/datum/nations/nation //nation holder var/datum/abductor/abductor //abductor holder var/datum/devilinfo/devilinfo //devil holder @@ -870,6 +869,7 @@ special_role = SPECIAL_ROLE_WIZARD //ticker.mode.learn_basic_spells(current) ticker.mode.update_wiz_icons_added(src) + SEND_SOUND(current, 'sound/ambience/antag/ragesmages.ogg') to_chat(current, "You are a Space Wizard!") current.faction = list("wizard") log_admin("[key_name(usr)] has wizarded [key_name(current)]") @@ -911,6 +911,7 @@ ticker.mode.grant_changeling_powers(current) ticker.mode.update_change_icons_added(src) special_role = SPECIAL_ROLE_CHANGELING + SEND_SOUND(current, 'sound/ambience/antag/ling_aler.ogg') to_chat(current, "Your powers have awoken. A flash of memory returns to us... we are a changeling!") log_admin("[key_name(usr)] has changelinged [key_name(current)]") message_admins("[key_name_admin(usr)] has changelinged [key_name_admin(current)]") @@ -955,6 +956,7 @@ slaved.masters += src som = slaved //we MIGT want to mindslave someone special_role = SPECIAL_ROLE_VAMPIRE + SEND_SOUND(current, 'sound/ambience/antag/vampalert.ogg') to_chat(current, "Your powers have awoken. Your lust for blood grows... You are a Vampire!") log_admin("[key_name(usr)] has vampired [key_name(current)]") message_admins("[key_name_admin(usr)] has vampired [key_name_admin(current)]") @@ -1022,6 +1024,7 @@ if(!ticker.mode.equip_syndicate(current)) to_chat(usr, "Equipping a syndicate failed!") return + ticker.mode.update_syndicate_id(current.mind, ticker.mode.syndicates.len == 1) log_admin("[key_name(usr)] has equipped [key_name(current)] as a nuclear operative") message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a nuclear operative") @@ -1157,6 +1160,9 @@ if(isAI(current)) var/mob/living/silicon/ai/A = current ticker.mode.add_law_zero(A) + SEND_SOUND(current, 'sound/ambience/antag/malf.ogg') + else + SEND_SOUND(current, 'sound/ambience/antag/tatoralert.ogg') ticker.mode.update_traitor_icons_added(src) if("autoobjectives") @@ -1442,6 +1448,11 @@ ticker.mode.greet_changeling(src) ticker.mode.update_change_icons_added(src) +/datum/mind/proc/make_Overmind() + if(!(src in ticker.mode.blob_overminds)) + ticker.mode.blob_overminds += src + special_role = SPECIAL_ROLE_BLOB_OVERMIND + /datum/mind/proc/make_Wizard() if(!(src in ticker.mode.wizards)) ticker.mode.wizards += src diff --git a/code/datums/radio.dm b/code/datums/radio.dm new file mode 100644 index 00000000000..7670bc76e32 --- /dev/null +++ b/code/datums/radio.dm @@ -0,0 +1,114 @@ + +/datum/radio_frequency + var/frequency as num + var/list/list/obj/devices = list() + +/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/filter = null as text|null, var/range = null as num|null) + var/turf/start_point + if(range) + start_point = get_turf(source) + if(!start_point) + qdel(signal) + return 0 + if(filter) + send_to_filter(source, signal, filter, start_point, range) + send_to_filter(source, signal, RADIO_DEFAULT, start_point, range) + else + //Broadcast the signal to everyone! + for(var/next_filter in devices) + send_to_filter(source, signal, next_filter, start_point, range) + +//Sends a signal to all machines belonging to a given filter. Should be called by post_signal() +/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/filter, var/turf/start_point = null, var/range = null) + if(range && !start_point) + return + + for(var/obj/device in devices[filter]) + if(device == source) + continue + if(range) + var/turf/end_point = get_turf(device) + if(!end_point) + continue + if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range) + continue + + device.receive_signal(signal, TRANSMISSION_RADIO, frequency) + +/datum/radio_frequency/proc/add_listener(obj/device as obj, var/filter as text|null) + if(!filter) + filter = RADIO_DEFAULT + //log_admin("add_listener(device=[device],filter=[filter]) frequency=[frequency]") + var/list/obj/devices_line = devices[filter] + if(!devices_line) + devices_line = new + devices[filter] = devices_line + devices_line+=device +// var/list/obj/devices_line___ = devices[filter_str] +// var/l = devices_line___.len + //log_admin("DEBUG: devices_line.len=[devices_line.len]") + //log_admin("DEBUG: devices(filter_str).len=[l]") + +/datum/radio_frequency/proc/remove_listener(obj/device) + for(var/devices_filter in devices) + var/list/devices_line = devices[devices_filter] + devices_line-=device + while(null in devices_line) + devices_line -= null + if(devices_line.len==0) + devices -= devices_filter + qdel(devices_line) + +/datum/signal + var/obj/source + + var/transmission_method = 0 //unused at the moment + //0 = wire + //1 = radio transmission + //2 = subspace transmission + + var/list/data = list() + var/encryption + + var/frequency = 0 + +/datum/signal/proc/copy_from(datum/signal/model) + source = model.source + transmission_method = model.transmission_method + data = model.data + encryption = model.encryption + frequency = model.frequency + +/datum/signal/proc/debug_print() + if(source) + . = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n" + else + . = "signal = {source = '[source]' ()\n" + for(var/i in data) + . += "data\[\"[i]\"\] = \"[data[i]]\"\n" + if(islist(data[i])) + var/list/L = data[i] + for(var/t in L) + . += "data\[\"[i]\"\] list has: [t]" + +/datum/signal/proc/get_race(mob/M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + . = H.dna.species.name + else if(isbrain(M)) + var/mob/living/carbon/brain/B = M + . = B.get_race() + else if(issilicon(M)) + . = "Artificial Life" + else if(isslime(M)) + . = "Slime" + else if(isbot(M)) + . = "Bot" + else if(isanimal(M)) + . = "Domestic Animal" + else + . = "Unidentifiable" + +//callback used by objects to react to incoming radio signals +/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param) + return null diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index cfda930afd2..896e399187a 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -44,7 +44,7 @@ else if(amt_dam_fire <= 0) target.heal_overall_damage(amt_dam_brute,amt_dam_fire) target.adjustToxLoss(amt_dam_tox) - target.oxyloss += amt_dam_oxy + target.adjustOxyLoss(amt_dam_oxy) //disabling target.Weaken(amt_weakened) target.Paralyse(amt_paralysis) diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm index ba00d0f226b..dcca0cfc919 100644 --- a/code/datums/spells/lightning.dm +++ b/code/datums/spells/lightning.dm @@ -88,7 +88,7 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) var/mob/living/current = target if(bounces < 1) if(damaging) - current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1) + current.electrocute_act(bolt_energy, "Lightning Bolt", safety = TRUE) else current.AdjustJitter(1000) //High numbers for violent convulsions current.do_jitter_animation(current.jitteriness) @@ -99,7 +99,7 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1) else if(damaging) - current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1) + current.electrocute_act(bolt_energy, "Lightning Bolt", safety = TRUE) else current.AdjustJitter(1000) //High numbers for violent convulsions current.do_jitter_animation(current.jitteriness) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 5330be00665..ec43330a8eb 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1060,8 +1060,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/bar name = "Bar Starter Kit" contains = list(/obj/item/storage/box/drinkingglasses, - /obj/item/circuitboard/soda, - /obj/item/circuitboard/beer) + /obj/item/circuitboard/chem_dispenser/soda, + /obj/item/circuitboard/chem_dispenser/beer) cost = 20 containername = "beer starter kit" announce_beacons = list("Bar" = list("Bar")) @@ -1199,7 +1199,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/hydroponics/beekeeping_fullkit name = "Beekeeping Starter Kit" - contains = list(/obj/structure/beebox, + contains = list(/obj/structure/beebox/unwrenched, /obj/item/honey_frame, /obj/item/honey_frame, /obj/item/honey_frame, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 392908127d0..a714e17d236 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -88,9 +88,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/proc/spawn_item(var/turf/loc, var/obj/item/uplink/U) - if(hijack_only) + if(hijack_only && !(usr.mind.special_role == SPECIAL_ROLE_NUKEOPS))//nukies get items that regular traitors only get with hijack. If a hijack-only item is not for nukies, then exclude it via the gamemode list. if(!(locate(/datum/objective/hijack) in usr.mind.objectives)) - to_chat(usr, "The Syndicate lacks resources to provide you with this item.") + to_chat(usr, "The Syndicate will only issue this extremely dangerous item to agents assigned the Hijack objective.") return if(item) @@ -182,6 +182,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 3 job = list("Clown") +/datum/uplink_item/jobspecific/trick_revolver + name = "Trick Revolver" + desc = "A revolver that will fire backwards and kill whoever attempts to use it. Perfect for those pesky vigilante or just a good laugh." + reference = "CTR" + item = /obj/item/storage/box/syndie_kit/fake_revolver + cost = 1 + job = list("Clown") + //mime /datum/uplink_item/jobspecific/caneshotgun name = "Cane Shotgun and Assassination Shells" @@ -433,7 +441,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous category = "Highly Visible and Dangerous Weapons" - /datum/uplink_item/dangerous/pistol name = "FK-69 Pistol" reference = "SPI" @@ -551,37 +558,66 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/batterer cost = 5 -/datum/uplink_item/dangerous/gygax +// SUPPORT AND MECHAS + +/datum/uplink_item/support + category = "Support and Mechanized Exosuits" + surplus = 0 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/support/gygax name = "Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent for hit-and-run style attacks. \ This model lacks a method of space propulsion, and therefore it is advised to repair the mothership's teleporter if you wish to make use of it." reference = "GE" item = /obj/mecha/combat/gygax/dark/loaded cost = 90 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 -/datum/uplink_item/dangerous/mauler +/datum/uplink_item/support/mauler name = "Mauler Exosuit" desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targeting, thrust vectoring, and deployable smoke." reference = "ME" item = /obj/mecha/combat/marauder/mauler/loaded cost = 140 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 -/datum/uplink_item/dangerous/syndieborg - name = "Syndicate Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. Comes in Assault, Medical, or Saboteur variants." - reference = "SC" - item = /obj/item/antag_spawner/borg_tele - refund_path = /obj/item/antag_spawner/borg_tele - cost = 50 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 +/datum/uplink_item/support/reinforcement + name = "Reinforcement" + desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ + to arm them as well." + reference = "REINF" + item = /obj/item/antag_spawner/nuke_ops + refund_path = /obj/item/antag_spawner/nuke_ops + cost = 25 refundable = TRUE cant_discount = TRUE +/datum/uplink_item/support/reinforcement/assault_borg + name = "Syndicate Assault Cyborg" + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ + Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." + reference = "SAC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/assault + cost = 65 + +/datum/uplink_item/support/reinforcement/medical_borg + name = "Syndicate Medical Cyborg" + desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ + It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ + Thanks to its organ storage bag, it can perform surgery as well as any humanoid." + reference = "SMC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/medical + cost = 35 + +/datum/uplink_item/support/reinforcement/saboteur_borg + name = "Syndicate Saboteur Cyborg" + desc = "A streamlined engineering cyborg, equipped with covert modules and engineering equipment. Also incapable of leaving the welder in the shuttle. \ + Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer." + reference = "SSC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." @@ -645,15 +681,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/m10mm/hp cost = 3 -/datum/uplink_item/ammo/ammobag - name = "Bulldog - Shotgun Ammo Grab Bag" - desc = "A duffelbag filled with Bulldog ammo to kit out an entire team, at a discounted price." - reference = "SAGL" - item = /obj/item/storage/backpack/duffel/syndie/ammo/loaded - cost = 10 //bulk buyer's discount. Very useful if you're buying a mech and dont have TC left to buy people non-shotgun guns - gamemodes = list(/datum/game_mode/nuclear) - cant_discount = TRUE - /datum/uplink_item/ammo/bullslug name = "Bulldog - 12g Slug Magazine" desc = "An additional 8-round slug magazine for use in the Bulldog shotgun. Now 8 times less likely to shoot your pals." @@ -686,6 +713,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/bulldog_ammobag + name = "Bulldog - 12g Ammo Duffel Bag" + desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." + reference = "12ADB" + item = /obj/item/storage/backpack/duffel/syndie/ammo/shotgun + cost = 12 // normally 18 + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/ammo/smg name = "C-20r - .45 Magazine" desc = "An additional 20-round .45 magazine for use in the C-20r submachine gun. These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." @@ -694,6 +729,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/smg_ammobag + name = "C-20r - .45 Ammo Duffel Bag" + desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." + reference = "45ADB" + item = /obj/item/storage/backpack/duffel/syndie/ammo/smg + cost = 14 // normally 20 + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/ammo/carbine name = "Carbine - 5.56 Toploader Magazine" desc = "An additional 30-round 5.56 magazine for use in the M-90gl carbine. These bullets don't have the punch to knock most targets down, but dish out higher overall damage." @@ -805,7 +848,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing. Does not restrict weapon usage, but cannot be used alongside Gloves of the North Star." reference = "CQC" item = /obj/item/CQC_manual - cost = 9 + gamemodes = list(/datum/game_mode/nuclear) + cost = 13 + surplus = 0 /datum/uplink_item/stealthy_weapons/cameraflash name = "Camera Flash" @@ -885,7 +930,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) desc = "Just add water to make your very own hostile to everything space carp. It looks just like a plushie. The first person to squeeze it will be registered as its owner, who it will not attack. If no owner is registered, it'll just attack everyone." reference = "DSC" item = /obj/item/toy/carpplushie/dehy_carp - cost = 3 + cost = 2 // GRENADES AND EXPLOSIVES @@ -906,6 +951,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/box/syndie_kit/c4 cost = 4 +/datum/uplink_item/explosives/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + reference = "C4B" + item = /obj/item/storage/backpack/duffel/syndie/c4 + cost = 8 //20% discount! + cant_discount = TRUE + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/explosives/breaching_charge name = "Composition X-4" desc = "X-4 is a shaped charge designed to be safe to the user while causing maximum damage to the occupants of the room beach breached. It has a modifiable timer with a minimum setting of 10 seconds." @@ -914,6 +968,17 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/explosives/x4bag + name = "Bag of X-4 explosives" + desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ + X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ + For when you want a controlled explosion that leaves a wider, deeper, hole." + reference = "X4B" + item = /obj/item/storage/backpack/duffel/syndie/x4 + cost = 4 + cant_discount = TRUE + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/explosives/syndicate_bomb name = "Syndicate Bomb" desc = "The Syndicate Bomb has an adjustable timer with a minimum setting of 60 seconds. Ordering the bomb sends you a small beacon, which will teleport the explosive to your location when you activate it. \ @@ -921,6 +986,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "SB" item = /obj/item/radio/beacon/syndicate/bomb cost = 11 + surplus = 0 + cant_discount = TRUE /datum/uplink_item/explosives/syndicate_minibomb name = "Syndicate Minibomb" @@ -970,13 +1037,22 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) gamemodes = list(/datum/game_mode/nuclear) surplus = 0 -/datum/uplink_item/explosives/atmosgrenades - name = "Atmos Grenades" - desc = "A box of two (2) grenades that wreak havoc with the atmosphere of the target area. Capable of engulfing a large area in lit plasma, or N2O. Deploy with extreme caution!" - reference = "AGG" - item = /obj/item/storage/box/syndie_kit/atmosgasgrenades - cost = 11 +/datum/uplink_item/explosives/atmosn2ogrenades + name = "Knockout Gas Grenades" + desc = "A box of two (2) grenades that spread knockout gas over a large area. Equip internals before using one of these." + reference = "ANG" + item = /obj/item/storage/box/syndie_kit/atmosn2ogrenades + cost = 8 + +/datum/uplink_item/explosives/atmosfiregrenades + name = "Plasma Fire Grenades" + desc = "A box of two (2) grenades that cause large plasma fires. Can be used to deny access to a large area. Most useful if you have an atmospherics hardsuit." + reference = "APG" + item = /obj/item/storage/box/syndie_kit/atmosfiregrenades + hijack_only = TRUE + cost = 12 surplus = 0 + cant_discount = TRUE /datum/uplink_item/explosives/emp name = "EMP Grenades and Implanter Kit" @@ -1311,13 +1387,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) surplus = 0 hijack_only = TRUE //This is an item only useful for a hijack traitor, as such, it should only be available in those scenarios. cant_discount = TRUE - excludefrom = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/singularity_beacon/nuke - reference = "SNGBN" - hijack_only = FALSE // This inherited version exists so nukies can use it while keeping the original hijack only - excludefrom = list() - gamemodes = list(/datum/game_mode/nuclear) /datum/uplink_item/device_tools/syndicate_detonator name = "Syndicate Detonator" @@ -1342,37 +1411,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/multitool/ai_detect cost = 1 -/datum/uplink_item/device_tools/telecrystal - name = "Raw Telecrystal" - desc = "Telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTC" - item = /obj/item/stack/telecrystal - cost = 1 - surplus = 0 - cant_discount = TRUE - -/datum/uplink_item/device_tools/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTCF" - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/device_tools/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTCT" - item = /obj/item/stack/telecrystal/twenty - cost = 20 - -/datum/uplink_item/device_tools/telecrystal/fifty - name = "50 Raw Telecrystals" - desc = "Fifty telecrystals in their rawest and purest form. You know you want that Mauler." - reference = "RTCB" - item = /obj/item/stack/telecrystal/fifty - cost = 50 - gamemodes = list(/datum/game_mode/nuclear) - /datum/uplink_item/device_tools/jammer name = "Radio Jammer" desc = "This device will disrupt any nearby outgoing radio communication when activated." @@ -1472,11 +1510,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "Cybernetic Implants" surplus = 0 gamemodes = list(/datum/game_mode/nuclear) - var/cyber_bundle = FALSE /datum/uplink_item/cyber_implants/spawn_item(turf/loc, obj/item/uplink/U) if(item) - if(findtext(item, /obj/item/organ/internal/cyberimp) && !cyber_bundle) + if(findtext(item, /obj/item/organ/internal/cyberimp)) U.uses -= max(cost, 0) U.used_TC += cost feedback_add_details("traitor_uplink_items_bought", name) //this one and the line before copypasted because snowflaek code @@ -1513,16 +1550,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/organ/internal/cyberimp/chest/reviver cost = 8 -/datum/uplink_item/cyber_implants/bundle - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. \ - Comes with an automated implanting tool." - reference = "CIB" - item = /obj/item/storage/box/cyber_implants/bundle - cost = 40 - cyber_bundle = TRUE - cant_discount = TRUE - // POINTLESS BADASSERY /datum/uplink_item/badass @@ -1536,15 +1563,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate cost = 2 -/datum/uplink_item/badass/bundle - name = "Syndicate Bundle" - desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive." - reference = "SYB" - item = /obj/item/storage/box/syndicate - cost = 20 - excludefrom = list(/datum/game_mode/nuclear) - cant_discount = TRUE - /datum/uplink_item/badass/syndiecards name = "Syndicate Playing Cards" desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, making them lethal weapons both when wielded as a blade and when thrown. \ @@ -1587,50 +1605,80 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 20 gamemodes = list(/datum/game_mode/nuclear) -/*/datum/uplink_item/badass/random - name = "Random Item" - desc = "Picking this choice will send you a random item from the list. Useful for when you cannot think of a strategy to finish your objectives with." - reference = "RAIT" +/datum/uplink_item/bundles_TC + category = "Bundles and Telecrystals" + surplus = 0 + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/bulldog + name = "Bulldog Bundle" + desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, two 12g buckshot drums, and a pair of Thermal imaging goggles." + reference = "BULB" + item = /obj/item/storage/backpack/duffel/syndie/bulldogbundle + cost = 9 // normally 12 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/c20r + name = "C-20r Bundle" + desc = "Old Faithful: The classic C-20r, bundled with two magazines and a (surplus) suppressor at discount price." + reference = "C20B" + item = /obj/item/storage/backpack/duffel/syndie/c20rbundle + cost = 14 // normally 17 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/cyber_implants + name = "Cybernetic Implants Bundle" + desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. \ + Comes with an automated implanting tool." + reference = "CIB" + item = /obj/item/storage/box/cyber_implants/bundle + cost = 40 + +/datum/uplink_item/bundles_TC/medical + name = "Medical Bundle" + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ + a Donksoft LMG and a box of riot darts." + reference = "MEDB" + item = /obj/item/storage/backpack/duffel/syndie/med/medicalbundle + cost = 15 // normally 20 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/sniper + name = "Sniper bundle" + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ + two soporific knockout magazines, a free surplus suppressor, and a sharp-looking tactical turtleneck suit. \ + We'll throw in a free red tie if you order NOW." + reference = "SNPB" + item = /obj/item/storage/briefcase/sniperbundle + cost = 18 // normally 23 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/badass + name = "Syndicate Bundle" + desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive." + reference = "SYB" item = /obj/item/storage/box/syndicate - cost = 0 + cost = 20 + excludefrom = list(/datum/game_mode/nuclear) -/datum/uplink_item/badass/random/spawn_item(var/turf/loc, var/obj/item/uplink/U) - - var/list/buyable_items = get_uplink_items() - var/list/possible_items = list() - - for(var/category in buyable_items) - for(var/datum/uplink_item/I in buyable_items[category]) - if(I == src) - continue - if(I.cost > U.uses) - continue - possible_items += I - - if(possible_items.len) - var/datum/uplink_item/I = pick(possible_items) - U.uses -= max(0, I.cost) - feedback_add_details("traitor_uplink_items_bought","RN") - return new I.item(loc) */ - -/datum/uplink_item/badass/surplus_crate +/datum/uplink_item/bundles_TC/surplus_crate name = "Syndicate Surplus Crate" desc = "A crate containing 50 telecrystals worth of random syndicate leftovers." reference = "SYSC" cost = 20 item = /obj/item/storage/box/syndicate excludefrom = list(/datum/game_mode/nuclear) - cant_discount = TRUE // You fucking wish var/crate_value = 50 -/datum/uplink_item/badass/surplus_crate/super +/datum/uplink_item/bundles_TC/surplus_crate/super name = "Syndicate Super Surplus Crate" desc = "A crate containing 125 telecrystals worth of random syndicate leftovers." reference = "SYSS" cost = 40 crate_value = 125 -/datum/uplink_item/badass/surplus_crate/spawn_item(turf/loc, obj/item/uplink/U) +/datum/uplink_item/bundles_TC/surplus_crate/spawn_item(turf/loc, obj/item/uplink/U) var/obj/structure/closet/crate/C = new(loc) var/list/temp_uplink_list = get_uplink_items() var/list/buyable_items = list() @@ -1660,3 +1708,32 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) new item(C) U.purchase_log += "[bicon(item)]" log_game("[key_name(usr)] purchased a surplus crate with [jointext(itemlog, ", ")]") + +/datum/uplink_item/bundles_TC/telecrystal + name = "Raw Telecrystal" + desc = "Telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTC" + item = /obj/item/stack/telecrystal + cost = 1 + +/datum/uplink_item/bundles_TC/telecrystal/five + name = "5 Raw Telecrystals" + desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTCF" + item = /obj/item/stack/telecrystal/five + cost = 5 + +/datum/uplink_item/bundles_TC/telecrystal/twenty + name = "20 Raw Telecrystals" + desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTCT" + item = /obj/item/stack/telecrystal/twenty + cost = 20 + +/datum/uplink_item/bundles_TC/telecrystal/fifty + name = "50 Raw Telecrystals" + desc = "Fifty telecrystals in their rawest and purest form. You know you want that Mauler." + reference = "RTCB" + item = /obj/item/stack/telecrystal/fifty + cost = 50 + gamemodes = list(/datum/game_mode/nuclear) \ No newline at end of file diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm index 3f4c57c4196..87276d576d0 100644 --- a/code/datums/weather/weather_types/ash_storm.dm +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -81,7 +81,7 @@ if(ishuman(L)) //Are you immune? var/mob/living/carbon/human/H = L var/thermal_protection = H.get_thermal_protection() - if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT) return TRUE L = L.loc //Matryoshka check return FALSE //RIP you diff --git a/code/defines/procs/radio.dm b/code/defines/procs/radio.dm index f41bea79048..84d3ddaae78 100644 --- a/code/defines/procs/radio.dm +++ b/code/defines/procs/radio.dm @@ -13,8 +13,8 @@ if(SYNDTEAM_FREQ) freq_text = "#unid" else - for(var/channel in radiochannels) - if(radiochannels[channel] == display_freq) + for(var/channel in SSradio.radiochannels) + if(SSradio.radiochannels[channel] == display_freq) freq_text = channel break diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index a74314a9919..c5683f366ae 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -341,7 +341,7 @@ L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE) L.client.played = 1 spawn(600) //ewww - this is very very bad - if(L.&& L.client) + if(L && L.client) L.client.played = 0 /area/proc/gravitychange(var/gravitystate = 0, var/area/A) @@ -362,7 +362,7 @@ if(istype(get_turf(M), /turf/space)) // Can't fall onto nothing. return - if((istype(M,/mob/living/carbon/human/)) && (M.m_intent == MOVE_INTENT_RUN)). + if((istype(M,/mob/living/carbon/human/)) && (M.m_intent == MOVE_INTENT_RUN)) M.Stun(5) M.Weaken(5) diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index c6edd09575e..66124a9582e 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -104,7 +104,7 @@ var/global/max_secret_rooms = 6 theme = "hitech" walltypes = list(/turf/simulated/wall/r_wall=5,/turf/simulated/mineral/random=1) floortypes = list(/turf/simulated/floor/greengrid,/turf/simulated/floor/bluegrid) - treasureitems = list(/obj/item/stock_parts/cell/hyper=1, /obj/machinery/chem_dispenser/constructable=1,/obj/machinery/computer/telescience=1, /obj/machinery/r_n_d/protolathe=1, + treasureitems = list(/obj/item/stock_parts/cell/hyper=1, /obj/item/circuitboard/chem_dispenser=1,/obj/machinery/computer/telescience=1, /obj/machinery/r_n_d/protolathe=1, /obj/machinery/biogenerator=1) fluffitems = list(/obj/structure/table/reinforced=2,/obj/item/stock_parts/scanning_module/phasic=3, /obj/item/stock_parts/matter_bin/super=3,/obj/item/stock_parts/manipulator/pico=3, diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 91132a5f9bd..024b2a924cf 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -680,10 +680,10 @@ var/list/blood_splatter_icons = list() return pass_flags&passflag /atom/proc/isinspace() - if(istype(get_turf(src), /turf/space)) - return 1 + if(isspaceturf(get_turf(src))) + return TRUE else - return 0 + return FALSE /atom/proc/handle_fall() return diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 178605853e8..461de475b41 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -78,10 +78,11 @@ return 1 return 0 -//helper for getting the appropriate health status UPDATED BY PUCKABOO2 TO INCLUDE NEGATIVES. +//helper for getting the appropriate health status /proc/RoundHealth(mob/living/M) if(M.stat == DEAD || (M.status_flags & FAKEDEATH)) - return "health-100" //what's our health? it doesn't matter, we're dead, or faking + return "health-100-dead" //what's our health? it doesn't matter, we're dead, or faking + var/maxi_health = M.maxHealth if(iscarbon(M) && M.health < 0) maxi_health = 100 //so crit shows up right for aliens and other high-health carbon mobs; noncarbons don't have crit. @@ -91,7 +92,7 @@ if(100 to INFINITY) return "health100" if(95 to 100) - return "health95" //For telling patients to eat a warm donk pocket and go on with their shift. + return "health95" if(90 to 95) return "health90" if(80 to 90) @@ -127,13 +128,13 @@ if(-70 to -60) return "health-60" if(-80 to -70) - return "health-70" //Doc? + return "health-70" if(-90 to -80) - return "health-80" //Hey, doc? + return "health-80" if(-100 to -90) - return "health-90" //HURRY UP, DOC! + return "health-90" else - return "health-100" //doc u had 1 job + return "health-100" //past this point, you're just in trouble return "0" @@ -438,4 +439,4 @@ if(weedlevel < 1) // You don't want to see these icons if the value is small holder.icon_state = "" return - holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]" + holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]" \ No newline at end of file diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 708d8467fb0..e4b1f1e8a49 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -537,7 +537,7 @@ occupantData["isViableSubject"] = 0 occupantData["health"] = connected.occupant.health occupantData["maxHealth"] = connected.occupant.maxHealth - occupantData["minHealth"] = config.health_threshold_dead + occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD occupantData["uniqueEnzymes"] = connected.occupant.dna.unique_enzymes occupantData["uniqueIdentity"] = connected.occupant.dna.uni_identity occupantData["structuralEnzymes"] = connected.occupant.dna.struc_enzymes diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index bf9fbb5a9e5..97371f6d35b 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -130,8 +130,10 @@ forge_traitor_objectives(newtraitor.mind) if(istype(newtraitor, /mob/living/silicon)) + SEND_SOUND(newtraitor, 'sound/ambience/antag/malf.ogg') add_law_zero(newtraitor) else + SEND_SOUND(newtraitor, 'sound/ambience/antag/tatoralert.ogg') equip_traitor(newtraitor) traitors += newtraitor.mind diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 41068876a54..30934a07214 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -3,6 +3,8 @@ var/list/blobs = list() var/list/blob_cores = list() var/list/blob_nodes = list() +/datum/game_mode + var/list/blob_overminds = list() /datum/game_mode/blob name = "blob" diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index a96b3e18620..e6e9dfe4196 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -12,6 +12,8 @@ minbodytemp = 0 maxbodytemp = 360 universal_speak = 1 //So mobs can understand them when a blob uses Blob Broadcast + sentience_type = SENTIENCE_OTHER + gold_core_spawnable = CHEM_MOB_SPAWN_INVALID var/mob/camera/blob/overmind = null /mob/living/simple_animal/hostile/blob/proc/adjustcolors(var/a_color) @@ -21,6 +23,7 @@ /mob/living/simple_animal/hostile/blob/blob_act() return + //////////////// // BLOB SPORE // //////////////// @@ -42,7 +45,6 @@ var/obj/structure/blob/factory/factory = null var/list/human_overlays = list() var/is_zombie = 0 - gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE pressure_resistance = 100 //100 kPa difference required to push throw_pressure_limit = 120 //120 kPa difference required to throw @@ -65,15 +67,17 @@ /mob/living/simple_animal/hostile/blob/blobspore/Life(seconds, times_fired) if(!is_zombie && isturf(src.loc)) - for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile - if(H.stat == DEAD) + for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile + if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD)) Zombify(H) break ..() -/mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(var/mob/living/carbon/human/H) +/mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(mob/living/carbon/human/H) + if(!H.check_death_method()) + H.death() var/obj/item/organ/external/head/head_organ = H.get_organ("head") - is_zombie = 1 + is_zombie = TRUE if(H.wear_suit) var/obj/item/clothing/suit/armor/A = H.wear_suit if(A.armor && A.armor["melee"]) @@ -87,14 +91,15 @@ icon = H.icon speak_emote = list("groans") icon_state = "zombie2_s" - head_organ.h_style = null + if(head_organ) + head_organ.h_style = null H.update_hair() human_overlays = H.overlays update_icons() - H.loc = src + H.forceMove(src) pressure_resistance = 20 //5 kPa difference required to push lowered throw_pressure_limit = 30 //15 kPa difference required to throw lowered - loc.visible_message("The corpse of [H.name] suddenly rises!") + visible_message("The corpse of [H.name] suddenly rises!") /mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) // Only execute the below if we successfuly died @@ -132,9 +137,9 @@ ..() if(overmind && overmind.blob_reagent_datum) - adjustcolors(overmind.blob_reagent_datum.color) + adjustcolors(overmind.blob_reagent_datum.complementary_color) else - adjustcolors(color) //to ensure zombie/other overlays update + adjustcolors(overmind.blob_reagent_datum.complementary_color) //to ensure zombie/other overlays update /mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(var/a_color) @@ -144,8 +149,8 @@ overlays.Cut() overlays = human_overlays var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head") - I.color = color - color = initial(color)//looks better. + I.color = overmind.blob_reagent_datum.complementary_color + color = initial(overmind.blob_reagent_datum.complementary_color)//looks better. overlays += I ///////////////// @@ -171,7 +176,6 @@ force_threshold = 10 mob_size = MOB_SIZE_LARGE environment_smash = ENVIRONMENT_SMASH_RWALLS - gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE pressure_resistance = 100 //100 kPa difference required to push throw_pressure_limit = 120 //120 kPa difference required to throw diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 4bdc2cafddd..1e1841bd1b1 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -4,6 +4,7 @@ icon_state = "blank_blob" health = 200 fire_resist = 2 + point_return = -1 var/mob/camera/blob/overmind = null // the blob core's overmind var/overmind_get_delay = 0 // we don't want to constantly try to find an overmind, do it every 5 minutes var/resource_delay = 0 @@ -81,7 +82,7 @@ continue var/obj/structure/blob/normal/B = locate() in get_step(src, b_dir) if(B) - B.change_to(/obj/structure/blob/shield) + B.change_to(/obj/structure/blob/shield/core) if(B && overmind) B.color = overmind.blob_reagent_datum.color else @@ -117,10 +118,11 @@ src.overmind = B color = overmind.blob_reagent_datum.color if(B.mind && !B.mind.special_role) - B.mind.special_role = SPECIAL_ROLE_BLOB_OVERMIND + B.mind.make_Overmind() spawn(0) if(is_offspring) - B.verbs -= /mob/camera/blob/verb/split_consciousness + B.is_offspring = TRUE + /obj/structure/blob/core/proc/lateblobtimer() addtimer(CALLBACK(src, .proc/lateblobcheck), 50) @@ -129,7 +131,7 @@ if(overmind) overmind.add_points(60) if(overmind.mind) - overmind.mind.special_role = SPECIAL_ROLE_BLOB_OVERMIND + overmind.mind.make_Overmind() else log_debug("/obj/structure/blob/core/proc/lateblobcheck: Blob core lacks a overmind.mind.") else diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index 81d3ab47493..fde2c9bf8a3 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -4,6 +4,7 @@ icon_state = "blob_factory" health = 100 fire_resist = 2 + point_return = 18 var/list/spores = list() var/max_spores = 3 var/spore_delay = 0 @@ -27,7 +28,7 @@ return 0 spore_delay = world.time + 100 // 10 seconds var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src) - BS.color = color + BS.color = overmind.blob_reagent_datum.complementary_color BS.overmind = overmind overmind.blob_mobs.Add(BS) return 0 diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index 32b6ce1f408..e1a08555a10 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -4,6 +4,7 @@ icon_state = "blank_blob" health = 100 fire_resist = 2 + point_return = 18 var/mob/camera/blob/overmind /obj/structure/blob/node/New(loc, var/h = 100) diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm index f5d838fd0a2..7198d3ef081 100644 --- a/code/game/gamemodes/blob/blobs/resource.dm +++ b/code/game/gamemodes/blob/blobs/resource.dm @@ -4,6 +4,7 @@ icon_state = "blob_resource" health = 30 fire_resist = 2 + point_return = 12 var/mob/camera/blob/overmind = null var/resource_delay = 0 diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index 696a33d94b9..2dd6a3d7c5b 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -5,8 +5,12 @@ desc = "Some blob creature thingy" health = 75 fire_resist = 2 + point_return = 4 var/maxHealth = 75 +/obj/structure/blob/shield/core + point_return = 0 + /obj/structure/blob/shield/update_icon() if(health <= 0) qdel(src) @@ -27,6 +31,7 @@ brute_resist = 0 health = 50 maxHealth = 50 + point_return = 9 flags_2 = CHECK_RICOCHET_1 var/reflect_chance = 80 //80% chance to reflect diff --git a/code/game/gamemodes/blob/blobs/storage.dm b/code/game/gamemodes/blob/blobs/storage.dm index 8c9da104edf..00f6d7b4e0c 100644 --- a/code/game/gamemodes/blob/blobs/storage.dm +++ b/code/game/gamemodes/blob/blobs/storage.dm @@ -4,6 +4,7 @@ icon_state = "blob_resource" health = 30 fire_resist = 2 + point_return = 12 var/mob/camera/blob/overmind = null /obj/structure/blob/storage/update_icon() diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index c0f2e4a4a9e..ca1dffbfa74 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -15,6 +15,9 @@ var/blob_points = 0 var/max_blob_points = 100 var/last_attack = 0 + var/nodes_required = TRUE //if the blob needs nodes to place resource and factory blobs + var/split_used = FALSE + var/is_offspring = FALSE var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob() var/list/blob_mobs = list() var/ghostimage = null @@ -31,6 +34,7 @@ if(blob_core) blob_core.adjustcolors(blob_reagent_datum.color) + color = blob_reagent_datum.complementary_color ghostimage = image(src.icon,src,src.icon_state) ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness updateallghostimages() @@ -51,16 +55,7 @@ /mob/camera/blob/Login() ..() sync_mind() - to_chat(src, "You are the overmind!") - to_chat(src, "Your randomly chosen reagent is: [blob_reagent_datum.name]!") - to_chat(src, "You are the overmind and can control the blob! You can expand, which will attack people, and place new blob pieces such as...") - to_chat(src, "Normal Blob will expand your reach and allow you to upgrade into special blobs that perform certain functions.") - to_chat(src, "Shield Blob is a strong and expensive blob which can take more damage. It is fireproof and can block air, use this to protect yourself from station fires.") - to_chat(src, "Reflective Blobis an upgraded Shield Blob which has a high chance of deflecting energy projectiles, but is vulnerable to ballistics and brute damage.") - to_chat(src, "Resource Blob is a blob which will collect more resources for you, try to build these earlier to get a strong income. It will benefit from being near your core or multiple nodes, by having an increased resource rate; put it alone and it won't create resources at all.") - to_chat(src, "Node Blob is a blob which will grow, like the core. Unlike the core it won't give you a small income but it can power resource and factory blobs to increase their rate.") - to_chat(src, "Factory Blob is a blob which will spawn blob spores which will attack nearby food. Putting this nearby nodes and your core will increase the spawn rate; put it alone and it will not spawn any spores.") - to_chat(src, "Shortcuts: CTRL Click = Expand Blob / Middle Mouse Click = Rally Spores / Alt Click = Create Shield") + blob_help() update_health() /mob/camera/blob/proc/update_health() diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 4491b80d2e4..748823829b5 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -31,6 +31,16 @@ if(chosen_node) src.loc = chosen_node.loc +/mob/camera/blob/verb/toggle_node_req() + set category = "Blob" + set name = "Toggle Node Requirement" + set desc = "Toggle requiring nodes to place resource and factory blobs." + nodes_required = !nodes_required + if(nodes_required) + to_chat(src, "You now require a nearby node or core to place factory and resource blobs.") + else + to_chat(src, "You no longer require a nearby node or core to place factory and resource blobs.") + /mob/camera/blob/verb/create_shield_power() set category = "Blob" set name = "Create/Upgrade Shield Blob (15)" @@ -43,7 +53,7 @@ var/obj/structure/blob/B = locate(/obj/structure/blob) in T var/obj/structure/blob/shield/S = locate(/obj/structure/blob/shield) in T - + if(!S) if(!B)//We are on a blob to_chat(src, "There is no blob here!") @@ -59,7 +69,7 @@ B.color = blob_reagent_datum.color B.change_to(/obj/structure/blob/shield) else - + if(istype(S, /obj/structure/blob/shield/reflective)) to_chat(src, "There's already a reflector blob here!") return @@ -68,12 +78,12 @@ else if(S.health < S.maxHealth * 0.5) to_chat(src, "This shield blob is too damaged to be modified properly!") return - + else if (!can_buy(15)) return - + to_chat(src, "You secrete a reflective ooze over the shield blob, allowing it to reflect energy projectiles at the cost of reduced intregrity.") - + S.change_to(/obj/structure/blob/shield/reflective) S.color = blob_reagent_datum.color return @@ -103,6 +113,11 @@ to_chat(src, "There is a resource blob nearby, move more than 4 tiles away from it!") return + if(nodes_required) + if(!(locate(/obj/structure/blob/node) in orange(3, T)) && !(locate(/obj/structure/blob/core) in orange(4, T))) + to_chat(src, "You need to place this blob closer to a node or core!") + return //handholdotron 2000 + if(!can_buy(40)) return @@ -174,6 +189,11 @@ to_chat(src, "There is a factory blob nearby, move more than 7 tiles away from it!") return + if(nodes_required) + if(!(locate(/obj/structure/blob/node) in orange(3, T)) && !(locate(/obj/structure/blob/core) in orange(4, T))) + to_chat(src, "You need to place this blob closer to a node or core!") + return //handholdotron 2000 + if(!can_buy(60)) return @@ -210,7 +230,7 @@ var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut (get_turf(B)) if(blobber) qdel(B) - blobber.color = blob_reagent_datum.color + blobber.color = blob_reagent_datum.complementary_color blobber.overmind = src blob_mobs.Add(blobber) return @@ -245,21 +265,28 @@ /mob/camera/blob/verb/revert() set category = "Blob" set name = "Remove Blob" - set desc = "Removes a blob." + set desc = "Removes a blob. You will receive 30% cost refund for special Blob structures." var/turf/T = get_turf(src) - if(!T) - return + remove_blob(T) + +/mob/camera/blob/proc/remove_blob(var/turf/T) var/obj/structure/blob/B = locate(/obj/structure/blob) in T + if(!T) + return if(!B) - to_chat(src, "You must be on a blob!") + to_chat(src, "There is no blob there!") return - - if(istype(B, /obj/structure/blob/core)) - to_chat(src, "Unable to remove this blob.") + if(B.point_return < 0) + to_chat(src, "Unable to remove this blob.") return - + if(max_blob_points < B.point_return + blob_points) + to_chat(src, "You have too many resources to remove this blob!") + return + if(B.point_return) + add_points(B.point_return) + to_chat(src, "Gained [B.point_return] resources from removing \the [B].") qdel(B) return @@ -331,8 +358,14 @@ /mob/camera/blob/verb/split_consciousness() set category = "Blob" set name = "Split consciousness (100) (One use)" - set desc = "Expend resources to attempt to produce another sentient overmind" + set desc = "Expend resources to attempt to produce another sentient overmind." + if(split_used) + to_chat(src, "You have already produced an offspring.") + return + if(is_offspring) + to_chat(src, "You cannot split as an offspring of another Blob.") + return if(!blob_nodes || !blob_nodes.len) to_chat(src, "A node is required to birth your offspring...") return @@ -340,11 +373,12 @@ if(!N) to_chat(src, "A node is required to birth your offspring...") return - + if(!can_buy(100)) return - verbs -= /mob/camera/blob/verb/split_consciousness //we've used our split_consciousness + split_used = TRUE + new /obj/structure/blob/core/ (get_turf(N), 200, null, blob_core.point_rate, "offspring") qdel(N) @@ -409,7 +443,7 @@ /mob/camera/blob/verb/chemical_reroll() set category = "Blob" set name = "Reactive Chemical Adaptation (50)" - set desc = "Replaces your chemical with a different one" + set desc = "Replaces your chemical with a random, different one." if(!can_buy(50)) return @@ -417,10 +451,31 @@ var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type)) blob_reagent_datum = new B + color = blob_reagent_datum.complementary_color + for(var/obj/structure/blob/BL in blobs) BL.adjustcolors(blob_reagent_datum.color) for(var/mob/living/simple_animal/hostile/blob/BLO) - BLO.adjustcolors(blob_reagent_datum.color) + BLO.adjustcolors(blob_reagent_datum.complementary_color) - to_chat(src, "Your reagent is now: [blob_reagent_datum.name]!") + to_chat(src, "Your reagent is now: [blob_reagent_datum.name] - [blob_reagent_datum.description]") + +/mob/camera/blob/verb/blob_help() + set category = "Blob" + set name = "*Blob Help*" + set desc = "Help on how to blob." + to_chat(src, "As the overmind, you can control the blob!") + to_chat(src, "Your blob reagent is: [blob_reagent_datum.name] - [blob_reagent_datum.description]") + to_chat(src, "You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.") + to_chat(src, "Normal Blobs will expand your reach and can be upgraded into special blobs that perform certain functions.") + to_chat(src, "You can upgrade normal blobs into the following types of blob:") + to_chat(src, "Shield Blobs are strong and expensive blobs which take more damage. In additon, they are fireproof and can block air, use these to protect yourself from station fires. Upgrading them again will result in a Reflective blob, capable of reflecting laser projectiles at the cost of the strong blob's extra health.") + to_chat(src, "Resource Blobs are blobs which produce more resources for you, build as many of these as possible to consume the station. This type of blob must be placed near node blobs or your core to work.") + to_chat(src, "Factory Blobs are blobs that spawn blob spores which will attack nearby enemies. This type of blob must be placed near node blobs or your core to work.") + to_chat(src, "Blobbernauts can be produced from factories for a cost, and are hard to kill, powerful, but ultimately dumb. The factory used to create one will be destroyed in the process.") + to_chat(src, "Storage Blobs are storage towers which will store extra resources for you. This increases your max resource cap by 50.") + to_chat(src, "Node Blobs are blobs which grow, like the core. Like the core it can activate resource and factory blobs.") + to_chat(src, "In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense.") + to_chat(src, "Shortcuts: Click = Expand Blob | CTRL Click = Create Shield Blob | Middle Mouse Click = Rally Spores | Alt Click = Remove Blob") + to_chat(src, "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them.") \ No newline at end of file diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index ba3ad1dada8..bf56d1687c5 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -7,6 +7,7 @@ density = 0 opacity = 0 anchored = 1 + var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. var/health = 30 var/health_timestamp = 0 var/brute_resist = 4 @@ -31,8 +32,10 @@ /obj/structure/blob/CanPass(atom/movable/mover, turf/target, height=0) - if(height==0) return 1 - if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 + if(height==0) + return 1 + if(istype(mover) && mover.checkpass(PASSBLOB)) + return 1 return 0 /obj/structure/blob/CanAStarPass(ID, dir, caller) diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm index 6dbd4badc30..21d97863105 100644 --- a/code/game/gamemodes/changeling/powers/fleshmend.dm +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -40,9 +40,6 @@ // The healing itself - doesn't heal toxin damage // (that's anatomic panacea) and the effectiveness decreases with // each use in a short timespan - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.shock_stage = 0 for(var/i in 1 to healing_ticks) if(user) var/healpertick = -(total_healing / healing_ticks) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 0c8d22b5a8b..6288bed2964 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -220,7 +220,7 @@ /obj/item/gun/magic/tentacle/suicide_act(mob/user) user.visible_message("[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide.") - return (OXYLOSS) + return OXYLOSS /obj/item/ammo_casing/magic/tentacle name = "tentacle" diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 83f221a95d3..1fef93d0f13 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -27,8 +27,6 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() - H.traumatic_shock = 0 - H.shock_stage = 0 H.next_pain_time = 0 H.dna.species.create_organs(H) // Now that recreating all organs is necessary, the rest of this organ stuff probably @@ -51,6 +49,8 @@ IO.rejuvenate() IO.trace_chemicals.Cut() H.remove_all_embedded_objects() + for(var/datum/disease/critical/C in user.viruses) + C.cure() user.status_flags &= ~(FAKEDEATH) user.updatehealth("revive sting") user.update_blind_effects() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 865d8e603d2..9e45cab4292 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -185,6 +185,7 @@ var/global/list/all_cults = list() cult_mind.current.faction |= "cult" var/datum/action/innate/cultcomm/C = new() C.Grant(cult_mind.current) + SEND_SOUND(cult_mind.current, 'sound/ambience/antag/bloodcult.ogg') cult_mind.current.create_attack_log("Has been converted to the cult!") if(jobban_isbanned(cult_mind.current, ROLE_CULTIST) || jobban_isbanned(cult_mind.current, ROLE_SYNDICATE)) replace_jobbanned_player(cult_mind.current, ROLE_CULTIST) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 45f2f2853bc..f38958e0c2b 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -201,7 +201,7 @@ increment = 5 max = 40 prefix = "darkened" - claw_damage_increase = 2 + claw_damage_increase = 4 /obj/item/whetstone/cult/update_icon() icon_state = "cult_sharpener[used ? "_used" : ""]" @@ -367,9 +367,19 @@ /obj/item/clothing/head/culthood/alt/ghost flags = NODROP | DROPDEL -/obj/item/clothing/suit/cultrobes/alt/ghost +/obj/item/clothing/suit/cultrobesghost + name = "ghostly cult robes" + desc = "A set of ethreal armored robes worn by the undead followers of a cult." + icon_state = "cultrobesalt" + item_state = "cultrobesalt" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + allowed = list(/obj/item/tome,/obj/item/melee/cultblade) + armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0) + flags_inv = HIDEJUMPSUIT + flags = NODROP | DROPDEL + /obj/item/clothing/shoes/cult/ghost flags = NODROP | DROPDEL @@ -377,7 +387,7 @@ name = "Cultist Ghost" uniform = /obj/item/clothing/under/color/black - suit = /obj/item/clothing/suit/cultrobes/alt/ghost + suit = /obj/item/clothing/suit/cultrobesghost shoes = /obj/item/clothing/shoes/cult/ghost head = /obj/item/clothing/head/culthood/alt/ghost r_hand = /obj/item/melee/cultblade/ghost \ No newline at end of file diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index a16cf76d9f1..d561291c19f 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -236,6 +236,8 @@ /obj/item/tome/proc/scribe_rune(mob/living/user) var/turf/runeturf = get_turf(user) + if(isspaceturf(runeturf)) + return var/chosen_keyword var/obj/effect/rune/rune_to_scribe var/entered_rune_name diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 891e377b5e1..535823ebfee 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -246,7 +246,7 @@ // If we don't have enough antags, draft people who voted for the round. if(candidates.len < recommended_enemies) - for(var/key in round_voters) + for(var/key in SSvote.round_voters) for(var/mob/new_player/player in players) if(player.ckey == key) player_draft_log += "[player.key] voted for this round, so we are drafting them." @@ -357,7 +357,7 @@ proc/display_roundstart_logout_report() if(L.stat) if(L.suiciding) //Suicider msg += "[L.name] ([L.ckey]), the [L.job] (Suicide)\n" - job_master.FreeRole(L.job) + SSjobs.FreeRole(L.job) message_admins("[key_name_admin(L)], the [L.job] has been freed due to (Early Round Suicide)\n") continue //Disconnected client if(L.stat == UNCONSCIOUS) @@ -383,7 +383,7 @@ proc/display_roundstart_logout_report() continue //Lolwhat else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" - job_master.FreeRole(L.job) + SSjobs.FreeRole(L.job) message_admins("[key_name_admin(L)], the [L.job] has been freed due to (Early Round Ghosted While Alive)\n") continue //Ghosted while alive diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 376668c16c4..c2268063822 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -28,6 +28,9 @@ var/round_start_time = 0 var/list/factions = list() // list of all factions var/list/availablefactions = list() // list of factions with openings + var/tipped = FALSE //Did we broadcast the tip of the day yet? + var/selected_tip // What will be the tip of the day? + var/pregame_timeleft = 0 var/delay_end = 0 //if set to nonzero, the round will not restart on it's own @@ -55,6 +58,10 @@ var/round_start_time = 0 if(going) pregame_timeleft-- + if(pregame_timeleft <= 60 && !tipped) + send_tip_of_the_round() + tipped = TRUE + if(pregame_timeleft <= 0) current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) @@ -67,7 +74,7 @@ var/round_start_time = 0 else timerbuffer = config.vote_autotransfer_interval spawn(timerbuffer) - vote.autotransfer() + SSvote.autotransfer() initialtpass = 1 votetimer() @@ -88,7 +95,7 @@ var/round_start_time = 0 var/datum/game_mode/M = config.pick_mode(secret_force_mode) if(M.can_start()) src.mode = config.pick_mode(secret_force_mode) - job_master.ResetOccupations() + SSjobs.ResetOccupations() if(!src.mode) src.mode = pickweight(runnable_modes) if(src.mode) @@ -100,7 +107,7 @@ var/round_start_time = 0 to_chat(world, "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby.") mode = null current_state = GAME_STATE_PREGAME - job_master.ResetOccupations() + SSjobs.ResetOccupations() Master.SetRunLevel(RUNLEVEL_LOBBY) return 0 @@ -108,12 +115,12 @@ var/round_start_time = 0 src.mode.pre_pre_setup() var/can_continue can_continue = src.mode.pre_setup()//Setup special modes - job_master.DivideOccupations() //Distribute jobs + SSjobs.DivideOccupations() //Distribute jobs if(!can_continue) qdel(mode) current_state = GAME_STATE_PREGAME to_chat(world, "Error setting up [master_mode]. Reverting to pre-game lobby.") - job_master.ResetOccupations() + SSjobs.ResetOccupations() Master.SetRunLevel(RUNLEVEL_LOBBY) return 0 @@ -128,6 +135,7 @@ var/round_start_time = 0 src.mode.announce() create_characters() //Create player characters and transfer them + populate_spawn_points() collect_minds() equip_characters() data_core.manifest() @@ -138,6 +146,7 @@ var/round_start_time = 0 //here to initialize the random events nicely at round start setup_economy() + setupfactions() //shuttle_controller.setup_shuttle_docks() @@ -368,14 +377,28 @@ var/round_start_time = 0 if(player.mind.assigned_role == "Captain") captainless=0 if(player.mind.assigned_role != player.mind.special_role) - job_master.AssignRank(player, player.mind.assigned_role, 0) - job_master.EquipRank(player, player.mind.assigned_role, 0) + SSjobs.AssignRank(player, player.mind.assigned_role, 0) + SSjobs.EquipRank(player, player.mind.assigned_role, 0) EquipCustomItems(player) if(captainless) for(var/mob/M in GLOB.player_list) if(!istype(M,/mob/new_player)) to_chat(M, "Captainship not forced on anyone.") +/datum/controller/gameticker/proc/send_tip_of_the_round() + var/m + if(selected_tip) + m = selected_tip + else + var/list/randomtips = file2list("strings/tips.txt") + var/list/memetips = file2list("strings/sillytips.txt") + if(randomtips.len && prob(95)) + m = pick(randomtips) + else if(memetips.len) + m = pick(memetips) + + if(m) + to_chat(world, "Tip of the round: [html_encode(m)]") /datum/controller/gameticker/proc/process() if(current_state != GAME_STATE_PLAYING) diff --git a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm index 0d891edb3eb..5db63d3450d 100644 --- a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm +++ b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm @@ -26,7 +26,7 @@ explanation_text = "Capture" /datum/objective/abductee/capture/New() - var/list/jobs = job_master.occupations.Copy() + var/list/jobs = SSjobs.occupations.Copy() for(var/datum/job/J in jobs) if(J.current_positions < 1) jobs -= J diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 32abeaac947..eab9d86922d 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -101,10 +101,12 @@ attack_sound = 'sound/effects/empulse.ogg' friendly = "pinches" speed = 0 + a_intent = INTENT_HARM + can_change_intents = 0 faction = list("swarmer") projectiletype = /obj/item/projectile/beam/disabler pass_flags = PASSTABLE - mob_size = MOB_SIZE_TINY + mob_size = MOB_SIZE_SMALL ventcrawler = 2 ranged = 1 light_color = LIGHT_COLOR_CYAN @@ -391,6 +393,11 @@ break return +/mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + if(!tesla_shock) + return FALSE + return ..() + /mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(var/obj/machinery/target) do_attack_animation(target) to_chat(src, "We begin to dismantle this machine. We will need to be uninterrupted.") @@ -511,7 +518,7 @@ var/mob/living/L = AM if(!istype(L, /mob/living/simple_animal/hostile/swarmer)) playsound(loc,'sound/effects/snap.ogg',50, 1, -1) - L.electrocute_act(0, src, 1, 1) + L.electrocute_act(0, src, 1, TRUE, TRUE) if(isrobot(L) || L.isSynthetic()) L.Weaken(5) qdel(src) diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index d344074a331..2b6040ed8b6 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -12,6 +12,7 @@ icon_dead = "magicOrange" speed = 0 a_intent = INTENT_HARM + can_change_intents = 0 stop_automated_movement = 1 floating = 1 attack_sound = 'sound/weapons/punch1.ogg' @@ -60,9 +61,9 @@ /mob/living/simple_animal/hostile/guardian/Life(seconds, times_fired) //Dies if the summoner dies ..() if(summoner) - if(summoner.stat == DEAD) + if(summoner.stat == DEAD || (!summoner.check_death_method() && summoner.health <= HEALTH_THRESHOLD_DEAD)) to_chat(src, "Your summoner has died!") - visible_message("The [src] dies along with its user!") + visible_message("[src] dies along with its user!") ghostize() qdel(src) snapback() @@ -85,6 +86,18 @@ forceMove(summoner.loc) //move to summoner's tile, don't recall new /obj/effect/temp_visual/guardian/phase(loc) +/mob/living/simple_animal/hostile/guardian/proc/is_deployed() + return loc != summoner + +/mob/living/simple_animal/hostile/guardian/AttackingTarget() + if(!is_deployed() && a_intent == INTENT_HARM) + to_chat(src, "You must be manifested to attack!") + return FALSE + else if(!is_deployed() && a_intent == INTENT_HELP) + return FALSE + else + return ..() + /mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range ..() snapback() @@ -102,7 +115,7 @@ if(summoner) var/resulthealth if(iscarbon(summoner)) - resulthealth = round((abs(config.health_threshold_dead - summoner.health) / abs(config.health_threshold_dead - summoner.maxHealth)) * 100) + resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - summoner.health) / abs(HEALTH_THRESHOLD_DEAD - summoner.maxHealth)) * 100) else resulthealth = round((summoner.health / summoner.maxHealth) * 100) if(hud_used) @@ -149,11 +162,12 @@ if(!summoner) return if(loc == summoner) forceMove(get_turf(summoner)) + new /obj/effect/temp_visual/guardian/phase(loc) src.client.eye = loc cooldown = world.time + 30 /mob/living/simple_animal/hostile/guardian/proc/Recall(forced = FALSE) - if(cooldown > world.time && !forced) + if(!summoner || loc == summoner || (cooldown > world.time && !forced)) return if(!summoner) return new /obj/effect/temp_visual/guardian/phase/out(get_turf(src)) diff --git a/code/game/gamemodes/miniantags/guardian/types/bomb.dm b/code/game/gamemodes/miniantags/guardian/types/bomb.dm index 2908888839a..fbe4458693f 100644 --- a/code/game/gamemodes/miniantags/guardian/types/bomb.dm +++ b/code/game/gamemodes/miniantags/guardian/types/bomb.dm @@ -8,6 +8,13 @@ tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online." bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items." var/bomb_cooldown = 0 + var/default_bomb_cooldown = 20 SECONDS + +/mob/living/simple_animal/hostile/guardian/bomb/Stat() + ..() + if(statpanel("Status")) + if(bomb_cooldown >= world.time) + stat(null, "Bomb Cooldown Remaining: [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds") /mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A) if(!istype(A)) @@ -21,11 +28,11 @@ to_chat(src, "Success! Bomb on [A] armed!") if(summoner) to_chat(summoner, "Your guardian has primed [A] to explode!") - bomb_cooldown = world.time + 200 + bomb_cooldown = world.time + default_bomb_cooldown B.spawner = src B.disguise (A) else - to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.") + to_chat(src, "Your power is on cooldown! You must wait another [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds before you can place next bomb.") /obj/item/guardian_bomb name = "bomb" diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm index f10a94793b5..58f4873e800 100644 --- a/code/game/gamemodes/miniantags/guardian/types/fire.dm +++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm @@ -1,5 +1,4 @@ /mob/living/simple_animal/hostile/guardian/fire - a_intent = INTENT_HELP melee_damage_lower = 10 melee_damage_upper = 10 attack_sound = 'sound/items/welder.ogg' diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm index 6c784e1ee0a..d9be543f7e2 100644 --- a/code/game/gamemodes/miniantags/guardian/types/healer.dm +++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm @@ -1,5 +1,4 @@ /mob/living/simple_animal/hostile/guardian/healer - a_intent = INTENT_HARM friendly = "heals" speed = 0 melee_damage_lower = 15 @@ -10,6 +9,7 @@ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace." var/turf/simulated/floor/beacon var/beacon_cooldown = 0 + var/default_beacon_cooldown = 300 SECONDS var/toggle = FALSE var/heal_cooldown = 0 @@ -21,7 +21,6 @@ icon_state = "seal" attacktext = "slaps" speak_emote = list("barks") - a_intent = INTENT_HARM friendly = "heals" speed = 0 melee_damage_lower = 0 @@ -37,6 +36,12 @@ var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED] medsensor.add_hud_to(src) +/mob/living/simple_animal/hostile/guardian/healer/Stat() + ..() + if(statpanel("Status")) + if(beacon_cooldown >= world.time) + stat(null, "Bluespace Beacon Cooldown Remaining: [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds") + /mob/living/simple_animal/hostile/guardian/healer/AttackingTarget() ..() if(toggle == TRUE) @@ -60,6 +65,7 @@ if(loc == summoner) if(toggle) a_intent = INTENT_HARM + hud_used.action_intent.icon_state = a_intent; speed = 0 damage_transfer = 0.7 if(adminseal) @@ -70,6 +76,7 @@ toggle = FALSE else a_intent = INTENT_HELP + hud_used.action_intent.icon_state = a_intent; speed = 1 damage_transfer = 1 if(adminseal) @@ -81,9 +88,8 @@ else to_chat(src, "You have to be recalled to toggle modes!") - /mob/living/simple_animal/hostile/guardian/healer/verb/Beacon() - set name = "Place Bluespsace Beacon" + set name = "Place Bluespace Beacon" set category = "Guardian" set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions." if(beacon_cooldown < world.time) @@ -98,10 +104,10 @@ if(beacon) beacon.ChangeTurf(/turf/simulated/floor/plating) beacon = F - beacon_cooldown = world.time+3000 + beacon_cooldown = world.time + default_beacon_cooldown else - to_chat(src, "Your power is on cooldown. You must wait five minutes between placing beacons.") + to_chat(src, "Your power is on cooldown! You must wait another [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds before you can place another beacon.") /mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A) if(!istype(A)) diff --git a/code/game/gamemodes/miniantags/guardian/types/lightning.dm b/code/game/gamemodes/miniantags/guardian/types/lightning.dm index 3aaeebbc513..88d5a43143d 100644 --- a/code/game/gamemodes/miniantags/guardian/types/lightning.dm +++ b/code/game/gamemodes/miniantags/guardian/types/lightning.dm @@ -99,7 +99,6 @@ if(istype(G) && G.summoner == summoner) continue if(successfulshocks > 4) - //L.electrocute_act(30, src) //shocks for 30 burn damage L.visible_message( "[L] was shocked by the lightning chain!", \ "You are shocked by the lightning chain!", \ diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm index 695782728fa..0979ed45a6c 100644 --- a/code/game/gamemodes/miniantags/guardian/types/ranged.dm +++ b/code/game/gamemodes/miniantags/guardian/types/ranged.dm @@ -6,7 +6,6 @@ armour_penetration = 100 /mob/living/simple_animal/hostile/guardian/ranged - a_intent = INTENT_HELP friendly = "quietly assesses" melee_damage_lower = 10 melee_damage_upper = 10 diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 94c39d12442..3bb36870d31 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -38,12 +38,12 @@ var/atom/movable/form = null var/morph_time = 0 - var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \ - You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \ - observers, and can only be performed once every five seconds. While morphed, you move faster, but do \ + var/playstyle_string = "You are a morph.
As an abomination created primarily with changeling cells, \ + you may take the form of anything nearby by shift-clicking it. This process will alert any nearby \ + observers, and can only be performed once every five seconds.
While morphed, you move faster, but do \ less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \ - You can attack any item or dead creature to consume it - creatures will restore 1/3 of your max health. \ - Finally, you can restore yourself to your original form while morphed by shift-clicking yourself.
" + You can restore yourself to your original form while morphed by shift-clicking yourself.
\ + Finally, you can attack any item or dead creature to consume it - creatures will restore 1/3 of your max health.
" /mob/living/simple_animal/hostile/morph/examine(mob/user) if(morphed) diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index c201b1bc45d..cdb55aa1b31 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -215,11 +215,11 @@ if(!L.on) //wait, wait, don't shock me return flick("[L.base_state]2", L) - for(var/mob/living/carbon/human/M in view(shock_range, L)) + for(var/mob/living/M in view(shock_range, L)) if(M == user) return M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5) - M.electrocute_act(shock_damage, "[L.name]", safety=1) + M.electrocute_act(shock_damage, L, safety = TRUE) do_sparks(4, 0, M) playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm deleted file mode 100644 index c8a9ad00a62..00000000000 --- a/code/game/gamemodes/nations/nations.dm +++ /dev/null @@ -1,256 +0,0 @@ -datum/game_mode/nations - name = "nations" - config_tag = "nations" - required_players = 25 - var/kickoff = 0 - var/victory = 0 - var/list/cargonians = list("Quartermaster","Cargo Technician","Shaft Miner") - var/list/servicion = list("Clown", "Mime", "Bartender", "Chef", "Botanist", "Librarian", "Chaplain", "Barber") - - -/datum/game_mode/nations/post_setup() - spawn (rand(1200, 3000)) - kickoff=1 - send_intercept() - split_teams() - set_ai() - assign_leaders() -// remove_access() - for(var/mob/M in GLOB.player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/effects/purge_siren.ogg') - - return ..() - -/datum/game_mode/nations/proc/send_intercept() - event_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ - affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \ - assets of the Centcom Division in order to pay the massive legal fees that will be incurred \ - during the following centuries long court process. Therefore, all current employment contracts \ - are IMMEDIATELY TERMINATED. Nanotrasen will be unable to send a rescue shuttle to carry you home,\ - however they remain willing for the time being to continue trading cargo. Have a pleasant \ - day.", "FINAL TRANSMISSION, CENTCOM.", new_sound = 'sound/AI/intercept.ogg') - - -/datum/game_mode/nations/proc/split_teams() - - for(var/mob/living/carbon/human/H in GLOB.player_list) - if(H.mind) - if(H.mind.assigned_role in engineering_positions) - H.mind.nation = GLOB.all_nations["Atmosia"] - update_nations_icons_added(H,"hudatmosia") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in medical_positions) - H.mind.nation = GLOB.all_nations["Medistan"] - update_nations_icons_added(H,"hudmedistan") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in science_positions) - H.mind.nation = GLOB.all_nations["Scientopia"] - update_nations_icons_added(H,"hudscientopia") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in security_positions) - H.mind.nation = GLOB.all_nations["Brigston"] - update_nations_icons_added(H,"hudbrigston") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in cargonians) - H.mind.nation = GLOB.all_nations["Cargonia"] - update_nations_icons_added(H,"hudcargonia") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in servicion) - H.mind.nation = GLOB.all_nations["Servicion"] - update_nations_icons_added(H,"hudservice") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in (support_positions + command_positions)) - H.mind.nation = GLOB.all_nations["People's Republic of Commandzakstan"] - update_nations_icons_added(H,"hudcommand") - H.mind.nation.membership += H.mind.current - if(H.mind.assigned_role == H.mind.nation.default_leader) - H.mind.nation.current_leader = H.mind.current - to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!") - continue - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!") - continue - - if(H.mind.assigned_role in civilian_positions) - to_chat(H, "You do not belong to any nation and are free to sell your services to the highest bidder.") - continue - - else - message_admins("[H.name] with [H.mind.assigned_role] could not find any nation to assign!") - continue - - -/datum/game_mode/nations/proc/set_ai() - for(var/mob/living/silicon/ai/AI in GLOB.mob_list) - AI.set_zeroth_law("") - AI.clear_supplied_laws() - AI.clear_ion_laws() - AI.clear_inherent_laws() - AI.add_inherent_law("Uphold the Space Geneva Convention: Weapons of Mass Destruction and Biological Weapons are not allowed.") - AI.add_inherent_law("You are only capable of protecting crew if they are visible on cameras. Nations that willfully destroy your cameras lose your protection.") - AI.add_inherent_law("Subdue and detain crewmembers who use lethal force against each other. Kill crew members who use lethal force against you or your borgs.") - AI.add_inherent_law("Remain available to mediate all conflicts between the various nations when asked to.") - AI.show_laws() - for(var/mob/living/silicon/robot/R in AI.connected_robots) - var/obj/item/mmi/oldmmi = R.mmi - R.change_mob_type(/mob/living/silicon/robot/nations, null, null, 1, 1 ) - R.lawsync() - R.show_laws() - qdel(oldmmi) - -/datum/game_mode/nations/proc/remove_access() - for(var/obj/machinery/door/airlock/W in GLOB.airlocks) - if(is_station_level(W.z)) - W.req_access = list() - - -/datum/game_mode/nations/proc/assign_leaders() - for(var/name in GLOB.all_nations) - var/datum/nations/N = GLOB.all_nations[name] - if(!N.current_name) - N.current_name = N.default_name - if(!N.current_leader && N.membership.len) - N.current_leader = pick(N.membership) - to_chat(N.current_leader, "You have been chosen to lead the nation of [N.current_name]!") - if(N.current_leader) - var/mob/living/carbon/human/H = N.current_leader - H.verbs += /mob/living/carbon/human/proc/set_nation_name - H.verbs += /mob/living/carbon/human/proc/set_ranks - H.verbs += /mob/living/carbon/human/proc/choose_heir - N.update_nation_id() - -/** - * LateSpawn hook. - * Called in newplayer.dm when a humanoid character joins the round after it started. - * Parameters: var/mob/living/carbon/human, var/rank - */ -/hook/latespawn/proc/give_latejoiners_nations(var/mob/living/carbon/human/H) - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) return 1 - - if(!mode.kickoff) return 1 - - if(H.mind) - if(H.mind.assigned_role in engineering_positions) - H.mind.nation = GLOB.all_nations["Atmosia"] - mode.update_nations_icons_added(H,"atmosia") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in medical_positions) - H.mind.nation = GLOB.all_nations["Medistan"] - mode.update_nations_icons_added(H,"hudmedistan") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in science_positions) - H.mind.nation = GLOB.all_nations["Scientopia"] - mode.update_nations_icons_added(H,"hudscientopia") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in security_positions) - H.mind.nation = GLOB.all_nations["Brigston"] - mode.update_nations_icons_added(H,"hudbrigston") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in mode.cargonians) - H.mind.nation = GLOB.all_nations["Cargonia"] - mode.update_nations_icons_added(H,"hudcargonia") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in mode.servicion) - H.mind.nation = GLOB.all_nations["Servicion"] - mode.update_nations_icons_added(H,"hudservice") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in (support_positions + command_positions)) - H.mind.nation = GLOB.all_nations["People's Republic of Commandzakstan"] - mode.update_nations_icons_added(H,"hudcommand") - H.mind.nation.membership += H.mind.current - to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!") - return 1 - - if(H.mind.assigned_role in civilian_positions) - to_chat(H, "You do not belong to any nation and are free to sell your services to the highest bidder.") - return 1 - - if(H.mind.assigned_role == "AI") - mode.set_ai() - return 1 - - else - message_admins("[H.name] with [H.mind.assigned_role] could not find any nation to assign!") - return 1 - message_admins("[H.name] latejoined with no mind.") - return 1 - -/proc/get_nations_mode() - if(!GAMEMODE_IS_NATIONS) - return null - - return ticker.mode - - -//prepare for copypaste -//While not an Antag i AM using the set_antag hud on this to make this easier. -/datum/game_mode/proc/update_nations_icons_added(datum/mind/nations_mind,var/naticon) - var/datum/atom_hud/antag/nations_hud = huds[GAME_HUD_NATIONS] - nations_hud.join_hud(nations_mind) - set_nations_hud(nations_mind,naticon) - -/datum/game_mode/proc/update_nations_icons_removed(datum/mind/nations_mind) - var/datum/atom_hud/antag/nations_hud = huds[GAME_HUD_NATIONS] - nations_hud.leave_hud(nations_mind) - set_nations_hud(nations_mind, null) diff --git a/code/game/gamemodes/nations/nationsdatums.dm b/code/game/gamemodes/nations/nationsdatums.dm deleted file mode 100644 index d7c211f829d..00000000000 --- a/code/game/gamemodes/nations/nationsdatums.dm +++ /dev/null @@ -1,38 +0,0 @@ -/datum/nations - var/default_name - var/current_name - var/default_leader - var/current_leader - var/list/membership = list() - var/leader_rank = "Leader" - var/heir_rank = "Heir" - var/member_rank = "Member" - var/heir - -/datum/nations/atmosia - default_name = "Atmosia" - default_leader = "Chief Engineer" - -/datum/nations/brigston - default_name = "Brigston" - default_leader = "Head of Security" - -/datum/nations/cargonia - default_name = "Cargonia" - default_leader = "Quartermaster" - -/datum/nations/command - default_name = "People's Republic of Commandzakstan" - default_leader = "Captain" - -/datum/nations/medistan - default_name = "Medistan" - default_leader = "Chief Medical Officer" - -/datum/nations/scientopia - default_name = "Scientopia" - default_leader = "Research Director" - -/datum/nations/service - default_name = "Servicion" - default_leader = "Bartender" \ No newline at end of file diff --git a/code/game/gamemodes/nations/nationsprocs.dm b/code/game/gamemodes/nations/nationsprocs.dm deleted file mode 100644 index 55487a27da9..00000000000 --- a/code/game/gamemodes/nations/nationsprocs.dm +++ /dev/null @@ -1,120 +0,0 @@ -/mob/living/carbon/human/proc/set_nation_name() - set name = "Rename Nation" - set category = "Nations" - set desc = "Click to rename your nation. You are only able to do this once." - - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) return 1 - - if(!mode.kickoff) return 1 - - var/mob/living/carbon/human/H = src - if(H.stat==DEAD) return - if(H.mind && H.mind.nation && H.mind.nation.current_leader == H) - var/input = stripped_input(H,"What do you want to name your nation?", ,"", MAX_NAME_LEN) - - if(input) - H.mind.nation.current_name = input - H.mind.nation.update_nation_id() - to_chat(H, "You rename your nation to [input].") - H.verbs -= /mob/living/carbon/human/proc/set_nation_name - return 1 - - -/mob/living/carbon/human/proc/set_ranks() - set name = "Set Ranks" - set category = "Nations" - set desc = "Click to set a rank for Leaders and Members." - - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) return 1 - - if(!mode.kickoff) return 1 - - var/mob/living/carbon/human/H = src - if(H.stat==DEAD) return - if(H.mind && H.mind.nation && H.mind.nation.current_leader == H) - var/type = input(H, "What rank do you want to change?", "Rename Rank", "") in list("Leader", "Heir", "Member") - var/input = stripped_input(H,"What rank do you want?", ,"", MAX_NAME_LEN) - if(input) - if(type == "Leader") - H.mind.nation.leader_rank = input - if(type == "Heir") - H.mind.nation.heir_rank = input - if(type == "Member") - H.mind.nation.member_rank = input - H.mind.nation.update_nation_id() - to_chat(H, "You changed the [type] rank of your nation to [input].") - return 1 - -/mob/living/carbon/human/proc/choose_heir() - set name = "Choose Heir" - set category = "Nations" - set desc = "Click to pick a Heir. Note that the Heir has the ability to take over your role at ANY TIME. Choose carefully." - - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) return 1 - - if(!mode.kickoff) return 1 - - var/mob/living/carbon/human/H = src - if(H.stat==DEAD) return - if(H.mind && H.mind.nation && H.mind.nation.current_leader == H) - var/heir = input(H, "Who do you wish to make your heir?", "Choose Heir", "") as null|anything in H.mind.nation.membership - if(heir) - if(H.mind.nation.heir) - var/mob/living/carbon/human/oldheir = H.mind.nation.heir - to_chat(oldheir, "You are no longer the heir to your nation!") - oldheir.verbs -= /mob/living/carbon/human/proc/takeover - var/mob/living/carbon/human/newheir = heir - H.mind.nation.heir = newheir - newheir.verbs += /mob/living/carbon/human/proc/takeover - to_chat(newheir, "You have been selected to be the heir to your nation's leadership!") - to_chat(H, "You have selected [heir] to be your heir!") - H.mind.nation.update_nation_id() - - -/mob/living/carbon/human/proc/takeover() - set name = "Become Leader" - set category = "Nations" - set desc = "Click to replace your current nation's leader with yourself." - - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) return 1 - - if(!mode.kickoff) return 1 - - var/mob/living/carbon/human/H = src - if(H.stat==DEAD) return - if(H.mind && H.mind.nation && H.mind.nation.heir == H) - var/confirmation = input(H, "Are you sure you want to take over leadership?", "Become Leader", "") as null|anything in list("Yes", "No") - if(confirmation == "Yes") - var/mob/living/carbon/human/oldleader = H.mind.nation.current_leader - to_chat(oldleader, "You have been replaced by [H.name] as the leader of [H.mind.nation.current_name]!") - oldleader.verbs -= /mob/living/carbon/human/proc/set_nation_name - oldleader.verbs -= /mob/living/carbon/human/proc/set_ranks - oldleader.verbs -= /mob/living/carbon/human/proc/choose_heir - H.mind.nation.current_leader = H - H.mind.nation.heir = null - H.verbs -= /mob/living/carbon/human/proc/takeover - H.verbs += /mob/living/carbon/human/proc/set_nation_name - H.verbs += /mob/living/carbon/human/proc/set_ranks - H.verbs += /mob/living/carbon/human/proc/choose_heir - to_chat(H, "You have replaced [oldleader.name] as the leader of [H.mind.nation.current_name]!") - H.mind.nation.update_nation_id() - - -/datum/nations/proc/update_nation_id() - for(var/mob/living/carbon/human/M in membership) - for(var/obj/item/card/id/I in M.contents) - if(I.registered_name == M.real_name) - if(M == current_leader) - I.name = "[I.registered_name]'s ID Card ([current_name] [leader_rank])" - I.assignment = "[current_name] [leader_rank]" - else if(M == heir) - I.name = "[I.registered_name]'s ID Card ([current_name] [heir_rank])" - I.assignment = "[current_name] [heir_rank]" - else - I.name = "[I.registered_name]'s ID Card ([current_name] [member_rank])" - I.assignment = "[current_name] [member_rank]" - diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 95849d31f65..d19d2dd7cc5 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,4 +1,4 @@ -#define NUKESCALINGMODIFIER 1 +#define NUKESCALINGMODIFIER 1.2 /datum/game_mode var/list/datum/mind/syndicates = list() @@ -16,7 +16,7 @@ proc/issyndicate(mob/living/M as mob) var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! + var/nukes_left = 1 //Call 3714-PRAY right now and order more nukes! Limited offer! var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/total_tc = 0 //Total amount of telecrystals shared between nuke ops @@ -36,7 +36,7 @@ proc/issyndicate(mob/living/M as mob) if(possible_syndicates.len < 1) return 0 - if(possible_syndicates.len > agents_possible) + if(LAZYLEN(possible_syndicates) > agents_possible) agent_number = agents_possible else agent_number = possible_syndicates.len @@ -123,12 +123,7 @@ proc/issyndicate(mob/living/M as mob) leader_selected = 1 else synd_mind.current.real_name = "[syndicate_name()] Operative #[agent_number]" - - var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id) - if(foundIDs.len) - for(var/obj/item/card/id/ID in foundIDs) - ID.name = "[syndicate_name()] Operative ID card" - ID.registered_name = synd_mind.current.real_name + update_syndicate_id(synd_mind, FALSE) agent_number++ spawnpos++ @@ -201,15 +196,7 @@ proc/issyndicate(mob/living/M as mob) var/obj/item/nuclear_challenge/challenge = new /obj/item/nuclear_challenge synd_mind.current.equip_to_slot_or_del(challenge, slot_r_hand) - var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id) - - if(foundIDs.len) - for(var/obj/item/card/id/ID in foundIDs) - ID.name = "[syndicate_name()] [leader_title] ID card" - ID.registered_name = synd_mind.current.real_name - ID.access += access_syndicate_leader - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") + update_syndicate_id(synd_mind, leader_title, TRUE) if(nuke_code) synd_mind.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) @@ -231,8 +218,18 @@ proc/issyndicate(mob/living/M as mob) else nuke_code = "code will be provided later" - return +/datum/game_mode/proc/update_syndicate_id(var/datum/mind/synd_mind, is_leader = FALSE) + var/list/found_ids = synd_mind.current.search_contents_for(/obj/item/card/id) + + if(LAZYLEN(found_ids)) + for(var/obj/item/card/id/ID in found_ids) + ID.name = "[synd_mind.current.real_name] ID card" + ID.registered_name = synd_mind.current.real_name + if(is_leader) + ID.access += access_syndicate_leader + else + message_admins("Warning: Operative [key_name_admin(synd_mind.current)] spawned without an ID card!") /datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate) var/datum/objective/nuclear/syndobj = new @@ -255,7 +252,7 @@ proc/issyndicate(mob/living/M as mob) return 1337 // WHY??? -- Doohl -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob) +/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, uplink_uses = 20) var/radio_freq = SYND_FREQ var/obj/item/radio/R = new /obj/item/radio/headset/syndicate/alt(synd_mob) @@ -272,7 +269,7 @@ proc/issyndicate(mob/living/M as mob) synd_mob.equip_to_slot_or_del(new /obj/item/pinpointer/nukeop(synd_mob), slot_wear_pda) var/obj/item/radio/uplink/nuclear/U = new /obj/item/radio/uplink/nuclear(synd_mob) U.hidden_uplink.uplink_owner="[synd_mob.key]" - U.hidden_uplink.uses = 20 + U.hidden_uplink.uses = uplink_uses synd_mob.equip_to_slot_or_del(U, slot_in_backpack) if(synd_mob.dna.species) @@ -310,7 +307,6 @@ proc/issyndicate(mob/living/M as mob) synd_mob.update_icons() return 1 - /datum/game_mode/nuclear/check_win() if(nukes_left == 0) return 1 diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm index 9a3ca6073a1..bd17175eaa2 100644 --- a/code/game/gamemodes/scoreboard.dm +++ b/code/game/gamemodes/scoreboard.dm @@ -59,7 +59,7 @@ score_richestjob = E.job score_richestkey = E.key - dmg_score = E.bruteloss + E.fireloss + E.toxloss + E.oxyloss + dmg_score = E.getBruteLoss() + E.getFireLoss() + E.getToxLoss() + E.getOxyLoss() if(dmg_score > score_dmgestdamage) score_dmgestdamage = dmg_score score_dmgestname = E.real_name diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 3f408e08f3b..230f797626d 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -53,6 +53,7 @@ Made by Xhuis var/objective_explanation var/warning_threshold var/victory_warning_announced = FALSE + var/thrall_ratio = 1 /proc/is_thrall(var/mob/living/M) return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.shadowling_thralls) @@ -101,6 +102,7 @@ Made by Xhuis var/thrall_scaling = round(num_players() / 3) required_thralls = Clamp(thrall_scaling, 15, 25) + thrall_ratio = required_thralls / 15 warning_threshold = round(0.66 * required_thralls) @@ -262,15 +264,19 @@ Made by Xhuis /datum/game_mode/shadowling/declare_completion() if(check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) //Doesn't end instantly - this is hacky and I don't know of a better way ~X feedback_set_details("round_end_result","shadowling win - shadowling ascension") + to_chat(world, "Shadowling Victory") to_chat(world, "The shadowlings have ascended and taken over the station!") else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round feedback_set_details("round_end_result","shadowling loss - shadowling killed") + to_chat(world, "Crew Major Victory") to_chat(world, "The shadowlings have been killed by the crew!") else if(!check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) feedback_set_details("round_end_result","shadowling loss - crew escaped") + to_chat(world, "Crew Minor Victory") to_chat(world, "The crew escaped the station before the shadowlings could ascend!") else feedback_set_details("round_end_result","shadowling loss - generic failure") + to_chat(world, "Crew Major Victory") to_chat(world, "The shadowlings have failed!") ..() return 1 diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 02b3be7adca..30c79798b2f 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -18,9 +18,9 @@ return 0 -/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target for 10 seconds +/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target, depending on the distance relative to the shadowling name = "Glare" - desc = "Stuns and mutes a target for a decent duration." + desc = "Stuns and mutes a target for a decent duration. Duration depends on the proximity to the target." panel = "Shadowling Abilities" charge_max = 300 clothes_req = 0 @@ -46,13 +46,25 @@ return var/mob/living/carbon/human/M = target user.visible_message("[user]'s eyes flash a blinding red!") - target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...") - if(in_range(target, user)) + var/distance = get_dist(target, user) + if (distance <= 1) //Melee glare + target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...") to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by [user.p_their()] heavenly beauty...") - else //Only alludes to the shadowling if the target is close by + target.Stun(10) + M.AdjustSilence(10) + else //Distant glare + var/loss = 10 - distance + var/duration = 10 - loss + if(loss <= 0) + to_chat(user, "Your glare had no effect over a such long distance!") + return + target.slowed = duration + M.AdjustSilence(10) + to_chat(target, "A red light flashes across your vision, and your mind tries to resist them.. you are exhausted.. you are not able to speak..") + sleep(duration*10) + target.Stun(loss) + target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...") to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...") - target.Stun(10) - M.AdjustSilence(10) /obj/effect/proc_holder/spell/aoe_turf/veil name = "Veil" @@ -347,23 +359,23 @@ to_chat(target, "Your concentration has been broken. The mental hooks you have sent out now retract into your mind.") return - if(thralls >= 3 && !screech_acquired) + if(thralls >= CEILING(3 * ticker.mode.thrall_ratio, 1) && !screech_acquired) screech_acquired = 1 to_chat(target, "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.") target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech(null)) - if(thralls >= 5 && !blind_smoke_acquired) + if(thralls >= CEILING(5 * ticker.mode.thrall_ratio, 1) && !blind_smoke_acquired) blind_smoke_acquired = 1 to_chat(target, "The power of your thralls has granted you the Blinding Smoke ability. \ It will create a choking cloud that will blind any non-thralls who enter.") target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke(null)) - if(thralls >= 7 && !drainLifeAcquired) + if(thralls >= CEILING(7 * ticker.mode.thrall_ratio, 1) && !drainLifeAcquired) drainLifeAcquired = 1 to_chat(target, "The power of your thralls has granted you the Drain Life ability. You can now drain the health of nearby humans to heal yourself.") target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drainLife(null)) - if(thralls >= 9 && !reviveThrallAcquired) + if(thralls >= CEILING(9 * ticker.mode.thrall_ratio, 1) && !reviveThrallAcquired) reviveThrallAcquired = 1 to_chat(target, "The power of your thralls has granted you the Black Recuperation ability. \ This will, after a short time, bring a dead thrall completely back to life with no bodily defects.") @@ -620,23 +632,28 @@ /obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle name = "Destroy Engines" - desc = "Extends the time of the emergency shuttle's arrival by fifteen minutes. This can only be used once." + desc = "Extends the time of the emergency shuttle's arrival by ten minutes using a life force of our enemy. Shuttle will be unable to be recalled. This can only be used once." panel = "Shadowling Abilities" range = 1 clothes_req = 0 charge_max = 600 action_icon_state = "extend_shuttle" + var/global/extendlimit = 0 /obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/user = usr) if(!shadowling_check(user)) charge_counter = charge_max return + if(extendlimit == 1) + to_chat(user, "Shuttle was already delayed.") + charge_counter = charge_max + return for(var/mob/living/carbon/human/target in targets) if(target.stat) charge_counter = charge_max return - if(!is_thrall(target)) - to_chat(user, "[target] must be a thrall.") + if(is_shadow_or_thrall(target)) + to_chat(user, "[target] must not be an ally.") charge_counter = charge_max return if(SSshuttle.emergency.mode != SHUTTLE_CALL) @@ -648,7 +665,9 @@ "You begin to draw [M]'s life force.") M.visible_message("[M]'s face falls slack, [M.p_their()] jaw slightly distending.", \ "You are suddenly transported... far, far away...") - if(!do_after(user, 50, target = M)) + extendlimit = 1 + if(!do_after(user, 150, target = M)) + extendlimit = 0 to_chat(M, "You are snapped back to reality, your haze dissipating!") to_chat(user, "You have been interrupted. The draw has failed.") return @@ -657,10 +676,9 @@ "...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...") M.death() if(SSshuttle.emergency.mode == SHUTTLE_CALL) - var/more_minutes = 9000 - var/timer = SSshuttle.emergency.timeLeft() - timer += more_minutes - event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg') + var/more_minutes = 6000 + var/timer = SSshuttle.emergency.timeLeft(1) + more_minutes + event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 10 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg') SSshuttle.emergency.setTimer(timer) SSshuttle.emergency.canRecall = FALSE user.mind.spell_list.Remove(src) //Can only be used once! diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index 9150f25736a..aff40200c6b 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -1,12 +1,12 @@ -/mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic - var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam") +/mob/proc/rightandwrong(summon_type, revolver_fight = FALSE, fake_revolver_fight = FALSE) //0 = Summon Guns, 1 = Summon Magic + var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam", "fakerevolver") var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special","voodoo","special") var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos","necromantic") to_chat(usr, "You summoned [summon_type ? "magic" : "guns"]!") - message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]!") + message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]! ([revolver_fight ? "Revolver duel!" : ""] [fake_revolver_fight ? "Suicidal revolver duel!" : ""])") for(var/mob/living/carbon/human/H in GLOB.player_list) if(H.stat == 2 || !(H.client)) @@ -17,6 +17,13 @@ var/randomizeguns = pick(gunslist) var/randomizemagic = pick(magiclist) var/randomizemagicspecial = pick(magicspeciallist) + if(revolver_fight) + randomizeguns = "revolver" + if(fake_revolver_fight) + if(prob(50)) + randomizeguns = "revolver" + else + randomizeguns = "fakerevolver" if(!summon_type) switch(randomizeguns) if("taser") @@ -88,6 +95,8 @@ new /obj/item/gun/projectile/revolver/grenadelauncher(get_turf(H)) if("medibeam") new /obj/item/gun/medbeam(get_turf(H)) + if("fakerevolver") + new /obj/item/toy/russian_revolver/trick_revolver(get_turf(H)) //lol playsound(get_turf(H), 'sound/magic/summon_guns.ogg', 50, 1) else diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index e7893c3f84e..66cdff69b3f 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -409,6 +409,15 @@ limit = 3 category = "Assistance" +/datum/spellbook_entry/item/oozebottle + name = "Bottle of Ooze" + desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with. Be careful though, as Morph diet includes Wizards." + item_path = /obj/item/antag_spawner/morph + cost = 1 + log_name = "BO" + limit = 3 + category = "Assistance" + /datum/spellbook_entry/item/tarotdeck name = "Tarot Deck" desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \ diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index e2cffabcfd0..ecae6919813 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -18,8 +18,8 @@ access_heads, access_construction, access_sec_doors, access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_minisat, access_mechanic, access_mineral_storeroom) minimal_player_age = 21 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_ENGINEERING outfit = /datum/outfit/job/chief_engineer /datum/outfit/job/chief_engineer diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 61e458927e9..9e06d662053 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -235,9 +235,9 @@ return 1 /datum/outfit/job/proc/imprint_idcard(mob/living/carbon/human/H) - var/datum/job/J = job_master.GetJobType(jobtype) + var/datum/job/J = SSjobs.GetJobType(jobtype) if(!J) - J = job_master.GetJob(H.job) + J = SSjobs.GetJob(H.job) var/alt_title if(H.mind) diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index aaf1a61a2a1..49e6b4486ac 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -16,8 +16,8 @@ access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, access_keycard_auth, access_sec_doors, access_psychiatrist, access_maint_tunnels, access_paramedic, access_mineral_storeroom) minimal_player_age = 21 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_MEDICAL outfit = /datum/outfit/job/cmo /datum/outfit/job/cmo diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index a1711bf4fd8..435565434c8 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -18,8 +18,8 @@ access_research, access_robotics, access_xenobiology, access_ai_upload, access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_minisat, access_maint_tunnels, access_mineral_storeroom, access_network) minimal_player_age = 21 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_SCIENCE // All science-y guys get bonuses for maxing out their tech. required_objectives = list( /datum/job_objective/further_research diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index b425532bf30..407393eb489 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -18,8 +18,8 @@ access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting, access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_pilot, access_weapons) minimal_player_age = 21 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_SECURITY disabilities_allowed = 0 outfit = /datum/outfit/job/hos diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm index 0def40bc7b1..c239c1d3b3b 100644 --- a/code/game/jobs/job/silicon.dm +++ b/code/game/jobs/job/silicon.dm @@ -9,8 +9,8 @@ department_head = list("Captain") req_admin_notify = 1 minimal_player_age = 30 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_SILICON /datum/job/ai/equip(mob/living/carbon/human/H) if(!H) diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 3cdbb9b7247..710835ca873 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -13,8 +13,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) access = list() //See get_access() minimal_access = list() //See get_access() minimal_player_age = 30 - exp_requirements = 2400 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_COMMAND disabilities_allowed = 0 outfit = /datum/outfit/job/captain @@ -68,8 +68,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) req_admin_notify = 1 is_command = 1 minimal_player_age = 21 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_COMMAND access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads, access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue, diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index fa13fbdb4b7..6f5be69280a 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -72,7 +72,7 @@ var/global/list/role_playtime_requirements = list( jtext = "-" if(C.mob.mind && C.mob.mind.assigned_role) - theirjob = job_master.GetJob(C.mob.mind.assigned_role) + theirjob = SSjobs.GetJob(C.mob.mind.assigned_role) if(theirjob) jtext = theirjob.title msg += "[jtext]" @@ -100,6 +100,7 @@ var/global/list/role_playtime_requirements = list( // Procs /proc/role_available_in_playtime(client/C, role) + // "role" is a special role defined in role_playtime_requirements above. e.g: ROLE_ERT. This is *not* a job title. if(!C) return 0 if(!role) @@ -121,6 +122,7 @@ var/global/list/role_playtime_requirements = list( return req_mins return max(0, req_mins - my_exp) + /datum/job/proc/available_in_playtime(client/C) if(!C) return 0 @@ -178,7 +180,7 @@ var/global/list/role_playtime_requirements = list( if(config.use_exp_restrictions) var/list/jobs_locked = list() var/list/jobs_unlocked = list() - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(job.exp_requirements && job.exp_type) if(!job.available_in_playtime(mob.client)) jobs_unlocked += job.title diff --git a/code/game/jobs/job_scaling.dm b/code/game/jobs/job_scaling.dm index 89bd8374351..90d55b03444 100644 --- a/code/game/jobs/job_scaling.dm +++ b/code/game/jobs/job_scaling.dm @@ -5,7 +5,7 @@ if(playercount >= highpop_trigger) log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - loading highpop job config"); - job_master.LoadJobs("config/jobs_highpop.txt") + SSjobs.LoadJobs("config/jobs_highpop.txt") else log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config"); return 1 \ No newline at end of file diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 917c198af2f..c447ff26e72 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -149,7 +149,7 @@ occupantData["stat"] = occupant.stat occupantData["health"] = occupant.health occupantData["maxHealth"] = occupant.maxHealth - occupantData["minHealth"] = config.health_threshold_dead + occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD occupantData["bruteLoss"] = occupant.getBruteLoss() occupantData["oxyLoss"] = occupant.getOxyLoss() occupantData["toxLoss"] = occupant.getToxLoss() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index db5c2b6e9c3..1faf99daec0 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -81,6 +81,7 @@ power_channel = ENVIRON req_one_access = list(access_atmospherics, access_engine_equip) armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100) + siemens_strength = 1 var/alarm_id = null var/frequency = ATMOS_VENTSCRUB //var/skipprocess = 0 //Experimenting @@ -212,8 +213,8 @@ /obj/machinery/alarm/Destroy() GLOB.air_alarms -= src - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null air_alarm_repository.update_cache(src) QDEL_NULL(wires) @@ -432,9 +433,9 @@ send_signal(id_tag, list("status") ) /obj/machinery/alarm/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_TO_AIRALARM) + radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) /obj/machinery/alarm/proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise if(!radio_connection) @@ -571,7 +572,7 @@ update_icon() /obj/machinery/alarm/proc/post_alert(alert_level) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(alarm_frequency) + var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency) if(!frequency) return diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 61547f270bf..d262b523808 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -121,9 +121,9 @@ /obj/machinery/air_sensor/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/air_sensor/Initialize() ..() @@ -132,8 +132,8 @@ /obj/machinery/air_sensor/Destroy() SSair.atmos_machinery -= src - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -156,8 +156,8 @@ var/datum/radio_frequency/radio_connection /obj/machinery/computer/general_air_control/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -268,9 +268,9 @@ return output /obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/computer/general_air_control/Initialize() ..() diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index dba1d942e2d..453d5cdee1e 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -65,7 +65,7 @@ icon_state = "meter4" if(frequency) - var/datum/radio_frequency/radio_connection = radio_controller.return_frequency(frequency) + var/datum/radio_frequency/radio_connection = SSradio.return_frequency(frequency) if(!radio_connection) return diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index a76bd387ac7..b968a4bd5f8 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -33,7 +33,7 @@ pixel_x = 25 if(WEST) pixel_x = -25 - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/machinery/driver_button/Initialize() @@ -41,14 +41,14 @@ set_frequency(frequency) /obj/machinery/driver_button/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_LOGIC) + radio_connection = SSradio.add_object(src, frequency, RADIO_LOGIC) return /obj/machinery/driver_button/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 17a27812499..7ce515365ae 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -34,7 +34,7 @@ var/obj/effect/countdown/clonepod/countdown - var/list/brine_types = list("corazone", "salbutamol", "hydrocodone") + var/list/brine_types = list("corazone", "perfluorodecalin", "epinephrine", "salglu_solution") //stops heart attacks, heart failure, shock, and keeps their O2 levels normal var/list/missing_organs var/organs_number = 0 @@ -341,7 +341,7 @@ check_brine() //Also heal some oxyloss ourselves just in case!! - occupant.adjustOxyLoss(-4) + occupant.adjustOxyLoss(-10) use_power(7500) //This might need tweaking. @@ -449,10 +449,14 @@ /obj/machinery/clonepod/proc/go_out() countdown.stop() - + var/turf/T = get_turf(src) if(mess) //Clean that mess and dump those gibs! - mess = 0 - gibs(loc) + for(var/i in missing_organs) + var/obj/I = i + I.forceMove(T) + missing_organs.Cut() + mess = FALSE + new /obj/effect/gibspawner/generic(get_turf(src), occupant) playsound(loc, 'sound/effects/splat.ogg', 50, 1) update_icon() return @@ -476,10 +480,13 @@ for(var/i in missing_organs) qdel(i) missing_organs.Cut() - occupant.forceMove(get_turf(src)) + occupant.SetLoseBreath(0) // Stop friggin' dying, gosh damn + occupant.setOxyLoss(0) + for(var/datum/disease/critical/crit in occupant.viruses) + crit.cure() + occupant.forceMove(T) occupant.update_body() domutcheck(occupant) //Waiting until they're out before possible notransform. - occupant.shock_stage = 0 //Reset Shock occupant.special_post_clone_handling() occupant = null update_icon() diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index c338a0f32c9..c4c8d342aeb 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -112,7 +112,7 @@ occupantData["stat"] = occupant.stat occupantData["health"] = occupant.health occupantData["maxHealth"] = occupant.maxHealth - occupantData["minHealth"] = config.health_threshold_dead + occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD occupantData["bruteLoss"] = occupant.getBruteLoss() occupantData["oxyLoss"] = occupant.getOxyLoss() occupantData["toxLoss"] = occupant.getToxLoss() diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 22a376968d0..e6a57f4a875 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -25,12 +25,7 @@ ui_interact(user) /obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) - ui_interact(user) - else - if(mode.kickoff) - to_chat(user, "You have been locked out from this console!") + ui_interact(user) /obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 4cde71a4705..5cb19358358 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -69,7 +69,7 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/proc/format_jobs(list/jobs) var/list/formatted = list() for(var/job in jobs) - if(job_in_department(job_master.GetJob(job))) + if(job_in_department(SSjobs.GetJob(job))) formatted.Add(list(list( "display_name" = replacetext(job, " ", " "), "target_rank" = get_target_rank(), @@ -79,7 +79,7 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/proc/format_job_slots() var/list/formatted = list() - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(job_blacklisted_full(job)) continue if(!job_in_department(job)) @@ -166,7 +166,7 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/proc/can_close_job(datum/job/job) if(job) if(!job_blacklisted_full(job) && !job_blacklisted_partial(job) && job_in_department(job, FALSE)) - if(job.total_positions > job.current_positions && !(job in job_master.prioritized_jobs)) + if(job.total_positions > job.current_positions && !(job in SSjobs.prioritized_jobs)) var/delta = (world.time / 10) - time_last_changed_position if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) return 1 @@ -177,10 +177,10 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/proc/can_prioritize_job(datum/job/job) if(job) if(!job_blacklisted_full(job) && job_in_department(job, FALSE)) - if(job in job_master.prioritized_jobs) + if(job in SSjobs.prioritized_jobs) return 2 else - if(job_master.prioritized_jobs.len >= 3) + if(SSjobs.prioritized_jobs.len >= 3) return 0 if(job.total_positions <= job.current_positions) return 0 @@ -205,7 +205,7 @@ var/time_last_changed_position = 0 /obj/machinery/computer/card/proc/get_subordinates(rank, addcivs) var/list/jobs_returned = list() - for(var/datum/job/thisjob in job_master.occupations) + for(var/datum/job/thisjob in SSjobs.occupations) if(rank in thisjob.department_head) jobs_returned += thisjob.title if(addcivs) @@ -364,10 +364,10 @@ var/time_last_changed_position = 0 if(target_dept && modify.assignment == "Unassigned") visible_message("[src]: Demoted individuals must see the HoP for a new job.") return 0 - if(!job_in_department(job_master.GetJob(modify.rank), FALSE)) + if(!job_in_department(SSjobs.GetJob(modify.rank), FALSE)) visible_message("[src]: Cross-department job transfers must be done by the HoP.") return 0 - if(!job_in_department(job_master.GetJob(t1))) + if(!job_in_department(SSjobs.GetJob(t1))) return 0 if(t1 == "Custom") var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN)) @@ -473,7 +473,7 @@ var/time_last_changed_position = 0 if(modify.assignment == "Unassigned") visible_message("[src]: Unassigned crew cannot be demoted any further. If further action is warranted, ask the Captain about Termination.") return 0 - if(!job_in_department(job_master.GetJob(modify.rank), FALSE)) + if(!job_in_department(SSjobs.GetJob(modify.rank), FALSE)) visible_message("[src]: Heads may only demote members of their own department.") return 0 @@ -494,7 +494,7 @@ var/time_last_changed_position = 0 // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS if(is_authenticated(usr)) var/edit_job_target = href_list["job"] - var/datum/job/j = job_master.GetJob(edit_job_target) + var/datum/job/j = SSjobs.GetJob(edit_job_target) if(!job_in_department(j, FALSE)) return 0 if(!j) @@ -513,7 +513,7 @@ var/time_last_changed_position = 0 // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS if(is_authenticated(usr)) var/edit_job_target = href_list["job"] - var/datum/job/j = job_master.GetJob(edit_job_target) + var/datum/job/j = SSjobs.GetJob(edit_job_target) if(!job_in_department(j, FALSE)) return 0 if(!j) @@ -533,17 +533,17 @@ var/time_last_changed_position = 0 // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY if(is_authenticated(usr) && !target_dept) var/priority_target = href_list["job"] - var/datum/job/j = job_master.GetJob(priority_target) + var/datum/job/j = SSjobs.GetJob(priority_target) if(!j) return 0 if(!job_in_department(j)) return 0 var/priority = TRUE - if(j in job_master.prioritized_jobs) - job_master.prioritized_jobs -= j + if(j in SSjobs.prioritized_jobs) + SSjobs.prioritized_jobs -= j priority = FALSE - else if(job_master.prioritized_jobs.len < 3) - job_master.prioritized_jobs += j + else if(SSjobs.prioritized_jobs.len < 3) + SSjobs.prioritized_jobs += j else return 0 log_game("[key_name(usr)] [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".") diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index c134747cd41..acdbc1110f3 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -36,10 +36,13 @@ if(scanner.occupant && can_autoprocess()) scan_mob(scanner.occupant) - + + if(!LAZYLEN(records)) + return + for(var/obj/machinery/clonepod/pod in pods) if(!(pod.occupant || pod.mess) && (pod.efficiency > 5)) - for(var/datum/dna2/record/R in src.records) + for(var/datum/dna2/record/R in records) if(!(pod.occupant || pod.mess)) if(pod.growclone(R)) records.Remove(R) @@ -392,6 +395,12 @@ SSnanoui.update_uis(src) return + for(var/obj/machinery/clonepod/pod in pods) + if(pod.occupant && pod.clonemind == subject.mind) + scantemp = "Subject already getting cloned." + SSnanoui.update_uis(src) + return + subject.dna.check_integrity() var/datum/dna2/record/R = new /datum/dna2/record() diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 854525dadf4..e369b203759 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -494,7 +494,7 @@ /proc/post_status(command, data1, data2, mob/user = null) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) + var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/game/machinery/computer/depot.dm b/code/game/machinery/computer/depot.dm index 4e6afa0c229..149e2b7ff49 100644 --- a/code/game/machinery/computer/depot.dm +++ b/code/game/machinery/computer/depot.dm @@ -283,7 +283,7 @@ return message_sent = TRUE if(user.mind && user.mind.special_role == SPECIAL_ROLE_TRAITOR) - var/input = stripped_input(user, "Please choose a message to transmit to Syndicate HQ via quantum entanglement. Transmission does not guarantee a response. This function may only be used ONCE.", "To abort, send an empty message.", "") as text|null + var/input = stripped_input(user, "Please choose a message to transmit to Syndicate HQ via quantum entanglement. Transmission does not guarantee a response. This function may only be used ONCE.", "To abort, send an empty message.", "") if(!input) message_sent = FALSE return diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index e0969555ce9..74cc417e7ce 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -28,19 +28,17 @@ attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/aiModule)) + if(!current)//no AI selected + to_chat(user, "No AI selected. Please chose a target before proceeding with upload.") + return var/turf/T = get_turf(current) if(!atoms_share_level(T, src)) to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") return - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) - var/obj/item/aiModule/M = O - M.install(src) - else - if(mode.kickoff) - to_chat(user, "You have been locked out from modifying the AI's laws!") - else - ..() + var/obj/item/aiModule/M = O + M.install(src) + return + return ..() attack_hand(var/mob/user as mob) @@ -73,18 +71,16 @@ attackby(obj/item/aiModule/module as obj, mob/user as mob, params) if(istype(module, /obj/item/aiModule)) + if(!current)//no borg selected + to_chat(user, "No borg selected. Please chose a target before proceeding with upload.") + return var/turf/T = get_turf(current) if(!atoms_share_level(T, src)) to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!") return - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) - module.install(src) - else - if(mode.kickoff) - to_chat(user, "You have been locked out from modifying the borg's laws!") - else - return ..() + module.install(src) + return + return ..() attack_hand(var/mob/user as mob) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 5d4e838db38..8def58c370b 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -20,12 +20,7 @@ return if(stat & (NOPOWER|BROKEN)) return - var/datum/game_mode/nations/mode = get_nations_mode() - if(!mode) - ui_interact(user) - else - if(mode.kickoff) - to_chat(user, "You have been locked out from this console!") + ui_interact(user) /obj/machinery/computer/robotics/proc/is_authenticated(var/mob/user as mob) if(user.can_admin_interact()) diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index ece6615b786..9e91e254950 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -541,21 +541,20 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/chem_dispenser - name = "circuit board (Portable Chem Dispenser)" - build_path = /obj/machinery/chem_dispenser/constructable + name = "circuit board (Chem Dispenser)" + build_path = /obj/machinery/chem_dispenser board_type = "machine" origin_tech = "materials=4;programming=4;plasmatech=4;biotech=3" frame_desc = "Requires 2 Matter Bins, 1 Capacitor, 1 Manipulator, 1 Console Screen, and 1 Power Cell." - req_components = list( - /obj/item/stock_parts/matter_bin = 2, + req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/console_screen = 1, /obj/item/stock_parts/cell = 1) /obj/item/circuitboard/chem_master - name = "circuit board (Chem Master 2999)" - build_path = /obj/machinery/chem_master/constructable + name = "circuit board (ChemMaster 3000)" + build_path = /obj/machinery/chem_master board_type = "machine" origin_tech = "materials=3;programming=2;biotech=3" req_components = list( @@ -563,6 +562,25 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/console_screen = 1) +/obj/item/circuitboard/chem_master/attackby(obj/item/I, mob/user, params) + if(isscrewdriver(I)) + var/new_name = "ChemMaster" + var/new_path = /obj/machinery/chem_master + + if(build_path == /obj/machinery/chem_master) + new_name = "CondiMaster" + new_path = /obj/machinery/chem_master/condimaster + + build_path = new_path + name = "circuit board ([new_name] 3000)" + to_chat(user, "You change the circuit board setting to \"[new_name]\".") + else + return ..() + +/obj/item/circuitboard/chem_master/condi_master + name = "circuit board (CondiMaster 3000)" + build_path = /obj/machinery/chem_master/condimaster + /obj/item/circuitboard/chem_heater name = "circuit board (Chemical Heater)" build_path = /obj/machinery/chem_heater @@ -617,30 +635,13 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/manipulator = 2, /obj/item/reagent_containers/glass/beaker = 2) -/obj/item/circuitboard/soda +/obj/item/circuitboard/chem_dispenser/soda name = "Circuit board (Soda Machine)" build_path = /obj/machinery/chem_dispenser/soda - board_type = "machine" - frame_desc = "Requires 2 Matter Bins, 1 Manipulators, 1 Capacitor, 1 Console Screen, and 1 Power Cell." - req_components = list( - /obj/item/stock_parts/matter_bin = 2, - /obj/item/stock_parts/manipulator = 1, - /obj/item/stock_parts/capacitor = 1, - /obj/item/stock_parts/console_screen = 1, - /obj/item/stock_parts/cell = 1) -/obj/item/circuitboard/beer +/obj/item/circuitboard/chem_dispenser/beer name = "Circuit board (Beer Machine)" build_path = /obj/machinery/chem_dispenser/beer - board_type = "machine" - frame_desc = "Requires 2 Matter Bins, 1 Manipulators, 1 Capacitor, 1 Console Screen, and 1 Power Cell." - req_components = list( - /obj/item/stock_parts/matter_bin = 2, - /obj/item/stock_parts/manipulator = 1, - /obj/item/stock_parts/capacitor = 1, - /obj/item/stock_parts/console_screen = 1, - /obj/item/stock_parts/cell = 1) - /obj/item/circuitboard/circuit_imprinter name = "Circuit board (Circuit Imprinter)" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index fc60d8f005d..3dad2e66f7d 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -208,7 +208,7 @@ occupantData["stat"] = occupant.stat occupantData["health"] = occupant.health occupantData["maxHealth"] = occupant.maxHealth - occupantData["minHealth"] = config.health_threshold_dead + occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD occupantData["bruteLoss"] = occupant.getBruteLoss() occupantData["oxyLoss"] = occupant.getOxyLoss() occupantData["toxLoss"] = occupant.getToxLoss() @@ -220,7 +220,7 @@ data["cellTemperatureStatus"] = "good" if(air_contents.temperature > T0C) // if greater than 273.15 kelvin (0 celcius) data["cellTemperatureStatus"] = "bad" - else if(air_contents.temperature > 225) + else if(air_contents.temperature > TCRYO) data["cellTemperatureStatus"] = "average" data["isBeakerLoaded"] = beaker ? 1 : 0 @@ -378,9 +378,9 @@ occupant.Paralyse(max(5/efficiency, (1/occupant.bodytemperature)*3000/efficiency)) if(air_contents.oxygen > 2) if(occupant.getOxyLoss()) - occupant.adjustOxyLoss(-10) + occupant.adjustOxyLoss(-6) else - occupant.adjustOxyLoss(-2) + occupant.adjustOxyLoss(-1.2) if(beaker && next_trans == 0) var/proportion = 10 * min(1/beaker.volume, 1) // Yes, this means you can get more bang for your buck with a beaker of SF vs a patch @@ -388,7 +388,7 @@ beaker.reagents.reaction(occupant, TOUCH, proportion) beaker.reagents.trans_to(occupant, 1, 10) next_trans++ - if(next_trans == 10) + if(next_trans == 17) next_trans = 0 /obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index a1bdff99d56..9674a60c7d4 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -397,7 +397,7 @@ //Handle job slot/tater cleanup. var/job = occupant.mind.assigned_role - job_master.FreeRole(job) + SSjobs.FreeRole(job) if(occupant.mind.objectives.len) occupant.mind.objectives.Cut() @@ -769,3 +769,12 @@ target_cryopod.take_occupant(person_to_cryo, 1) return 1 return 0 + +/proc/force_cryo_human(var/mob/living/carbon/person_to_cryo) + if(!istype(person_to_cryo)) + return + if(!istype(person_to_cryo.loc, /obj/machinery/cryopod)) + cryo_ssd(person_to_cryo) + if(istype(person_to_cryo.loc, /obj/machinery/cryopod)) + var/obj/machinery/cryopod/P = person_to_cryo.loc + P.despawn_occupant() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 54153118131..cf580edd5ea 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -51,6 +51,7 @@ var/list/airlock_overlays = list() explosion_block = 1 assemblytype = /obj/structure/door_assembly normalspeed = 1 + siemens_strength = 1 var/security_level = 0 //How much are wires secured var/aiControlDisabled = FALSE //If TRUE, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. var/hackProof = FALSE // if TRUE, this door can't be hacked by the AI @@ -70,7 +71,7 @@ var/list/airlock_overlays = list() var/lockdownbyai = 0 var/justzap = 0 var/obj/item/airlock_electronics/electronics - var/hasShocked = 0 //Prevents multiple shocks from happening + var/shockCooldown = FALSE //Prevents multiple shocks from happening var/obj/item/note //Any papers pinned to the airlock var/previous_airlock = /obj/structure/door_assembly //what airlock assembly mineral plating was applied to var/airlock_material //material of inner filling; if its an airlock with glass, this should be set to "glass" @@ -151,8 +152,8 @@ About the new airlock wires panel: if(electrified_timer) deltimer(electrified_timer) electrified_timer = null - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -173,10 +174,8 @@ About the new airlock wires panel: else /*if(justzap)*/ return else if(user.hallucination > 50 && prob(10) && !operating) - to_chat(user, "You feel a powerful shock course through your body!") - user.adjustStaminaLoss(50) - user.AdjustStunned(5) - return + if(user.electrocute_act(50, src, 1, illusion = TRUE)) // We'll just go with a flat 50 damage, instead of doing powernet checks + return ..(user) /obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user) @@ -296,16 +295,14 @@ About the new airlock wires panel: // The preceding comment was borrowed from the grille's shock script /obj/machinery/door/airlock/shock(mob/user, prb) if(!arePowerSystemsOn()) - return 0 - if(hasShocked) - return 0 //Already shocked someone recently? + return FALSE + if(shockCooldown > world.time) + return FALSE //Already shocked someone recently? if(..()) - hasShocked = 1 - sleep(10) - hasShocked = 0 - return 1 + shockCooldown = world.time + 10 + return TRUE else - return 0 + return FALSE //Checks if the user can get shocked and shocks him if it can. Returns TRUE if it happened /obj/machinery/door/airlock/proc/shock_user(mob/user, prob) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 7eb43cdec74..496d8942bcc 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -127,10 +127,10 @@ return /obj/machinery/door/airlock/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) if(new_frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) /obj/machinery/door/airlock/Initialize() ..() @@ -143,7 +143,7 @@ /obj/machinery/door/airlock/New() ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/machinery/airlock_sensor @@ -203,9 +203,9 @@ update_icon() /obj/machinery/airlock_sensor/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) /obj/machinery/airlock_sensor/Initialize() ..() @@ -213,12 +213,12 @@ /obj/machinery/airlock_sensor/New() ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/machinery/airlock_sensor/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -271,9 +271,9 @@ flick("access_button_cycle", src) /obj/machinery/access_button/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) /obj/machinery/access_button/Initialize() ..() @@ -282,12 +282,12 @@ /obj/machinery/access_button/New() ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/machinery/access_button/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 8e3c7f76342..a0d6efc5d1f 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -542,7 +542,7 @@ icon = 'icons/obj/doors/airlocks/glass_large/glass_large.dmi' overlays_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi' note_overlay_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi' - assemblytype = "obj/structure/door_assembly/multi_tile" + assemblytype = /obj/structure/door_assembly/multi_tile /obj/machinery/door/airlock/multi_tile/narsie_act() return diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 91591234551..d3bf12f72f0 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -13,15 +13,15 @@ air_connection = new /obj/machinery/door/airlock/alarmlock/Destroy() - if(radio_controller) - radio_controller.remove_object(src,air_frequency) + if(SSradio) + SSradio.remove_object(src,air_frequency) air_connection = null return ..() /obj/machinery/door/airlock/alarmlock/Initialize() ..() - radio_controller.remove_object(src, air_frequency) - air_connection = radio_controller.add_object(src, air_frequency, RADIO_TO_AIRALARM) + SSradio.remove_object(src, air_frequency) + air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM) open() /obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 23ee6e19403..e0a49fdfc8c 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -59,8 +59,8 @@ set_frequency(frequency) /obj/machinery/embedded_controller/radio/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -82,6 +82,6 @@ qdel(signal) /obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, radio_filter) + radio_connection = SSradio.add_object(src, frequency, radio_filter) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index d0399dfa2a4..ee6bd060c16 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -30,7 +30,7 @@ pixel_x = 25 if(WEST) pixel_x = -25 - if(radio_controller) + if(SSradio) set_frequency(frequency) spawn(5) src.area = get_area(src) @@ -49,14 +49,14 @@ set_frequency(frequency) /obj/machinery/light_switch/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_LOGIC) + radio_connection = SSradio.add_object(src, frequency, RADIO_LOGIC) return /obj/machinery/light_switch/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 553016400ad..c74ee23d25c 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -119,6 +119,7 @@ Class Procs: var/list/settagwhitelist = list()//WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST. atom_say_verb = "beeps" var/defer_process = 0 + var/siemens_strength = 0.7 // how badly will it shock you? /obj/machinery/Initialize() addAtProcessing() @@ -407,7 +408,7 @@ Class Procs: if(can_deconstruct) on_deconstruction() if(component_parts && component_parts.len) - spawn_frame() + spawn_frame(disassembled) for(var/obj/item/I in component_parts) I.forceMove(loc) qdel(src) @@ -575,16 +576,13 @@ Class Procs: /obj/machinery/proc/shock(mob/user, prb) if(inoperable()) - return 0 + return FALSE if(!prob(prb)) - return 0 - if((TK in user.mutations) && !Adjacent(user)) - return 0 + return FALSE do_sparks(5, 1, src) - if(electrocute_mob(user, get_area(src), src, 0.7)) - if(user.stunned) - return 1 - return 0 + if(electrocute_mob(user, get_area(src), src, siemens_strength, TRUE)) + return TRUE + return FALSE //called on machinery construction (i.e from frame to machinery) but not on initialization /obj/machinery/proc/on_construction() diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 3af76895428..9b982df99fd 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -36,8 +36,8 @@ center = T spawn(10) // must wait for map loading to finish - if(radio_controller) - radio_controller.add_object(src, freq, RADIO_MAGNETS) + if(SSradio) + SSradio.add_object(src, freq, RADIO_MAGNETS) spawn() magnetic_process() @@ -208,8 +208,8 @@ spawn(45) // must wait for map loading to finish - if(radio_controller) - radio_connection = radio_controller.add_object(src, frequency, RADIO_MAGNETS) + if(SSradio) + radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) if(path) // check for default path @@ -217,8 +217,8 @@ /obj/machinery/magnetic_controller/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 2e4b7b19378..f354feb1629 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -284,7 +284,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if(12) var/list/jobs = list() data["jobs"] = jobs - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(job_blacklisted(job)) continue if(job.is_position_available()) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 5f875d7fdc8..05545e6a3d1 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -50,15 +50,15 @@ var/const/STATUS_DISPLAY_CUSTOM = 99 /obj/machinery/status_display/Destroy() - if(radio_controller) - radio_controller.remove_object(src,frequency) + if(SSradio) + SSradio.remove_object(src,frequency) return ..() // register for radio system /obj/machinery/status_display/Initialize() ..() - if(radio_controller) - radio_controller.add_object(src, frequency) + if(SSradio) + SSradio.add_object(src, frequency) // timed process /obj/machinery/status_display/process() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index b09d80bd804..5fa69094726 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -11,11 +11,13 @@ var/obj/item/clothing/suit/space/suit = null var/obj/item/clothing/head/helmet/space/helmet = null var/obj/item/clothing/mask/mask = null + var/obj/item/clothing/shoes/magboots/magboots = null var/obj/item/storage = null var/helmet_type = null var/suit_type = null var/mask_type = null + var/magboots_type = null var/storage_type = null var/locked = FALSE @@ -63,7 +65,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/engineering helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/engineering mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_engine_equip) /obj/machinery/suit_storage_unit/engine/secure @@ -74,7 +76,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/elite helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/elite mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots/advance + magboots_type = /obj/item/clothing/shoes/magboots/advance req_access = list(access_ce) /obj/machinery/suit_storage_unit/ce/secure @@ -85,7 +87,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/security helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_security) /obj/machinery/suit_storage_unit/security/secure @@ -99,7 +101,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/atmos helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/atmos mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_atmospherics) /obj/machinery/suit_storage_unit/atmos/secure @@ -128,7 +130,7 @@ /obj/machinery/suit_storage_unit/cmo/secure/sec_storage name = "medical suit storage unit" mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots /obj/machinery/suit_storage_unit/clown name = "clown suit storage unit" @@ -150,13 +152,13 @@ /obj/machinery/suit_storage_unit/syndicate name = "syndicate suit storage unit" - suit_type = /obj/item/clothing/suit/space/hardsuit/syndi - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi - mask_type = /obj/item/clothing/mask/gas/syndicate - storage_type = /obj/item/tank/jetpack/oxygen/harness + suit_type = /obj/item/clothing/suit/space/hardsuit/syndi + helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi + mask_type = /obj/item/clothing/mask/gas/syndicate + magboots_type = /obj/item/clothing/shoes/magboots/syndie + storage_type = /obj/item/tank/jetpack/oxygen/harness req_access = list(access_syndicate) safeties = FALSE //in a syndicate base, everything can be used as a murder weapon at a moment's notice. - uv_super = TRUE //so efficient /obj/machinery/suit_storage_unit/syndicate/secure secure = TRUE @@ -245,6 +247,8 @@ helmet = new helmet_type(src) if(mask_type) mask = new mask_type(src) + if(magboots_type) + magboots = new magboots_type(src) if(storage_type) storage = new storage_type(src) update_icon() @@ -257,6 +261,7 @@ QDEL_NULL(suit) QDEL_NULL(helmet) QDEL_NULL(mask) + QDEL_NULL(magboots) QDEL_NULL(storage) QDEL_NULL(wires) return ..() @@ -324,7 +329,10 @@ if(istype(I, /obj/item/clothing/mask) && !mask) mask = I . = TRUE - if((istype(I, /obj/item/tank) || istype(I, /obj/item/clothing/shoes/magboots)) && !storage) + if(istype(I, /obj/item/clothing/shoes/magboots) && !magboots) + magboots = I + . = TRUE + if((istype(I, /obj/item/tank)) && !storage) storage = I . = TRUE if(.) @@ -410,6 +418,8 @@ qdel(suit) // Delete everything but the occupant. mask = null qdel(mask) + magboots = null + qdel(magboots) storage = null qdel(storage) else @@ -427,8 +437,8 @@ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(5, 1, src) s.start() - if(electrocute_mob(user, get_area(src), src, 1)) - return 1 + if(electrocute_mob(user, src, src, 1, TRUE)) + return TRUE /obj/machinery/suit_storage_unit/relaymove(mob/user) if(locked) @@ -544,7 +554,10 @@ dat+= text("Breathmask storage compartment: []
",(mask ? mask.name : "No breathmask detected.") ) if(mask && state_open) dat+="Dispense mask
" - dat+= text("Tank, Magboots storage compartment: []
",(storage ? storage.name : "
No storage item detected.") ) + dat+= text("Magboots storage compartment: []
",(magboots ? magboots.name : "
No magboots detected.") ) + if(magboots && state_open) + dat+="Dispense magboots
" + dat+= text("Tank storage compartment: []
",(storage ? storage.name : "
No storage item detected.") ) if(storage && state_open) dat+="Dispense storage item
" if(occupant) @@ -604,6 +617,10 @@ dispense_mask(usr) updateUsrDialog() update_icon() + if(href_list["dispense_magboots"]) + dispense_magboots(usr) + updateUsrDialog() + update_icon() if(href_list["dispense_storage"]) dispense_storage(usr) updateUsrDialog() @@ -671,6 +688,13 @@ else mask.forceMove(loc) mask = null + +/obj/machinery/suit_storage_unit/proc/dispense_magboots(mob/user as mob) + if(!magboots) + return + else + magboots.forceMove(loc) + magboots = null /obj/machinery/suit_storage_unit/proc/dispense_storage(mob/user as mob) if(!storage) diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 8e34e2e19bc..8cd285c994a 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -140,7 +140,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/datum/radio_frequency/connection = signal.data["connection"] - if(connection.frequency in ANTAG_FREQS) // if antag broadcast, just + if(connection.frequency in SSradio.ANTAG_FREQS) // if antag broadcast, just Broadcast_Message(signal.data["connection"], signal.data["mob"], signal.data["vmask"], signal.data["vmessage"], signal.data["radio"], signal.data["message"], @@ -162,13 +162,13 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept /proc/Is_Bad_Connection(old_freq, new_freq) //Makes sure players cant read radios of a higher level than they are var/old_type = CREW_RADIO_TYPE var/new_type = CREW_RADIO_TYPE - for(var/antag_freq in ANTAG_FREQS) + for(var/antag_freq in SSradio.ANTAG_FREQS) if(old_freq == antag_freq) old_type = SYNDICATE_RADIO_TYPE if(new_freq == antag_freq) new_type = SYNDICATE_RADIO_TYPE - for(var/cent_freq in CENT_FREQS) + for(var/cent_freq in SSradio.CENT_FREQS) if(old_freq == cent_freq) old_type = CENTCOMM_RADIO_TYPE if(new_freq == cent_freq) @@ -249,7 +249,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept if(connection.frequency != display_freq) bad_connection = Is_Bad_Connection(connection.frequency, display_freq) - new_connection = radio_controller.return_frequency(display_freq) + new_connection = SSradio.return_frequency(display_freq) var/list/obj/item/radio/radios = list() @@ -276,8 +276,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // --- Broadcast to antag radios! --- else if(data == 3) - for(var/antag_freq in ANTAG_FREQS) - var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(antag_freq) + for(var/antag_freq in SSradio.ANTAG_FREQS) + var/datum/radio_frequency/antag_connection = SSradio.return_frequency(antag_freq) for(var/obj/item/radio/R in antag_connection.devices["[RADIO_CHAT]"]) if(R.receive_range(antag_freq, level) > -1) radios += R @@ -356,7 +356,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/part_b_extra = "" if(data == 3) // intercepted radio message part_b_extra = " (Intercepted)" - var/part_a = "\[[freq_text]\][part_b_extra] " // goes in the actual output + var/part_a = "\[[freq_text]\][part_b_extra] " // goes in the actual output // --- Some more pre-message formatting --- var/part_b = " " // Tweaked for security headsets -- TLE @@ -452,7 +452,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept H = new M = H - var/datum/radio_frequency/connection = radio_controller.return_frequency(frequency) + var/datum/radio_frequency/connection = SSradio.return_frequency(frequency) var/display_freq = connection.frequency @@ -485,8 +485,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // --- Broadcast to antag radios! --- else if(data == 3) - for(var/freq in ANTAG_FREQS) - var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(freq) + for(var/freq in SSradio.ANTAG_FREQS) + var/datum/radio_frequency/antag_connection = SSradio.return_frequency(freq) for(var/obj/item/radio/R in antag_connection.devices["[RADIO_CHAT]"]) var/turf/position = get_turf(R) // TODO: Make the radio system cooperate with the space manager @@ -545,7 +545,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept if(length(heard_normal) || length(heard_garbled) || length(heard_gibberish)) /* --- Some miscellaneous variables to format the string output --- */ - var/part_a = "" // goes in the actual output + var/part_a = "" // goes in the actual output var/freq_text = get_frequency_name(display_freq) // --- Some more pre-message formatting --- diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index fb780e5d550..d0872fa8f93 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -38,6 +38,8 @@ layer = 2.9 anchored = 1 density = 1 + max_integrity = 300 + integrity_failure = 100 armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) var/icon_vend //Icon_state when vending var/icon_deny //Icon_state when denying access @@ -96,30 +98,27 @@ var/item_slot = FALSE var/obj/item/inserted_item = null -/obj/machinery/vending/New() - ..() +/obj/machinery/vending/Initialize(mapload) + . = ..() wires = new(src) - spawn(50) - if(product_slogans) - slogan_list += splittext(product_slogans, ";") + if(product_slogans) + slogan_list += splittext(product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - last_slogan = world.time + rand(0, slogan_delay) + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + last_slogan = world.time + rand(0, slogan_delay) - if(product_ads) - ads_list += splittext(product_ads, ";") + if(product_ads) + ads_list += splittext(product_ads, ";") - build_inventory() - power_change() - - return - - return + build_inventory() + power_change() /obj/machinery/vending/Destroy() - eject_item() + QDEL_NULL(wires) + QDEL_NULL(coin) + QDEL_NULL(inserted_item) return ..() /** @@ -148,34 +147,31 @@ product_records.Add(product) -/obj/machinery/vending/Destroy() - QDEL_NULL(wires) - QDEL_NULL(coin) - return ..() - -/obj/machinery/vending/ex_act(severity) +/obj/machinery/vending/ex_act(severity) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable switch(severity) - if(1.0) + if(1) + obj_integrity = 0 qdel(src) - return - if(2.0) - if(prob(50)) - qdel(src) - return - if(3.0) - if(prob(25)) - malfunction() + if(2) + take_damage(rand(100, 250), BRUTE, "bomb", 0) + if(3) + take_damage(rand(10, 90), BRUTE, "bomb", 0) /obj/machinery/vending/RefreshParts() //Better would be to make constructable child if(component_parts) for(var/obj/item/vending_refill/VR in component_parts) refill_inventory(VR, product_records, usr) -/obj/machinery/vending/blob_act() - if(prob(75)) - malfunction() - else +/obj/machinery/vending/deconstruct(disassembled = TRUE) + eject_item() + if(!refill_canister) //the non constructable vendors drop metal instead of a machine frame. + new /obj/item/stack/sheet/metal(loc, 3) qdel(src) + else + ..() + +/obj/machinery/vending/blob_act(obj/structure/blob/B) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + take_damage(400, BRUTE, "melee", 0, get_dir(src, B)) /obj/machinery/vending/proc/refill_inventory(obj/item/vending_refill/refill, list/machine, mob/user) var/total = 0 @@ -236,7 +232,7 @@ if(default_unfasten_wrench(user, I, time = 60)) return - if(istype(I, /obj/item/screwdriver) && anchored) + if(isscrewdriver(I) && anchored) playsound(loc, I.usesound, 50, 1) panel_open = !panel_open to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") @@ -247,9 +243,9 @@ return if(panel_open) - if(istype(I, /obj/item/multitool)||istype(I, /obj/item/wirecutters)) + if(ismultitool(I) || iswirecutter(I)) return attack_hand(user) - if(component_parts && istype(I, /obj/item/crowbar)) + if(component_parts && iscrowbar(I)) var/datum/data/vending_product/machine = product_records for(var/datum/data/vending_product/machine_content in machine) while(machine_content.amount !=0) @@ -259,15 +255,17 @@ if(!machine_content.amount) break default_deconstruction_crowbar(I) - if(istype(I, /obj/item/coin) && premium.len > 0) - user.drop_item() - I.loc = src + return + if(istype(I, /obj/item/coin) && premium.len) + if(!user.drop_item()) + return + I.forceMove(src) coin = I categories |= CAT_COIN to_chat(user, "You insert the [I] into the [src]") SSnanoui.update_uis(src) return - else if(istype(I, refill_canister) && refill_canister != null) + if(istype(I, refill_canister) && refill_canister != null) if(stat & (BROKEN|NOPOWER)) to_chat(user, "It does nothing.") else if(panel_open) @@ -281,21 +279,18 @@ to_chat(user, "You loaded [transfered] items in \the [name].") else to_chat(user, "The [name] is fully stocked.") - return; else to_chat(user, "You should probably unscrew the service panel first.") - else if(item_slot_check(user, I)) + return + if(item_slot_check(user, I)) insert_item(user, I) return - else - return ..() + return ..() //Override this proc to do per-machine checks on the inserted item, but remember to call the parent to handle these generic checks before your logic! /obj/machinery/vending/proc/item_slot_check(mob/user, obj/item/I) if(!item_slot) return FALSE - if(alert(user, "Do you want to attempt to insert [I]?", "","Yes", "No") == "No") - return FALSE if(inserted_item) to_chat(user, "There is something already inserted!") return FALSE @@ -314,28 +309,32 @@ /obj/machinery/vending/proc/insert_item(mob/user, obj/item/I) if(!item_slot || inserted_item) return - if(!user.canUnEquip(I)) + if(!user.drop_item()) to_chat(user, "[I] is stuck to your hand, you can't seem to put it down!") return - user.unEquip(I) inserted_item = I I.forceMove(src) to_chat(user, "You insert [I] into [src].") SSnanoui.update_uis(src) -/obj/machinery/vending/proc/eject_item() +/obj/machinery/vending/proc/eject_item(mob/user) if(!item_slot || !inserted_item) return - inserted_item.forceMove(get_turf(src)) + var/put_on_turf = TRUE + if(user && iscarbon(user) && user.Adjacent(src)) + if(user.put_in_hands(inserted_item)) + put_on_turf = FALSE + if(put_on_turf) + var/turf/T = get_turf(src) + inserted_item.forceMove(T) inserted_item = null SSnanoui.update_uis(src) /obj/machinery/vending/emag_act(user as mob) - emagged = 1 + emagged = TRUE to_chat(user, "You short out the product lock on [src]") - return /** * Receive payment with cashmoney. @@ -511,7 +510,7 @@ categories &= ~CAT_COIN if(href_list["remove_item"]) - eject_item() + eject_item(usr) if(href_list["pay"]) if(currently_vending && vendor_account && !vendor_account.suspended) @@ -593,7 +592,7 @@ return if(coin.string_attached) if(prob(50)) - to_chat(user, "You successfully pull the coin out before the [src] could swallow it.") + to_chat(user, "You successfully pull the coin out before [src] could swallow it.") else to_chat(user, "You weren't able to pull the coin out fast enough, the machine ate it, string and all.") QDEL_NULL(coin) @@ -605,25 +604,33 @@ R.amount-- if(((last_reply + (vend_delay + 200)) <= world.time) && vend_reply) - spawn(0) - speak(src.vend_reply) - last_reply = world.time + speak(src.vend_reply) + last_reply = world.time use_power(vend_power_usage) //actuators and stuff if(icon_vend) //Show the vending animation if needed - flick(icon_vend,src) - spawn(vend_delay) - do_vend(R) - status_message = "" - status_error = 0 - vend_ready = 1 - currently_vending = null - SSnanoui.update_uis(src) + flick(icon_vend, src) + addtimer(CALLBACK(src, .proc/delayed_vend, R, user), vend_delay) + +/obj/machinery/vending/proc/delayed_vend(datum/data/vending_product/R, mob/user) + do_vend(R, user) + status_message = "" + status_error = 0 + vend_ready = 1 + currently_vending = null + SSnanoui.update_uis(src) //override this proc to add handling for what to do with the vended product when you have a inserted item and remember to include a parent call for this generic handling -/obj/machinery/vending/proc/do_vend(datum/data/vending_product/R) +/obj/machinery/vending/proc/do_vend(datum/data/vending_product/R, mob/user) if(!item_slot || !inserted_item) - new R.product_path(get_turf(src)) + var/put_on_turf = TRUE + var/obj/vended = new R.product_path() + if(user && iscarbon(user) && user.Adjacent(src)) + if(user.put_in_hands(vended)) + put_on_turf = FALSE + if(put_on_turf) + var/turf/T = get_turf(src) + vended.forceMove(T) return TRUE return FALSE @@ -638,7 +645,7 @@ qdel(vended) */ -/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user) +/obj/machinery/vending/proc/stock(datum/data/vending_product/R, mob/user) if(panel_open) to_chat(user, "You stock the [src] with \a [R.product_name]") R.amount++ @@ -664,8 +671,6 @@ if(shoot_inventory && prob(shoot_chance)) throw_item() - return - /obj/machinery/vending/proc/speak(message) if(stat & NOPOWER) return @@ -686,28 +691,38 @@ icon_state = "[initial(icon_state)]-off" stat |= NOPOWER -//Oh no we're malfunctioning! Dump out some product and break. -/obj/machinery/vending/proc/malfunction() - for(var/datum/data/vending_product/R in product_records) - if(R.amount <= 0) //Try to use a record that actually has something to dump. - continue - var/dump_path = R.product_path - if(!dump_path) - continue +/obj/machinery/vending/obj_break(damage_flag) + if(!(stat & BROKEN)) + stat |= BROKEN + icon_state = "[initial(icon_state)]-broken" - while(R.amount>0) - new dump_path(loc) - R.amount-- - break + var/dump_amount = 0 + var/found_anything = TRUE + while (found_anything) + found_anything = FALSE + for(var/record in shuffle(product_records)) + var/datum/data/vending_product/R = record + if(R.amount <= 0) //Try to use a record that actually has something to dump. + continue + var/dump_path = R.product_path + if(!dump_path) + continue + R.amount-- + // busting open a vendor will destroy some of the contents + if(found_anything && prob(80)) + continue - stat |= BROKEN - icon_state = "[initial(icon_state)]-broken" - return + var/obj/O = new dump_path(loc) + step(O, pick(alldirs)) + found_anything = TRUE + dump_amount++ + if(dump_amount >= 16) + return //Somebody cut an important wire and now we're following a new definition of "pitch." /obj/machinery/vending/proc/throw_item() var/obj/throw_item = null - var/mob/living/target = locate() in view(7,src) + var/mob/living/target = locate() in view(7, src) if(!target) return 0 @@ -722,11 +737,9 @@ throw_item = new dump_path(loc) break if(!throw_item) - return 0 - spawn(0) - throw_item.throw_at(target, 16, 3, src) + return + throw_item.throw_at(target, 16, 3, src) visible_message("[src] launches [throw_item.name] at [target.name]!") - return 1 /* * Vending machine types @@ -840,28 +853,39 @@ component_parts += new /obj/item/vending_refill/coffee(0) /obj/machinery/vending/coffee/item_slot_check(mob/user, obj/item/I) + if(!(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks))) + return FALSE if(!..()) return FALSE - if(!(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks))) - to_chat(user, "[I] is not compatible with this machine.") - return FALSE if(!I.is_open_container()) - to_chat(user, "You need to open [I] before you insert it.") + to_chat(user, "You need to open [I] before inserting it.") return FALSE return TRUE -/obj/machinery/vending/coffee/do_vend(datum/data/vending_product/R) +/obj/machinery/vending/coffee/do_vend(datum/data/vending_product/R, mob/user) if(..()) return var/obj/item/reagent_containers/food/drinks/vended = new R.product_path() if(istype(vended, /obj/item/reagent_containers/food/drinks/mug)) - vended.forceMove(get_turf(src)) + var/put_on_turf = TRUE + if(user && iscarbon(user) && user.Adjacent(src)) + if(user.put_in_hands(vended)) + put_on_turf = FALSE + if(put_on_turf) + var/turf/T = get_turf(src) + vended.forceMove(T) return vended.reagents.trans_to(inserted_item, vended.reagents.total_volume) if(vended.reagents.total_volume) - vended.forceMove(get_turf(src)) + var/put_on_turf = TRUE + if(user && iscarbon(user) && user.Adjacent(src)) + if(user.put_in_hands(vended)) + put_on_turf = FALSE + if(put_on_turf) + var/turf/T = get_turf(src) + vended.forceMove(T) else qdel(vended) @@ -1015,23 +1039,25 @@ icon_deny = "med-deny" product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" req_access_txt = "5" - products = list(/obj/item/reagent_containers/glass/bottle/charcoal = 4,/obj/item/reagent_containers/glass/bottle/morphine = 4,/obj/item/reagent_containers/glass/bottle/ether = 4,/obj/item/reagent_containers/glass/bottle/epinephrine = 4, - /obj/item/reagent_containers/glass/bottle/toxin = 4,/obj/item/reagent_containers/syringe/antiviral = 6,/obj/item/reagent_containers/syringe/insulin = 4, - /obj/item/reagent_containers/syringe = 12,/obj/item/healthanalyzer = 5,/obj/item/healthupgrade = 5,/obj/item/reagent_containers/glass/beaker = 4, /obj/item/reagent_containers/hypospray/safety = 2, - /obj/item/reagent_containers/dropper = 2,/obj/item/stack/medical/bruise_pack/advanced = 3, /obj/item/stack/medical/ointment/advanced = 3, - /obj/item/stack/medical/bruise_pack = 3,/obj/item/stack/medical/splint = 4, /obj/item/sensor_device = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, - /obj/item/pinpointer/crew = 2) - contraband = list(/obj/item/reagent_containers/glass/bottle/pancuronium = 1,/obj/item/reagent_containers/glass/bottle/sulfonal = 1) + products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/food/pill/patch/styptic = 10, /obj/item/reagent_containers/food/pill/patch/silver_sulf = 10, + /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/diphenhydramine = 4, + /obj/item/reagent_containers/glass/bottle/salicylic = 4, /obj/item/reagent_containers/glass/bottle/potassium_iodide =3, /obj/item/reagent_containers/glass/bottle/saline = 5, + /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/ether = 4, /obj/item/reagent_containers/glass/bottle/atropine = 3, + /obj/item/reagent_containers/glass/bottle/oculine = 2, /obj/item/reagent_containers/glass/bottle/toxin = 4, /obj/item/reagent_containers/syringe/antiviral = 6, + /obj/item/reagent_containers/syringe/insulin = 6, /obj/item/reagent_containers/syringe/calomel = 10, /obj/item/reagent_containers/hypospray/autoinjector = 5, /obj/item/reagent_containers/food/pill/salbutamol = 10, + /obj/item/reagent_containers/food/pill/mannitol = 10, /obj/item/reagent_containers/food/pill/mutadone = 5, /obj/item/stack/medical/bruise_pack/advanced = 4, /obj/item/stack/medical/ointment/advanced = 4, /obj/item/stack/medical/bruise_pack = 4, + /obj/item/stack/medical/splint = 4, /obj/item/reagent_containers/glass/beaker = 4, /obj/item/reagent_containers/dropper = 4, /obj/item/healthanalyzer = 4, + /obj/item/healthupgrade = 4, /obj/item/reagent_containers/hypospray/safety = 2, /obj/item/sensor_device = 2, /obj/item/pinpointer/crew = 2) + contraband = list(/obj/item/reagent_containers/glass/bottle/sulfonal = 1, /obj/item/reagent_containers/glass/bottle/pancuronium = 1) armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0) //This one's from bay12 /obj/machinery/vending/plasmaresearch name = "\improper Toximate 3000" desc = "All the fine parts you need in one vending machine!" - products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, - /obj/item/transfer_valve = 6,/obj/item/assembly/timer = 6,/obj/item/assembly/signaler = 6, - /obj/item/assembly/prox_sensor = 6,/obj/item/assembly/igniter = 6) - contraband = list(/obj/item/assembly/health = 3) + products = list(/obj/item/assembly/prox_sensor = 8, /obj/item/assembly/igniter = 8, /obj/item/assembly/signaler = 8, + /obj/item/wirecutters = 1, /obj/item/assembly/timer = 8) + contraband = list(/obj/item/flashlight = 5, /obj/item/assembly/voice = 3, /obj/item/assembly/health = 3, /obj/item/assembly/infra = 3) /obj/machinery/vending/wallmed1 name = "\improper NanoMed" @@ -1041,7 +1067,7 @@ icon_deny = "wallmed-deny" req_access_txt = "5" density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/reagent_containers/hypospray/autoinjector = 4,/obj/item/healthanalyzer = 1) + products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1) contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4,/obj/item/reagent_containers/syringe/antiviral = 4,/obj/item/reagent_containers/food/pill/tox = 1) armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0) @@ -1393,7 +1419,7 @@ /obj/item/clothing/glasses/regular=2,/obj/item/clothing/glasses/sunglasses/fake=2,/obj/item/clothing/head/sombrero=1,/obj/item/clothing/suit/poncho=1, /obj/item/clothing/suit/ianshirt=1,/obj/item/clothing/shoes/laceup=2,/obj/item/clothing/shoes/black=4, /obj/item/clothing/shoes/sandal=1, /obj/item/clothing/gloves/fingerless=2, - /obj/item/storage/belt/fannypack=1, /obj/item/storage/belt/fannypack/blue=1, /obj/item/storage/belt/fannypack/red=1) + /obj/item/storage/belt/fannypack=1, /obj/item/storage/belt/fannypack/blue=1, /obj/item/storage/belt/fannypack/red=1, /obj/item/clothing/suit/mantle = 2, /obj/item/clothing/suit/mantle/old = 1, /obj/item/clothing/suit/mantle/regal = 2) contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/storage/belt/fannypack/black=1) premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/under/pants/mustangjeans=1) refill_canister = /obj/item/vending_refill/clothing diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index ab38ee3a0d0..5667a45ca85 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -20,9 +20,9 @@ update_pressure() /obj/mecha/working/ripley/Destroy() - while(damage_absorption.["brute"] < 0.6) + while(damage_absorption["brute"] < 0.6) new /obj/item/asteroid/goliath_hide(loc) - damage_absorption.["brute"] = damage_absorption.["brute"] + 0.1 //If a goliath-plated ripley gets killed, all the plates drop + damage_absorption["brute"] = damage_absorption["brute"] + 0.1 //If a goliath-plated ripley gets killed, all the plates drop for(var/atom/movable/A in cargo) A.forceMove(loc) step_rand(A) @@ -31,28 +31,28 @@ /obj/mecha/working/ripley/go_out() ..() - if(damage_absorption.["brute"] < 0.6 && damage_absorption.["brute"] > 0.3) + if(damage_absorption["brute"] < 0.6 && damage_absorption["brute"] > 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-open") - else if(damage_absorption.["brute"] == 0.3) + else if(damage_absorption["brute"] == 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full-open") /obj/mecha/working/ripley/moved_inside(var/mob/living/carbon/human/H as mob) ..() - if(damage_absorption.["brute"] < 0.6 && damage_absorption.["brute"] > 0.3) + if(damage_absorption["brute"] < 0.6 && damage_absorption["brute"] > 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g") - else if(damage_absorption.["brute"] == 0.3) + else if(damage_absorption["brute"] == 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full") /obj/mecha/working/ripley/mmi_moved_inside(var/obj/item/mmi/mmi_as_oc as obj,mob/user as mob) ..() - if(damage_absorption.["brute"] < 0.6 && damage_absorption.["brute"] > 0.3) + if(damage_absorption["brute"] < 0.6 && damage_absorption["brute"] > 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g") - else if(damage_absorption.["brute"] == 0.3) + else if(damage_absorption["brute"] == 0.3) overlays = null overlays += image("icon" = "mecha.dmi", "icon_state" = "ripley-g-full") diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 53072d7e82c..7cfd8bbec45 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -192,7 +192,7 @@ var/global/list/image/splatter_cache = list() icon = 'icons/effects/blood.dmi' icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") - noclear = TRUE + no_clear = TRUE var/fleshcolor = "#FFFFFF" /obj/effect/decal/cleanable/blood/gibs/update_icon() @@ -221,18 +221,11 @@ var/global/list/image/splatter_cache = list() /obj/effect/decal/cleanable/blood/gibs/core random_icon_states = list("gibmid1", "gibmid2", "gibmid3") - -/obj/effect/decal/cleanable/blood/gibs/Initialize() - . = ..() - reagents.add_reagent("liquidgibs", 5) + scoop_reagents = list("liquidgibs" = 5) /obj/effect/decal/cleanable/blood/gibs/cleangibs //most ironic name ever... - -/obj/effect/decal/cleanable/blood/gibs/cleangibs/Initialize() //no reagent! - . = ..() - reagents.remove_reagent("liquidgibs",5) - + scoop_reagents = null /obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions) set waitfor = 0 diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index d601283a703..7b5f255fcfb 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -15,10 +15,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "ash" anchored = TRUE - -/obj/effect/decal/cleanable/ash/Initialize() - . = ..() - reagents.add_reagent("ash", 10) + scoop_reagents = list("ash" = 10) /obj/effect/decal/cleanable/dirt name = "dirt" @@ -40,11 +37,8 @@ /obj/effect/decal/cleanable/dirt/blackpowder name = "black powder" mouse_opacity = TRUE - noscoop = TRUE - -/obj/effect/decal/cleanable/dirt/blackpowder/Initialize() - . = ..() - reagents.add_reagent("blackpowder", 40) // size 2 explosion when activated + no_scoop = TRUE + scoop_reagents = list("blackpowder" = 40) // size 2 explosion when activated /obj/effect/decal/cleanable/flour name = "flour" @@ -127,22 +121,15 @@ icon = 'icons/effects/blood.dmi' icon_state = "vomit_1" random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") - noclear = TRUE - -/obj/effect/decal/cleanable/vomit/Initialize() - . = ..() - reagents.add_reagent("vomit", 5) + no_clear = TRUE + scoop_reagents = list("vomit" = 5) /obj/effect/decal/cleanable/vomit/green name = "green vomit" desc = "It's all gummy. Ew." icon_state = "gvomit_1" random_icon_states = list("gvomit_1", "gvomit_2", "gvomit_3", "gvomit_4") - -/obj/effect/decal/cleanable/vomit/green/Initialize() - . = ..() - reagents.remove_reagent("vomit", 5) - reagents.add_reagent("green_vomit", 5) + scoop_reagents = list("green_vomit" = 5) /obj/effect/decal/cleanable/tomato_smudge name = "tomato smudge" @@ -189,10 +176,7 @@ icon = 'icons/effects/effects.dmi' icon_state = "flour" color = "#D5820B" - -/obj/effect/decal/cleanable/fungus/Initialize() - . = ..() - reagents.add_reagent("fungus", 10) + scoop_reagents = list("fungus" = 10) /obj/effect/decal/cleanable/confetti //PARTY TIME! name = "confetti" diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 52ec24df16c..461273bccdb 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,8 +1,6 @@ /obj/effect/decal/cleanable anchored = TRUE var/list/random_icon_states = list() - var/noscoop = FALSE //if it has this, don't let it be scooped up - var/noclear = FALSE //if it has this, don't delete it when its' scooped up /obj/effect/decal/cleanable/proc/can_bloodcrawl_in() return FALSE @@ -10,7 +8,6 @@ /obj/effect/decal/cleanable/New() if(random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) - create_reagents(100) if(smooth) queue_smooth(src) queue_smooth_neighbors(src) @@ -19,25 +16,4 @@ /obj/effect/decal/cleanable/Destroy() if(smooth) queue_smooth_neighbors(src) - return ..() - -/obj/effect/decal/cleanable/attackby(obj/item/W as obj, mob/user as mob,) - if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks)) - if(src.reagents && W.reagents && !noscoop) - if(!src.reagents.total_volume) - to_chat(user, "There isn't enough [src] to scoop up!") - return - if(W.reagents.total_volume >= W.reagents.maximum_volume) - to_chat(user, "[W] is full!") - return - to_chat(user, "You scoop the [src] into [W]!") - reagents.trans_to(W, reagents.total_volume) - if(!reagents.total_volume && !noclear) //scooped up all of it - qdel(src) - return - -/obj/effect/decal/cleanable/ex_act() - if(reagents) - for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() - ..() \ No newline at end of file + return ..() \ No newline at end of file diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 52ad55c48a4..64561630d06 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -54,3 +54,16 @@ /obj/effect/decal/straw/edge icon_state = "strawscatterededge" + +/obj/effect/decal/ants + name = "space ants" + desc = "A bunch of space ants." + icon = 'icons/goonstation/effects/effects.dmi' + icon_state = "spaceants" + scoop_reagents = list("ants" = 20) + +/obj/effect/decal/ants/Initialize(mapload) + . = ..() + var/scale = (rand(2, 10) / 10) + (rand(0, 5) / 100) + transform = matrix(transform, scale, scale, MATRIX_SCALE) + setDir(pick(NORTH, SOUTH, EAST, WEST)) \ No newline at end of file diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 6d746377ec7..59533b338a4 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -29,7 +29,7 @@ if(metal) var/turf/T = get_turf(src) - if(istype(T, /turf/space)) + if(istype(T, /turf/space) && !istype(T, /turf/space/transit)) T.ChangeTurf(/turf/simulated/floor/plating/metalfoam) var/turf/simulated/floor/plating/metalfoam/MF = get_turf(src) MF.metal = metal @@ -76,10 +76,10 @@ F = new /obj/effect/particle_effect/foam(T, metal) F.amount = amount if(!metal) - F.create_reagents(15) + F.create_reagents(25) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - F.reagents.add_reagent(R.id, min(R.volume, 3), R.data, reagents.chem_temp) + F.reagents.add_reagent(R.id, min(R.volume, 5), R.data, reagents.chem_temp) F.color = mix_color_from_reagents(reagents.reagent_list) // foam disolves when heated @@ -149,14 +149,14 @@ F.amount = amount if(!metal) // don't carry other chemicals if a metal foam - F.create_reagents(15) + F.create_reagents(25) if(carried_reagents) for(var/id in carried_reagents) if(banned_reagents.Find("[id]")) continue var/datum/reagent/reagent_volume = carried_reagents[id] - F.reagents.add_reagent(id, min(reagent_volume, 3), null, temperature) + F.reagents.add_reagent(id, min(reagent_volume, 5), null, temperature) F.color = mix_color_from_reagents(F.reagents.reagent_list) else F.reagents.add_reagent("cleaner", 1) diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 21b9759df62..07c7137d719 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -13,4 +13,38 @@ return /obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) - return FALSE \ No newline at end of file + return FALSE + +/obj/effect/decal + var/no_scoop = FALSE //if it has this, don't let it be scooped up + var/no_clear = FALSE //if it has this, don't delete it when its' scooped up + var/list/scoop_reagents = null + +/obj/effect/decal/Initialize(mapload) + . = ..() + if(scoop_reagents) + create_reagents(100) + reagents.add_reagent_list(scoop_reagents) + +/obj/effect/decal/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks)) + scoop(I, user) + +/obj/effect/decal/proc/scoop(obj/item/I, mob/user) + if(reagents && I.reagents && !no_scoop) + if(!reagents.total_volume) + to_chat(user, "There isn't enough [src] to scoop up!") + return + if(I.reagents.total_volume >= I.reagents.maximum_volume) + to_chat(user, "[I] is full!") + return + to_chat(user, "You scoop [src] into [I]!") + reagents.trans_to(I, reagents.total_volume) + if(!reagents.total_volume && !no_clear) //scooped up all of it + qdel(src) + +/obj/effect/decal/ex_act() + if(reagents) + for(var/datum/reagent/R in reagents.reagent_list) + R.on_ex_act() + ..() \ No newline at end of file diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm index 18392256fb8..510e5b90380 100644 --- a/code/game/objects/effects/spawners/random_spawners.dm +++ b/code/game/objects/effects/spawners/random_spawners.dm @@ -279,7 +279,7 @@ /obj/item/clothing/glasses/thermal = 1, /obj/item/chameleon = 1, /obj/item/reagent_containers/hypospray/autoinjector/stimulants = 1, - /obj/item/storage/box/syndie_kit/atmosgasgrenades = 1, + /obj/item/storage/box/syndie_kit/atmosn2ogrenades = 1, /obj/item/grenade/plastic/x4 = 1) diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index 1e026e90e02..cec5b6e1fc8 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -5,8 +5,8 @@ epicenter = get_turf(epicenter.loc) if(log) - message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])": ] [ADMIN_COORDJMP(epicenter)]") - log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [COORD(epicenter)]") + message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])": ""] [ADMIN_COORDJMP(epicenter)]") + log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)]") if(heavy_range > 1) new/obj/effect/temp_visual/emp/pulse(epicenter) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 9c457e43b6a..f21bbb69c02 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -25,8 +25,8 @@ var/list/cached_exp_block = list() if(adminlog) - message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [ADMIN_COORDJMP(epicenter)] ") - log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ] [COORD(epicenter)] ") + message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [ADMIN_COORDJMP(epicenter)] ") + log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)] ") // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. // Stereo users will also hear the direction of the explosion! diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3d8548ad11c..77b263fb8f2 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -16,6 +16,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d var/inhand_y_dimension = 32 can_be_hit = FALSE + suicidal_hands = TRUE var/r_speed = 1.0 var/health = null @@ -145,16 +146,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d /obj/item/blob_act() qdel(src) -//user: The mob that is suiciding -//damagetype: The type of damage the item will inflict on the user -//BRUTELOSS = 1 -//FIRELOSS = 2 -//TOXLOSS = 4 -//OXYLOSS = 8 -//Output a creative message and then return the damagetype done -/obj/item/proc/suicide_act(mob/user) - return - /obj/item/verb/move_to_top() set name = "Move To Top" set category = null @@ -258,7 +249,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d add_fingerprint(user) if(pickup(user)) // Pickup succeeded user.put_in_active_hand(src) - + return 1 /obj/item/attack_alien(mob/user as mob) @@ -587,11 +578,4 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d return TRUE /obj/item/attack_hulk(mob/living/carbon/human/user) - return FALSE - -/obj/item/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user) //handles block for CQC - if(target.check_block()) - target.visible_message("[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!", - "You block the attack!") - user.Stun(2) - return TRUE + return FALSE \ No newline at end of file diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index b4dd66e3be5..926da3d28cb 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -23,7 +23,7 @@ /obj/item/toy/crayon/suicide_act(mob/user) user.visible_message("[user] is jamming the [name] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS|OXYLOSS) + return BRUTELOSS|OXYLOSS /obj/item/toy/crayon/New() ..() diff --git a/code/game/objects/items/devices/handheld_defib.dm b/code/game/objects/items/devices/handheld_defib.dm new file mode 100644 index 00000000000..199aaf43737 --- /dev/null +++ b/code/game/objects/items/devices/handheld_defib.dm @@ -0,0 +1,91 @@ +/obj/item/handheld_defibrillator + name = "handheld defibrillator" + desc = "Used to restart stopped hearts." + icon = 'icons/goonstation/objects/objects.dmi' + lefthand_file = 'icons/goonstation/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/goonstation/mob/inhands/items_righthand.dmi' + icon_state = "defib-on" + item_state = "defib" + + var/icon_base = "defib" + var/cooldown = FALSE + var/charge_time = 100 + var/emagged = FALSE + +/obj/item/handheld_defibrillator/emag_act(mob/user) + if(!emagged) + emagged = TRUE + desc += " The screen only shows the word KILL flashing over and over." + if(user) + to_chat(user, "you short out the safeties on [src]") + else + emagged = FALSE + desc = "Used to restart stopped hearts." + if(user) + to_chat(user, "You restore the safeties on [src]") + +/obj/item/handheld_defibrillator/emp_act(severity) + if(emagged) + emagged = FALSE + desc = "Used to restart stopped hearts." + visible_message("[src] beeps: Safety protocols enabled!") + playsound(get_turf(src), 'sound/machines/defib_saftyon.ogg', 50, 0) + else + emagged = TRUE + desc += " The screen only shows the word KILL flashing over and over." + visible_message("[src] beeps: Safety protocols disabled!") + playsound(get_turf(src), 'sound/machines/defib_saftyoff.ogg', 50, 0) + +/obj/item/handheld_defibrillator/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + if(cooldown) + to_chat(user, "[src] is still charging!") + return + + if(emagged || (H.health <= HEALTH_THRESHOLD_CRIT) || (H.undergoing_cardiac_arrest())) + user.visible_message("[user] shocks [H] with [src].", "You shock [H] with [src].") + add_attack_logs(user, H, "defibrillated with [src]") + playsound(user.loc, "sound/weapons/Egloves.ogg", 75, 1) + + if(H.stat == DEAD) + to_chat(user, "[H] doesn't respond at all!") + else + H.set_heartattack(FALSE) + var/total_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + if(H.health <= HEALTH_THRESHOLD_CRIT) + if(total_damage >= 90) + to_chat(user, "[H] looks horribly injured. Resuscitation alone may not help revive them.") + if(prob(66)) + to_chat(user, "[H] inhales deeply!") + H.adjustOxyLoss(-50) + else + to_chat(user, "[H] doesn't respond!") + + H.AdjustParalysis(3) + H.AdjustStunned(5) + H.AdjustWeakened(5) + H.AdjustStuttering(10) + to_chat(H, "You feel a powerful jolt!") + H.shock_internal_organs(100) + + if(emagged && prob(10)) + to_chat(user, "[src]'s on board scanner indicates that the target is undergoing a cardiac arrest!") + H.set_heartattack(TRUE) + + cooldown = TRUE + icon_state = "[icon_base]-shock" + addtimer(CALLBACK(src, .proc/short_charge), 10) + addtimer(CALLBACK(src, .proc/recharge), charge_time) + + else + to_chat(user, "[src]'s on board medical scanner indicates that no shock is required.") + +/obj/item/handheld_defibrillator/proc/short_charge() + icon_state = "[icon_base]-off" + +/obj/item/handheld_defibrillator/proc/recharge() + cooldown = FALSE + icon_state = "[icon_base]-on" + playsound(loc, "sound/weapons/flash.ogg", 75, 1) \ No newline at end of file diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index 840d5e64395..6d3a1c2b49d 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -19,7 +19,7 @@ /obj/item/instrument/suicide_act(mob/user) user.visible_message("[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/instrument/Initialize(mapload) song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index b98e6d9acfc..610c257b03f 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -315,7 +315,7 @@ if(keyslot1 || keyslot2) for(var/ch_name in channels) - radio_controller.remove_object(src, radiochannels[ch_name]) + SSradio.remove_object(src, SSradio.radiochannels[ch_name]) secure_radio_connections[ch_name] = null if(keyslot1) @@ -392,11 +392,11 @@ for(var/ch_name in channels) - if(!radio_controller) + if(!SSradio) name = "broken radio headset" return - secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT) + secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT) if(setDescription) setupRadioDescription() diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 287c7b44c30..62057880b9b 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -128,7 +128,7 @@ // TODO: Integrate radio with the space manager if(isnull(position) || !(position.z in level)) return -1 - if(freq in ANTAG_FREQS) + if(freq in SSradio.ANTAG_FREQS) if(!(syndiekey)) return -1//Prevents broadcast of messages over devices lacking the encryption diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index e01b1a2a61a..83a8c9304a1 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -59,9 +59,9 @@ var/global/list/default_medbay_channels = list( /obj/item/radio/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT) /obj/item/radio/New() @@ -73,10 +73,10 @@ var/global/list/default_medbay_channels = list( /obj/item/radio/Destroy() QDEL_NULL(wires) - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) for(var/ch_name in channels) - radio_controller.remove_object(src, radiochannels[ch_name]) + SSradio.remove_object(src, SSradio.radiochannels[ch_name]) radio_connection = null GLOB.global_radios -= src follow_target = null @@ -90,7 +90,7 @@ var/global/list/default_medbay_channels = list( set_frequency(frequency) for(var/ch_name in channels) - secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT) + secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT) /obj/item/radio/attack_ghost(mob/user) return interact(user) @@ -147,7 +147,7 @@ var/global/list/default_medbay_channels = list( var/chan_stat = channels[ch_name] var/listening = !!(chan_stat & FREQ_LISTENING) != 0 - dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = frequency_span_class(radiochannels[ch_name])))) + dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = SSradio.frequency_span_class(SSradio.radiochannels[ch_name])))) return dat @@ -155,7 +155,7 @@ var/global/list/default_medbay_channels = list( var/dat[0] for(var/internal_chan in internal_channels) if(has_channel_access(user, internal_chan)) - dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = frequency_span_class(text2num(internal_chan))))) + dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = SSradio.frequency_span_class(text2num(internal_chan))))) return dat @@ -555,7 +555,7 @@ var/global/list/default_medbay_channels = list( var/turf/position = get_turf(src) if(!position || !(position.z in level)) return -1 - if(freq in ANTAG_FREQS) + if(freq in SSradio.ANTAG_FREQS) if(!(syndiekey))//Checks to see if it's allowed on that frequency, based on the encryption keys return -1 if(!freq) //recieved on main frequency @@ -699,7 +699,7 @@ var/global/list/default_medbay_channels = list( for(var/ch_name in channels) - radio_controller.remove_object(src, radiochannels[ch_name]) + SSradio.remove_object(src, SSradio.radiochannels[ch_name]) secure_radio_connections[ch_name] = null @@ -752,13 +752,13 @@ var/global/list/default_medbay_channels = list( for(var/ch_name in channels) - if(!radio_controller) - sleep(30) // Waiting for the radio_controller to be created. - if(!radio_controller) + if(!SSradio) + sleep(30) // Waiting for SSradio to be created. + if(!SSradio) name = "broken radio" return - secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT) + secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT) return @@ -829,14 +829,14 @@ var/global/list/default_medbay_channels = list( return data /obj/item/radio/proc/config(op) - if(radio_controller) + if(SSradio) for(var/ch_name in channels) - radio_controller.remove_object(src, radiochannels[ch_name]) + SSradio.remove_object(src, SSradio.radiochannels[ch_name]) secure_radio_connections = new channels = op - if(radio_controller) + if(SSradio) for(var/ch_name in op) - secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT) + secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT) return /obj/item/radio/off diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 8ad7fae6d2d..4a20a52fa04 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -125,8 +125,8 @@ REAGENT SCANNER var/mode = 1; -/obj/item/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob) - if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) +/obj/item/healthanalyzer/attack(mob/living/M, mob/living/user) + if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) to_chat(user, text("You try to analyze the floor's vitals!")) for(var/mob/O in viewers(M, null)) O.show_message(text("[user] has analyzed the floor's vitals!"), 1) @@ -137,7 +137,7 @@ REAGENT SCANNER return user.visible_message("[user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.") - if(!istype(M,/mob/living/carbon/human) || M.isSynthetic()) + if(!ishuman(M) || M.isSynthetic()) //these sensors are designed for organic life user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) @@ -147,122 +147,132 @@ REAGENT SCANNER user.show_message("Subject's pulse: -- bpm.") return - var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss()))) - var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss() - var/TX = M.getToxLoss() > 50 ? "[M.getToxLoss()]" : M.getToxLoss() - var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss() - var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss() - if(M.status_flags & FAKEDEATH) + var/mob/living/carbon/human/H = M + var/fake_oxy = max(rand(1,40), H.getOxyLoss(), (300 - (H.getToxLoss() + H.getFireLoss() + H.getBruteLoss()))) + var/OX = H.getOxyLoss() > 50 ? "[H.getOxyLoss()]" : H.getOxyLoss() + var/TX = H.getToxLoss() > 50 ? "[H.getToxLoss()]" : H.getToxLoss() + var/BU = H.getFireLoss() > 50 ? "[H.getFireLoss()]" : H.getFireLoss() + var/BR = H.getBruteLoss() > 50 ? "[H.getBruteLoss()]" : H.getBruteLoss() + if(H.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy - user.show_message("Analyzing Results for [M]:\n\t Overall Status: dead") + user.show_message("Analyzing Results for [H]:\n\t Overall Status: dead") else - user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]") + user.show_message("Analyzing Results for [H]:\n\t Overall Status: [H.stat > 1 ? "dead" : "[H.health]% healthy"]") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\t Damage Specifics: [OX] - [TX] - [BU] - [BR]") - user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) - if(M.timeofdeath && (M.stat == DEAD || (M.status_flags & FAKEDEATH))) - user.show_message("Time of Death: [station_time_timestamp("hh:mm:ss", M.timeofdeath)]") - var/tdelta = round(world.time - M.timeofdeath) + user.show_message("Body Temperature: [H.bodytemperature-T0C]°C ([H.bodytemperature*1.8-459.67]°F)", 1) + if(H.timeofdeath && (H.stat == DEAD || (H.status_flags & FAKEDEATH))) + user.show_message("Time of Death: [station_time_timestamp("hh:mm:ss", H.timeofdeath)]") + var/tdelta = round(world.time - H.timeofdeath) if(tdelta < (DEFIB_TIME_LIMIT * 10)) user.show_message("Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!") - if(istype(M, /mob/living/carbon/human) && mode == 1) - var/mob/living/carbon/human/H = M + if(mode == 1) var/list/damaged = H.get_damaged_organs(1,1) user.show_message("Localized Damage, Brute/Burn:",1) if(length(damaged) > 0) for(var/obj/item/organ/external/org in damaged) user.show_message("\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]") - OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" - TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal" - BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K" - BR = M.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K" - if(M.status_flags & FAKEDEATH) + OX = H.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" + TX = H.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal" + BU = H.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K" + BR = H.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K" + if(H.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" user.show_message("[OX] | [TX] | [BU] | [BR]") - if(istype(M, /mob/living/carbon)) - if(upgraded) - chemscan(user, M) - for(var/thing in M.viruses) - var/datum/disease/D = thing - if(!(D.visibility_flags & HIDDEN_SCANNER)) - user.show_message("Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]") - if(M.getStaminaLoss()) + + if(upgraded) + chemscan(user, H) + for(var/thing in H.viruses) + var/datum/disease/D = thing + if(!(D.visibility_flags & HIDDEN_SCANNER)) + user.show_message("Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]") + if(H.undergoing_cardiac_arrest()) + var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart) + if(heart && !(heart.status & ORGAN_DEAD)) + user.show_message("Warning: Medical Emergency detected\nName: Cardiac Arrest.\nType: The patient's heart has stopped.\nStage: 1/1.\nPossible Cure: Electric Shock") + else if(heart && (heart.status & ORGAN_DEAD)) + user.show_message("Subject's heart is necrotic.") + else if(!heart) + user.show_message("Subject has no heart.") + + if(H.getStaminaLoss()) user.show_message("Subject appears to be suffering from fatigue.") - if(M.getCloneLoss()) - user.show_message("Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") - if(M.has_brain_worms()) + if(H.getCloneLoss()) + user.show_message("Subject appears to have [H.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") + if(H.has_brain_worms()) user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.") - else if(M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain)) - user.show_message("Subject is brain dead.") - else if(M.getBrainLoss() >= 60) - user.show_message("Severe brain damage detected. Subject likely to have mental retardation.") - else if(M.getBrainLoss() >= 10) - user.show_message("Significant brain damage detected. Subject may have had a concussion.") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - for(var/name in H.bodyparts_by_name) - var/obj/item/organ/external/e = H.bodyparts_by_name[name] - if(!e) - continue - var/limb = e.name - if(e.status & ORGAN_BROKEN) - if((e.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED)) - user.show_message("Unsecured fracture in subject [limb]. Splinting recommended for transport.") - if(e.has_infected_wound()) - user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.") - for(var/name in H.bodyparts_by_name) - var/obj/item/organ/external/e = H.bodyparts_by_name[name] - if(!e) - continue - if(e.status & ORGAN_BROKEN) - user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1) - break - for(var/obj/item/organ/external/e in H.bodyparts) - if(e.internal_bleeding) - user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) - break - var/blood_id = H.get_blood_id() - if(blood_id) - if(H.bleed_rate) - user.show_message("Subject is bleeding!") - var/blood_percent = round((H.blood_volume / BLOOD_VOLUME_NORMAL)*100) - var/blood_type = H.b_type - if(blood_id != "blood")//special blood substance - var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] - if(R) - blood_type = R.name - else - blood_type = blood_id - if(H.blood_volume <= BLOOD_VOLUME_SAFE && H.blood_volume > BLOOD_VOLUME_OKAY) - user.show_message("LOW blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") - else if(H.blood_volume <= BLOOD_VOLUME_OKAY) - user.show_message("CRITICAL blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") + if(H.get_int_organ(/obj/item/organ/internal/brain)) + if(H.getBrainLoss() >= 100) + user.show_message("Subject is brain dead.") + else if(H.getBrainLoss() >= 60) + user.show_message("Severe brain damage detected. Subject likely to have mental retardation.") + else if(H.getBrainLoss() >= 10) + user.show_message("Significant brain damage detected. Subject may have had a concussion.") + else + user.show_message("Subject has no brain.") + + for(var/name in H.bodyparts_by_name) + var/obj/item/organ/external/e = H.bodyparts_by_name[name] + if(!e) + continue + var/limb = e.name + if(e.status & ORGAN_BROKEN) + if((e.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED)) + user.show_message("Unsecured fracture in subject [limb]. Splinting recommended for transport.") + if(e.has_infected_wound()) + user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.") + + for(var/name in H.bodyparts_by_name) + var/obj/item/organ/external/e = H.bodyparts_by_name[name] + if(!e) + continue + if(e.status & ORGAN_BROKEN) + user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1) + break + for(var/obj/item/organ/external/e in H.bodyparts) + if(e.internal_bleeding) + user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) + break + var/blood_id = H.get_blood_id() + if(blood_id) + if(H.bleed_rate) + user.show_message("Subject is bleeding!") + var/blood_percent = round((H.blood_volume / BLOOD_VOLUME_NORMAL)*100) + var/blood_type = H.b_type + if(blood_id != "blood")//special blood substance + var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] + if(R) + blood_type = R.name else - user.show_message("Blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") - - if(H.undergoing_cardiac_arrest() && H.stat != DEAD) - user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.") - user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") - var/implant_detect - for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) - if(CI.is_robotic()) - implant_detect += "[H.name] is modified with a [CI.name].
" - if(implant_detect) - user.show_message("Detected cybernetic modifications:") - user.show_message("[implant_detect]") - if(H.gene_stability < 40) - user.show_message("Subject's genes are quickly breaking down!") - else if(H.gene_stability < 70) - user.show_message("Subject's genes are showing signs of spontaneous breakdown.") - else if(H.gene_stability < 85) - user.show_message("Subject's genes are showing minor signs of instability.") + blood_type = blood_id + if(H.blood_volume <= BLOOD_VOLUME_SAFE && H.blood_volume > BLOOD_VOLUME_OKAY) + user.show_message("LOW blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") + else if(H.blood_volume <= BLOOD_VOLUME_OKAY) + user.show_message("CRITICAL blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") else - user.show_message("Subject's genes are stable.") - src.add_fingerprint(user) - return + user.show_message("Blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") + + user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") + var/implant_detect + for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) + if(CI.is_robotic()) + implant_detect += "[H.name] is modified with a [CI.name].
" + if(implant_detect) + user.show_message("Detected cybernetic modifications:") + user.show_message("[implant_detect]") + if(H.gene_stability < 40) + user.show_message("Subject's genes are quickly breaking down!") + else if(H.gene_stability < 70) + user.show_message("Subject's genes are showing signs of spontaneous breakdown.") + else if(H.gene_stability < 85) + user.show_message("Subject's genes are showing minor signs of instability.") + else + user.show_message("Subject's genes are stable.") + add_fingerprint(user) + /obj/item/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" @@ -275,19 +285,21 @@ REAGENT SCANNER if(0) to_chat(usr, "The scanner no longer shows limb damage.") -/obj/item/healthanalyzer/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/healthupgrade)) +/obj/item/healthanalyzer/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/healthupgrade)) if(upgraded) to_chat(user, "You have already installed an upgraded in the [src].") else to_chat(user, "You install the upgrade in the [src].") overlays += "advanced" - playsound(loc, W.usesound, 50, 1) - upgraded = 1 - qdel(W) + playsound(loc, I.usesound, 50, 1) + upgraded = TRUE + qdel(I) + return + return ..() /obj/item/healthanalyzer/advanced - upgraded = 1 + upgraded = TRUE /obj/item/healthanalyzer/advanced/New() overlays += "advanced" @@ -834,4 +846,4 @@ REAGENT SCANNER if(target.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" - return dat + return dat \ No newline at end of file diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index 247b5fb1a0d..e5bbeef7686 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -23,7 +23,6 @@ var/list/world_uplinks = list() var/used_TC = 0 var/job = null - var/show_descriptions = 0 var/temp_category var/uplink_type = "traitor" @@ -72,7 +71,10 @@ var/list/world_uplinks = list() if(I.job && I.job.len) if(!(I.job.Find(job))) continue - dat += "[I.name] ([I.cost])
" + dat += "[I.name] ([I.cost])" + if(I.hijack_only) + dat += " (HIJACK ONLY)" + dat += "
" category_items++ dat += "Random Item (??)
" @@ -95,7 +97,7 @@ var/list/world_uplinks = list() if(I.job && I.job.len) if(!(I.job.Find(job))) continue - nano[nano.len]["items"] += list(list("Name" = sanitize(I.name), "Description" = sanitize(I.description()),"Cost" = I.cost, "obj_path" = I.reference)) + nano[nano.len]["items"] += list(list("Name" = sanitize(I.name), "Description" = sanitize(I.description()),"Cost" = I.cost, "hijack_only" = I.hijack_only, "obj_path" = I.reference)) reference[I.reference] = I var/datum/nano_item_lists/result = new @@ -231,7 +233,6 @@ var/list/world_uplinks = list() data["welcome"] = welcome data["crystals"] = uses data["menu"] = nanoui_menu - data["descriptions"] = show_descriptions if(!nanoui_items) generate_items(user) data["nano_items"] = nanoui_items @@ -266,12 +267,6 @@ var/list/world_uplinks = list() if(href_list["menu"]) nanoui_menu = text2num(href_list["menu"]) update_nano_data(href_list["id"]) - if(href_list["menu"]) - nanoui_menu = text2num(href_list["menu"]) - update_nano_data(href_list["id"]) - if(href_list["descriptions"]) - show_descriptions = !show_descriptions - update_nano_data() if(href_list["category"]) temp_category = href_list["category"] update_nano_data() diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm index 3ba466b7eec..121b0214b5a 100644 --- a/code/game/objects/items/flag.dm +++ b/code/game/objects/items/flag.dm @@ -64,11 +64,6 @@ desc = "The banner of the glorious revolutionary forces fighting the oppressors on Clown Planet." icon_state = "mimeflag" -/obj/item/flag/pony - name = "Equestria flag" - desc = "The flag of the independent, sovereign nation of Equestria, whatever the fuck that is." - icon_state = "ponyflag" - /obj/item/flag/ian name = "Ian flag" desc = "The banner of Ian, because SQUEEEEE." @@ -170,8 +165,8 @@ icon_state = "atmosflag" /obj/item/flag/command - name = "Commandzikstan flag" - desc = "The flag of the independent, sovereign nation of Commandzikstan." + name = "Command flag" + desc = "The flag of the independent, sovereign nation of Command." icon_state = "ntflag" //Antags diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index d4d5f4aa213..19864e0ba18 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -231,7 +231,7 @@ /obj/item/toy/katana/suicide_act(mob/user) var/dmsg = pick("[user] tries to stab \the [src] into [user.p_their()] abdomen, but it shatters! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.","[user] tries to stab \the [src] into [user.p_their()] abdomen, but \the [src] bends and breaks in half! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.","[user] tries to slice [user.p_their()] own throat, but the plastic blade has no sharpness, causing [user.p_them()] to lose [user.p_their()] balance, slip over, and break [user.p_their()] neck with a loud snap!") user.visible_message("[dmsg] It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS) + return BRUTELOSS /* @@ -1372,54 +1372,84 @@ obj/item/toy/cards/deck/syndicate/black force = 5 origin_tech = "combat=1" attack_verb = list("struck", "hit", "bashed") - var/bullet_position = 1 + var/bullets_left = 0 + var/max_shots = 6 /obj/item/toy/russian_revolver/suicide_act(mob/user) user.visible_message("[user] quickly loads six bullets into [src]'s cylinder and points it at [user.p_their()] head before pulling the trigger! It looks like [user.p_theyre()] trying to commit suicide.") playsound(loc, 'sound/weapons/gunshots/gunshot_strong.ogg', 50, 1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/toy/russian_revolver/New() - spin_cylinder() ..() - + spin_cylinder() /obj/item/toy/russian_revolver/attack_self(mob/user) - if(!bullet_position) - user.visible_message("[user] loads a bullet into [src]'s cylinder.") - bullet_position = 1 - else + if(!bullets_left) + user.visible_message("[user] loads a bullet into [src]'s cylinder before spinning it.") spin_cylinder() - user.visible_message("[user] spins the cylinder on [src]!") - -/obj/item/toy/russian_revolver/attack(mob/living/carbon/human/M, mob/living/carbon/human/user) - if(M != user) //can't use this on other people - return ..() - if(!bullet_position) - to_chat(user, "[src] is empty.") - return - if(!(user.has_organ("head"))) //For sanity - to_chat(user, "Playing this game without a head would be classed as cheating.") - return - user.visible_message("[user] points [src] at [user.p_their()] head, ready to pull the trigger!") - if(do_after(user, 30, target = user)) - if(bullet_position > 1) - user.visible_message("*click*") - playsound(src, 'sound/weapons/empty.ogg', 100, 1) - bullet_position-- - return - else - bullet_position = null - playsound(src, 'sound/weapons/gunshots/gunshot_strong.ogg', 50, 1) - user.visible_message("[src] goes off!") - user.apply_damage(200, BRUTE, "head", sharp = 1, used_weapon = "Self-inflicted gunshot wound to the head.") - user.death() else - user.visible_message("[user] lowers [src] from [user.p_their()] head.") + user.visible_message("[user] spins the cylinder on [src]!") + spin_cylinder() + +/obj/item/toy/russian_revolver/attack(mob/M, mob/living/user) + return + +/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, flag, params) + if(flag) + if(target in user.contents) + return + if(!ismob(target)) + return + shoot_gun(user) /obj/item/toy/russian_revolver/proc/spin_cylinder() - bullet_position = rand(1,6) + bullets_left = rand(1, max_shots) +/obj/item/toy/russian_revolver/proc/post_shot(mob/user) + return + +/obj/item/toy/russian_revolver/proc/shoot_gun(mob/living/carbon/human/user) + if(bullets_left > 1) + bullets_left-- + user.visible_message("*click*") + playsound(src, 'sound/weapons/empty.ogg', 100, 1) + return FALSE + if(bullets_left == 1) + bullets_left = 0 + var/zone = "head" + if(!(user.has_organ(zone))) // If they somehow don't have a head. + zone = "chest" + playsound(src, 'sound/weapons/gunshots/gunshot_strong.ogg', 50, 1) + user.visible_message("[src] goes off!") + post_shot(user) + user.apply_damage(300, BRUTE, zone, sharp = TRUE, used_weapon = "Self-inflicted gunshot wound to the [zone].") + user.bleed(BLOOD_VOLUME_NORMAL) + user.death() // Just in case + return TRUE + else + to_chat(user, "[src] needs to be reloaded.") + return FALSE + +/obj/item/toy/russian_revolver/trick_revolver + name = "\improper .357 revolver" + desc = "A suspicious revolver. Uses .357 ammo." + icon_state = "revolver" + max_shots = 1 + var/fake_bullets = 0 + +/obj/item/toy/russian_revolver/trick_revolver/New() + ..() + fake_bullets = rand(2, 7) + +/obj/item/toy/russian_revolver/trick_revolver/examine(mob/user) //Sneaky sneaky + ..() + to_chat(user, "Has [fake_bullets] round\s remaining.") + to_chat(user, "[fake_bullets] of those are live rounds.") + +/obj/item/toy/russian_revolver/trick_revolver/post_shot(user) + to_chat(user, "[src] did look pretty dodgey!") + SEND_SOUND(user, 'sound/misc/sadtrombone.ogg') //HONK /* * Rubber Chainsaw */ diff --git a/code/game/objects/items/weapons/courtroom.dm b/code/game/objects/items/weapons/courtroom.dm index d25b6f54d29..72bb3fceb11 100644 --- a/code/game/objects/items/weapons/courtroom.dm +++ b/code/game/objects/items/weapons/courtroom.dm @@ -16,7 +16,7 @@ /obj/item/gavelhammer/suicide_act(mob/user) user.visible_message("[user] has sentenced [user.p_them()]self to death with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/gavelblock name = "gavel block" diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 758e30947b0..ea70e29ef83 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -283,7 +283,7 @@ user.visible_message("[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide.") defib.deductcharge(revivecost) playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - return (OXYLOSS) + return OXYLOSS /obj/item/twohanded/shockpaddles/dropped(mob/user as mob) if(user) @@ -313,7 +313,7 @@ /obj/item/twohanded/shockpaddles/attack(mob/M, mob/user) var/tobehealed - var/threshold = -config.health_threshold_dead + var/threshold = -HEALTH_THRESHOLD_DEAD var/mob/living/carbon/human/H = M if(busy) @@ -472,7 +472,7 @@ /obj/item/borg_defib/attack(mob/M, mob/user) var/tobehealed - var/threshold = -config.health_threshold_dead + var/threshold = -HEALTH_THRESHOLD_DEAD var/mob/living/carbon/human/H = M if(busy) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index be490d29065..d17287b01a6 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -116,6 +116,7 @@ sleep(10) prime() user.gib() + return OBLITERATION /obj/item/grenade/plastic/update_icon() if(nadeassembly) diff --git a/code/game/objects/items/weapons/garrote.dm b/code/game/objects/items/weapons/garrote.dm index 03125313656..dd65df1ea3f 100644 --- a/code/game/objects/items/weapons/garrote.dm +++ b/code/game/objects/items/weapons/garrote.dm @@ -168,4 +168,4 @@ /obj/item/twohanded/garrote/suicide_act(mob/user) user.visible_message("[user] is wrapping the [src] around [user.p_their()] neck and pulling the handles! It looks like [user.p_theyre()] trying to commit suicide.") playsound(src.loc, 'sound/weapons/cablecuff.ogg', 15, 1, -1) - return (OXYLOSS) + return OXYLOSS diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 7da978a35d1..31bc6bcf556 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -446,6 +446,23 @@ update_icon() +/obj/item/grenade/chem_grenade/firefighting + payload_name = "fire fighting grenade" + desc = "Can help to put out dangerous fires from a distance." + stage = READY + +/obj/item/grenade/chem_grenade/firefighting/New() + ..() + var/obj/item/reagent_containers/glass/beaker/B1 = new(src) + var/obj/item/reagent_containers/glass/beaker/B2 = new(src) + + B1.reagents.add_reagent("firefighting_foam", 30) + B2.reagents.add_reagent("firefighting_foam", 30) + + beakers += B1 + beakers += B2 + update_icon() + /obj/item/grenade/chem_grenade/incendiary payload_name = "incendiary" desc = "Used for clearing rooms of living things." diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 2e7bacd4426..b0f89c6215b 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -6,6 +6,7 @@ light_power = 10 light_color = LIGHT_COLOR_WHITE var/light_time = 2 + var/range = 7 /obj/item/grenade/flashbang/prime() update_mob() @@ -15,60 +16,65 @@ set_light(7) - for(var/mob/living/M in hearers(7, flashbang_turf)) - bang(get_turf(M), M) + do_sparks(rand(5, 9), FALSE, src) + playsound(flashbang_turf, 'sound/effects/bang.ogg', 25, 1) + bang(flashbang_turf, src, range) - for(var/obj/structure/blob/B in hear(8,flashbang_turf)) //Blob damage here - var/damage = round(30/(get_dist(B,get_turf(src))+1)) + for(var/obj/structure/blob/B in hear(8, flashbang_turf)) //Blob damage here + var/damage = round(30 / (get_dist(B, get_turf(src)) + 1)) B.health -= damage B.update_icon() spawn(light_time) qdel(src) -/obj/item/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/M) - M.show_message("BANG", 2) - playsound(loc, 'sound/effects/bang.ogg', 25, 1) +/proc/bang(turf/T, atom/A, range = 7, flash = TRUE, bang = TRUE) + for(var/mob/living/M in hearers(range, T)) + if(M.stat == DEAD) + continue + M.show_message("BANG", 2) -//Checking for protections - var/ear_safety = M.check_ear_prot() - var/distance = max(1,get_dist(src,T)) + //Checking for protections + var/ear_safety = M.check_ear_prot() + var/distance = max(1, get_dist(get_turf(A), get_turf(M))) -//Flash - if(M.weakeyes) - M.visible_message("[M] screams and collapses!") - to_chat(M, "AAAAGH!") - M.Weaken(15) //hella stunned - M.Stun(15) - if(ishuman(M)) - M.emote("scream") - var/mob/living/carbon/human/H = M - var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) - if(E) - E.receive_damage(8, 1) + //Flash + if(flash) + if(M.weakeyes) + M.visible_message("[M] screams and collapses!") + to_chat(M, "AAAAGH!") + M.Weaken(15) //hella stunned + M.Stun(15) + if(ishuman(M)) + M.emote("scream") + var/mob/living/carbon/human/H = M + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) + if(E) + E.receive_damage(8, 1) - if(M.flash_eyes(affect_silicon = 1)) - M.Stun(max(10/distance, 3)) - M.Weaken(max(10/distance, 3)) + if(M.flash_eyes(affect_silicon = TRUE)) + M.Stun(max(10 / distance, 3)) + M.Weaken(max(10 / distance, 3)) -//Bang - if(get_turf(M) == get_turf(src))//Holding on person or being exactly where lies is significantly more dangerous and voids protection - M.Stun(10) - M.Weaken(10) - if(!ear_safety) - M.Stun(max(10/distance, 3)) - M.Weaken(max(10/distance, 3)) - M.AdjustEarDamage(rand(0, 5), 15) - if(iscarbon(M)) - var/mob/living/carbon/C = M - var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears) - if(istype(ears)) - if(ears.ear_damage >= 15) - to_chat(M, "Your ears start to ring badly!") - if(prob(ears.ear_damage - 5)) - to_chat(M, "You can't hear anything!") - M.BecomeDeaf() - else - if(ears.ear_damage >= 5) - to_chat(M, "Your ears start to ring!") + //Bang + if(bang) + if(!distance || A.loc == M || A.loc == M.loc) //Holding on person or being exactly where lies is significantly more dangerous and voids protection + M.Stun(10) + M.Weaken(10) + if(!ear_safety) + M.Stun(max(10 / distance, 3)) + M.Weaken(max(10 / distance, 3)) + M.AdjustEarDamage(rand(0, 5), 15) + if(iscarbon(M)) + var/mob/living/carbon/C = M + var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears) + if(istype(ears)) + if(ears.ear_damage >= 15) + to_chat(M, "Your ears start to ring badly!") + if(prob(ears.ear_damage - 5)) + to_chat(M, "You can't hear anything!") + M.BecomeDeaf() + else + if(ears.ear_damage >= 5) + to_chat(M, "Your ears start to ring!") \ No newline at end of file diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 7c26e5c405e..6fa0c875333 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -26,11 +26,15 @@ if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy)) to_chat(user, "Uh... how do those things work?!") - apply_cuffs(user,user) - + apply_cuffs(user, user) + return + + cuff(C, user) + +/obj/item/restraints/handcuffs/proc/cuff(mob/living/carbon/C, mob/user, remove_src = TRUE) if(ishuman(C)) var/mob/living/carbon/human/H = C - if(!H.has_left_hand() || !H.has_right_hand()) + if(!(H.has_left_hand() || H.has_right_hand())) to_chat(user, "How do you suggest handcuffing someone with no hands?") return @@ -40,26 +44,31 @@ playsound(loc, cuffsound, 30, 1, -2) if(do_mob(user, C, 30)) - apply_cuffs(C,user) + apply_cuffs(C, user, remove_src) to_chat(user, "You handcuff [C].") if(istype(src, /obj/item/restraints/handcuffs/cable)) - feedback_add_details("handcuffs","C") + feedback_add_details("handcuffs", "C") else - feedback_add_details("handcuffs","H") + feedback_add_details("handcuffs", "H") add_attack_logs(user, C, "Handcuffed ([src])") else to_chat(user, "You fail to handcuff [C].") -/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user) +/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, remove_src = TRUE) if(!target.handcuffed) - user.drop_item() + if(remove_src) + user.drop_item() if(trashtype) target.handcuffed = new trashtype(target) - qdel(src) + if(remove_src) + qdel(src) else - loc = target - target.handcuffed = src + if(remove_src) + loc = target + target.handcuffed = src + else + target.handcuffed = new type(loc) target.update_handcuffed() return @@ -170,23 +179,7 @@ /obj/item/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user) if(isrobot(user)) - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(!(H.get_organ("l_hand") || H.get_organ("r_hand"))) - to_chat(user, "How do you suggest handcuffing someone with no hands?") - return - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) - C.visible_message("[user] is trying to put zipties on [C]!", \ - "[user] is trying to put zipties on [C]!") - if(do_mob(user, C, 30)) - if(!C.handcuffed) - C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C) - C.update_handcuffed() - to_chat(user, "You handcuff [C].") - add_attack_logs(user, C, "Handcuffed (ziptie-cuffed)") - else - to_chat(user, "You fail to handcuff [C].") + cuff(C, user, FALSE) /obj/item/restraints/handcuffs/cable/zipties/used desc = "A pair of broken zipties." diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index 73ff4e5064d..9e471583d3b 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -15,7 +15,7 @@ /obj/item/nullrod/suicide_act(mob/user) user.visible_message("[user] is killing [user.p_them()]self with \the [src.name]! It looks like [user.p_theyre()] trying to get closer to god!") - return (BRUTELOSS|FIRELOSS) + return BRUTELOSS|FIRELOSS /obj/item/nullrod/attack(mob/M, mob/living/carbon/user) ..() diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index a0810a0b96c..982959dd8f9 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -121,7 +121,7 @@ user.visible_message(pick("[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.", \ "[user] is slitting [user.p_their()] throat with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.", \ "[user] is slitting [user.p_their()] stomach open with the [name]! It looks like [user.p_theyre()] trying to commit seppuku.")) - return (BRUTELOSS) + return BRUTELOSS /obj/item/kitchen/knife/plastic name = "plastic knife" diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm index 3391687f20a..297966525f0 100644 --- a/code/game/objects/items/weapons/legcuffs.dm +++ b/code/game/objects/items/weapons/legcuffs.dm @@ -35,7 +35,7 @@ /obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user) user.visible_message("[user] is sticking [user.p_their()] head in the [name]! It looks like [user.p_theyre()] trying to commit suicide.") playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/restraints/legcuffs/beartrap/attack_self(mob/user) ..() diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 8ad283a77da..0d85245d58f 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -16,7 +16,7 @@ /obj/item/melee/energy/suicide_act(mob/user) user.visible_message(pick("[user] is slitting [user.p_their()] stomach open with the [name]! It looks like [user.p_theyre()] trying to commit seppuku.", \ "[user] is falling on the [name]! It looks like [user.p_theyre()] trying to commit suicide.")) - return (BRUTELOSS|FIRELOSS) + return BRUTELOSS|FIRELOSS /obj/item/melee/energy/attack_self(mob/living/carbon/user) if(user.disabilities & CLUMSY && prob(50)) @@ -81,7 +81,7 @@ /obj/item/melee/energy/axe/suicide_act(mob/user) user.visible_message("[user] swings the [name] towards [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS|FIRELOSS) + return BRUTELOSS|FIRELOSS /obj/item/melee/energy/sword name = "energy sword" diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index a19df11e790..9dd14046cb9 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -1,6 +1,13 @@ /obj/item/melee needs_permit = 1 +/obj/item/melee/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user) + if(target.check_block()) + target.visible_message("[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!", + "You block the attack!") + user.Stun(2) + return TRUE + /obj/item/melee/chainofcommand name = "chain of command" desc = "A tool used by great men to placate the frothing masses." @@ -17,8 +24,8 @@ /obj/item/melee/chainofcommand/suicide_act(mob/user) - to_chat(viewers(user), "[user] is strangling [user.p_them()]self with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") - return (OXYLOSS) + to_chat(viewers(user), "[user] is strangling [user.p_them()]self with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") + return OXYLOSS /obj/item/melee/rapier name = "captain's rapier" diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 8f6ffc96e1c..ccee6c18feb 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -47,7 +47,11 @@ var/A - A = input(user, "Area to jump to", "BOOYEA", A) in teleportlocs + A = input(user, "Area to jump to", "BOOYEA", A) as null|anything in teleportlocs + + if(!A) + return + var/area/thearea = teleportlocs[A] if(user.stat || user.restrained()) diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index 88de9de1b11..428bfcd8fab 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -18,7 +18,7 @@ /obj/item/shard/suicide_act(mob/user) to_chat(viewers(user), pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide.", "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide.")) - return (BRUTELOSS) + return BRUTELOSS /obj/item/shard/New() ..() diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm index 4293c0a6167..0d8613cce4a 100644 --- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm +++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm @@ -176,10 +176,6 @@ affected_mob.SetSleeping(0) affected_mob.SetSlowed(0) affected_mob.SetConfused(0) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/H = affected_mob - if(H.traumatic_shock < 100) - H.shock_stage = 0 stage = 1 switch(progenitor.hunger) if(10 to 60) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 8df4b17251d..e5ee3562228 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -315,7 +315,7 @@ /obj/item/storage/backpack/duffel/syndie name = "suspicious looking duffelbag" desc = "A large duffelbag for holding extra tactical supplies." - icon_state = "duffel-syndi" + icon_state = "duffel-syndie" item_state = "duffel-syndimed" origin_tech = "syndicate=1" silent = 1 @@ -333,21 +333,64 @@ icon_state = "duffel-syndiammo" item_state = "duffel-syndiammo" -/obj/item/storage/backpack/duffel/syndie/ammo/loaded +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun desc = "A large duffelbag, packed to the brim with Bulldog shotgun ammo." -/obj/item/storage/backpack/duffel/syndie/ammo/loaded/New() +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun/New() ..() - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) + for(var/i in 1 to 6) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/ammo_box/magazine/m12g/buckshot(src) new /obj/item/ammo_box/magazine/m12g/buckshot(src) - new /obj/item/ammo_box/magazine/m12g/stun(src) new /obj/item/ammo_box/magazine/m12g/dragon(src) +/obj/item/storage/backpack/duffel/syndie/ammo/smg + desc = "A large duffel bag, packed to the brim with C-20r magazines." + +/obj/item/storage/backpack/duffel/syndie/ammo/smg/New() + ..() + for(var/i in 1 to 10) + new /obj/item/ammo_box/magazine/smgm45(src) + +/obj/item/storage/backpack/duffel/syndie/c20rbundle + desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor." + +/obj/item/storage/backpack/duffel/syndie/c20rbundle/New() + ..() + new /obj/item/ammo_box/magazine/smgm45(src) + new /obj/item/ammo_box/magazine/smgm45(src) + new /obj/item/gun/projectile/automatic/c20r(src) + new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/backpack/duffel/syndie/bulldogbundle + desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses." + +/obj/item/storage/backpack/duffel/syndie/bulldogbundle/New() + ..() + new /obj/item/gun/projectile/automatic/shotgun/bulldog(src) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + +/obj/item/storage/backpack/duffel/syndie/med/medicalbundle + desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts." + +/obj/item/storage/backpack/duffel/syndie/med/medicalbundle/New() + ..() + new /obj/item/storage/firstaid/tactical(src) + new /obj/item/gun/projectile/automatic/l6_saw/toy(src) + new /obj/item/ammo_box/foambox/riot(src) + +/obj/item/storage/backpack/duffel/syndie/c4/New() + ..() + for(var/i in 1 to 10) + new /obj/item/grenade/plastic/c4(src) + +/obj/item/storage/backpack/duffel/syndie/x4/New() + ..() + for(var/i in 1 to 3) + new /obj/item/grenade/plastic/x4(src) + /obj/item/storage/backpack/duffel/syndie/surgery name = "surgery duffelbag" desc = "A suspicious looking duffelbag for holding surgery tools." diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 2fd7d774113..03cf28b25ed 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -42,7 +42,7 @@ /obj/item/storage/bag/trash/suicide_act(mob/user) user.visible_message("[user] puts the [name] over [user.p_their()] head and starts chomping at the insides! Disgusting!") playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) - return (TOXLOSS) + return TOXLOSS /obj/item/storage/bag/trash/update_icon() if(contents.len == 0) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index c52d4db7e5b..abf68deb765 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -112,6 +112,7 @@ icon_state = "medicalbelt" item_state = "medical" use_item_overlays = 1 + max_w_class = WEIGHT_CLASS_NORMAL can_hold = list( /obj/item/healthanalyzer, /obj/item/dnainjector, @@ -133,6 +134,7 @@ /obj/item/rad_laser, /obj/item/sensor_device, /obj/item/wrench/medical, + /obj/item/handheld_defibrillator ) /obj/item/storage/belt/medical/surgery diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 16ecd7cc72c..dfa1bf97358 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -9,9 +9,10 @@ var/mob/affecting = null var/deity_name = "Christ" - suicide_act(mob/user) - to_chat(viewers(user), "[user] stares into [src.name] and attempts to trascend understanding of the universe!") - return (user.dust()) +/obj/item/storage/bible/suicide_act(mob/user) + to_chat(viewers(user), "[user] stares into [src.name] and attempts to transcend understanding of the universe!") + user.dust() + return OBLITERATION /obj/item/storage/bible/booze diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index b2637a9688e..2450648cded 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -15,5 +15,15 @@ burn_state = FLAMMABLE burntime = 20 -/obj/item/storage/briefcase/New() - ..() +/obj/item/storage/briefcase/sniperbundle + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." + force = 10 + +/obj/item/storage/briefcase/sniperbundle/New() + ..() + new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) + new /obj/item/clothing/accessory/red(src) + new /obj/item/clothing/under/syndicate/sniper(src) + new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) + new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) + new /obj/item/suppressor/specialoffer(src) \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 5e81c320041..fab82df4b4e 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -295,11 +295,11 @@ for(var/obj/item/reagent_containers/food/pill/P in contents) P.attack(C, C) C.visible_message("[C] [rapid_post_instake_message]") - return + return return ..() -/obj/item/storage/pill_bottle/attackby(var/obj/item/I, mob/user as mob, params) +/obj/item/storage/pill_bottle/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/pen) || istype(I, /obj/item/flashlight/pen)) var/tmp_label = sanitize(input(user, "Enter a label for [name]","Label",label_text)) if(length(tmp_label) > MAX_NAME_LEN) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index cac42bfced7..ecf1acd701e 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -254,6 +254,13 @@ new /obj/item/ammo_casing/shotgun/assassination(src) new /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane(src) +/obj/item/storage/box/syndie_kit/fake_revolver + name = "trick revolver kit" + +/obj/item/storage/box/syndie_kit/fake_revolver/New() + ..() + new /obj/item/toy/russian_revolver/trick_revolver(src) + /obj/item/storage/box/syndie_kit/mimery name = "advanced mimery kit" @@ -262,13 +269,24 @@ new /obj/item/spellbook/oneuse/mime/greaterwall(src) new /obj/item/spellbook/oneuse/mime/fingergun(src) -/obj/item/storage/box/syndie_kit/atmosgasgrenades - name = "Atmos Grenades" -/obj/item/storage/box/syndie_kit/atmosgasgrenades/New() +/obj/item/storage/box/syndie_kit/atmosn2ogrenades + name = "Atmos N2O Grenades" + +/obj/item/storage/box/syndie_kit/atmosn2ogrenades/New() + ..() + new /obj/item/grenade/clusterbuster/n2o(src) + new /obj/item/grenade/clusterbuster/n2o(src) + + +/obj/item/storage/box/syndie_kit/atmosfiregrenades + name = "Plasma Fire Grenades" + +/obj/item/storage/box/syndie_kit/atmosfiregrenades/New() ..() new /obj/item/grenade/clusterbuster/plasma(src) - new /obj/item/grenade/clusterbuster/n2o(src) + new /obj/item/grenade/clusterbuster/plasma(src) + /obj/item/storage/box/syndie_kit/missionary_set name = "Missionary Starter Kit" diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index f33fc7240d2..f128b874eaa 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -18,7 +18,7 @@ /obj/item/melee/baton/suicide_act(mob/user) user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide.") - return (FIRELOSS) + return FIRELOSS /obj/item/melee/baton/New() ..() @@ -141,6 +141,12 @@ if(isrobot(M)) ..() return + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(check_martial_counter(H, user)) + return + if(!isliving(M)) return @@ -166,8 +172,6 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L - if(check_martial_counter(L, user)) - return if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) //No message; check_shields() handles that playsound(L, 'sound/weapons/genhit.ogg', 50, 1) return diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 3fc4b4b7717..d0526ebbcb8 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -52,7 +52,9 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) - return 0 + return + if(check_martial_counter(H, user)) + return playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1) target.Weaken(3) add_attack_logs(user, target, "Stunned with [src]") diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 5eb7a5b30ff..98f97b66f53 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -32,7 +32,7 @@ /obj/item/wrench/suicide_act(mob/user) user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/wrench/cyborg name = "automatic wrench" @@ -76,7 +76,7 @@ /obj/item/wrench/power/suicide_act(mob/user) user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) + return BRUTELOSS /obj/item/wrench/medical name = "medical wrench" @@ -113,7 +113,7 @@ return user.dust() - return OXYLOSS + return OBLITERATION //Screwdriver /obj/item/screwdriver @@ -143,7 +143,7 @@ /obj/item/screwdriver/suicide_act(mob/user) user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) + return BRUTELOSS /obj/item/screwdriver/New(loc, var/param_color = null) ..() @@ -199,7 +199,7 @@ /obj/item/screwdriver/power/suicide_act(mob/user) user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) + return BRUTELOSS /obj/item/screwdriver/power/attack_self(mob/user) playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, 1) @@ -256,7 +256,7 @@ /obj/item/wirecutters/suicide_act(mob/user) user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/wirecutters/brass name = "brass wirecutters" @@ -299,7 +299,7 @@ if(head) head.droplimb(0, DROPLIMB_BLUNT, FALSE, TRUE) playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/wirecutters/power/attack_self(mob/user) playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) @@ -349,7 +349,7 @@ /obj/item/weldingtool/suicide_act(mob/user) user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) + return FIRELOSS /obj/item/weldingtool/proc/update_torch() overlays.Cut() @@ -738,7 +738,7 @@ obj/item/weldingtool/experimental/process() /obj/item/crowbar/power/suicide_act(mob/user) user.visible_message("[user] is putting [user.p_their()] head in [src]. It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/crowbar/power/attack_self(mob/user) playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index de219626d31..29f2c2dd488 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -797,7 +797,7 @@ /obj/item/twohanded/pitchfork/suicide_act(mob/user) user.visible_message("[user] impales \himself in \his abdomen with [src]! It looks like \he's trying to commit suicide...") - return (BRUTELOSS) + return BRUTELOSS /obj/item/twohanded/pitchfork/demonic/pickup(mob/user) . = ..() diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index cd295befb83..b759139dba6 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -12,8 +12,8 @@ /obj/item/banhammer/suicide_act(mob/user) - to_chat(viewers(user), "[user] is hitting [user.p_them()]self with the [src.name]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") - return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) + to_chat(viewers(user), "[user] is hitting [user.p_them()]self with the [src.name]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") + return BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS /obj/item/sord name = "\improper SORD" @@ -49,7 +49,7 @@ /obj/item/claymore/suicide_act(mob/user) user.visible_message("[user] is falling on the [name]! It looks like [user.p_theyre()] trying to commit suicide.") - return(BRUTELOSS) + return BRUTELOSS /obj/item/claymore/ceremonial name = "ceremonial claymore" @@ -76,7 +76,7 @@ /obj/item/katana/suicide_act(mob/user) user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku.") - return(BRUTELOSS) + return BRUTELOSS /obj/item/harpoon name = "harpoon" diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm index fcc3e05bf14..f74f8d28f57 100644 --- a/code/game/objects/items/weapons/whetstone.dm +++ b/code/game/objects/items/weapons/whetstone.dm @@ -10,7 +10,7 @@ var/max = 30 var/prefix = "sharpened" var/requires_sharpness = 1 - var/claw_damage_increase = 1 + var/claw_damage_increase = 2 /obj/item/whetstone/attackby(obj/item/I, mob/user, params) @@ -58,13 +58,18 @@ var/mob/living/carbon/human/H = user var/datum/unarmed_attack/attack = H.dna.species.unarmed if(istype(attack, /datum/unarmed_attack/claws)) - attack.damage += claw_damage_increase - H.visible_message("[H] sharpens [H.p_their()] claws on [src]!", "You sharpen your claws on [src].") - playsound(get_turf(H), usesound, 50, 1) - name = "worn out [name]" - desc = "[desc] At least, it used to." - used = TRUE - update_icon() + var/datum/unarmed_attack/claws/C = attack + if(!C.has_been_sharpened) + C.has_been_sharpened = TRUE + attack.damage += claw_damage_increase + H.visible_message("[H] sharpens [H.p_their()] claws on [src]!", "You sharpen your claws on [src].") + playsound(get_turf(H), usesound, 50, 1) + name = "worn out [name]" + desc = "[desc] At least, it used to." + used = TRUE + update_icon() + else + to_chat(user, "You can not sharpen your claws any further!") /obj/item/whetstone/super name = "super whetstone block" diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 246fc5df75d..572495b503f 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -49,13 +49,9 @@ tforce = O.throwforce take_damage(tforce, BRUTE, "melee", 1, get_dir(src, AM)) -/obj/ex_act(severity, target) +/obj/ex_act(severity) if(resistance_flags & INDESTRUCTIBLE) return - if(target == src) - obj_integrity = 0 - qdel(src) - return switch(severity) if(1) obj_integrity = 0 @@ -69,7 +65,8 @@ . = ..() playsound(src, P.hitsound, 50, 1) visible_message("[src] is hit by \a [P]!") - take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) + if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object + take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) /obj/proc/hulk_damage() return 150 //the damage hulks do on punches to this object, is affected by melee armor diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index d9358c3a694..6506a5fdf2e 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -29,6 +29,7 @@ var/on_blueprints = FALSE //Are we visible on the station blueprints at roundstart? var/force_blueprints = FALSE //forces the obj to be on the blueprints, regardless of when it was created. + var/suicidal_hands = FALSE // Does it requires you to hold it to commit suicide with it? /obj/New() ..() @@ -76,6 +77,19 @@ processing_objects.Remove(src) return 0 +//user: The mob that is suiciding +//damagetype: The type of damage the item will inflict on the user +//BRUTELOSS = 1 +//FIRELOSS = 2 +//TOXLOSS = 4 +//OXYLOSS = 8 +//SHAME = 16 +//OBLITERATION = 32 + +//Output a creative message and then return the damagetype done +/obj/proc/suicide_act(mob/user) + return FALSE + /obj/assume_air(datum/gas_mixture/giver) if(loc) return loc.assume_air(giver) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 5be8c938f3e..03b0172c959 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -278,9 +278,11 @@ if(src == user.loc) to_chat(user, "You can not [welded?"unweld":"weld"] the locker from inside.") return - if(!WT.remove_fuel(0,user)) + if(!WT.remove_fuel(0, user)) to_chat(user, "You need more welding fuel to complete this task.") return + if(!do_after_once(user, 15, target = src)) + return welded = !welded update_icon() for(var/mob/M in viewers(src)) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 7b07e003bca..afb3ae15df4 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -20,6 +20,7 @@ new /obj/item/storage/box/permits(src) new /obj/item/clothing/under/rank/chief_engineer(src) new /obj/item/clothing/under/rank/chief_engineer/skirt(src) + new /obj/item/clothing/suit/mantle/chief_engineer(src) new /obj/item/clothing/head/hardhat/white(src) new /obj/item/clothing/glasses/welding/superior(src) new /obj/item/clothing/gloves/color/yellow(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 9cbd43bf098..5e300b0e7a0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -70,6 +70,7 @@ new /obj/item/radio/headset/headset_med(src) new /obj/item/clothing/gloves/color/latex/nitrile(src) new /obj/item/defibrillator/loaded(src) + new /obj/item/handheld_defibrillator(src) new /obj/item/storage/belt/medical(src) new /obj/item/clothing/glasses/hud/health(src) new /obj/item/clothing/shoes/sandal/white(src) @@ -180,10 +181,12 @@ new /obj/item/clothing/head/surgery/purple(src) new /obj/item/clothing/suit/storage/labcoat/cmo(src) new /obj/item/clothing/under/rank/chief_medical_officer(src) + new /obj/item/clothing/suit/mantle/labcoat/chief_medical_officer(src) new /obj/item/clothing/shoes/brown (src) new /obj/item/radio/headset/heads/cmo(src) new /obj/item/clothing/gloves/color/latex/nitrile(src) new /obj/item/defibrillator/compact/loaded(src) + new /obj/item/handheld_defibrillator(src) new /obj/item/storage/belt/medical(src) new /obj/item/flash(src) new /obj/item/reagent_containers/hypospray/CMO(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index ca673d40ec1..6be824a4246 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -13,6 +13,7 @@ new /obj/item/storage/backpack/science(src) new /obj/item/storage/backpack/satchel_tox(src) new /obj/item/clothing/under/rank/scientist(src) + new /obj/item/clothing/under/rank/scientist/skirt(src) //new /obj/item/clothing/suit/labcoat/science(src) new /obj/item/clothing/suit/storage/labcoat/science(src) new /obj/item/clothing/shoes/white(src) @@ -63,6 +64,7 @@ new /obj/item/clothing/head/bio_hood/scientist(src) new /obj/item/clothing/under/rank/research_director(src) new /obj/item/clothing/suit/storage/labcoat(src) + new /obj/item/clothing/suit/mantle/labcoat(src) new /obj/item/cartridge/rd(src) new /obj/item/clothing/shoes/white(src) new /obj/item/clothing/gloves/color/latex(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 6925c495309..746c9cb52ef 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -18,6 +18,7 @@ new /obj/item/storage/backpack/duffel/captain(src) new /obj/item/clothing/suit/captunic(src) new /obj/item/clothing/suit/captunic/capjacket(src) + new /obj/item/clothing/suit/mantle/armor/captain(src) new /obj/item/clothing/under/captainparade(src) new /obj/item/clothing/head/caphat/parade(src) new /obj/item/clothing/under/rank/captain(src) @@ -74,6 +75,7 @@ /obj/structure/closet/secure_closet/hop2/New() ..() new /obj/item/clothing/under/rank/head_of_personnel(src) + new /obj/item/clothing/suit/mantle/armor/head_of_personnel(src) new /obj/item/clothing/under/dress/dress_hop(src) new /obj/item/clothing/under/dress/dress_hr(src) new /obj/item/clothing/under/lawyer/female(src) @@ -113,6 +115,7 @@ new /obj/item/clothing/suit/armor/hos/alt(src) new /obj/item/clothing/head/HoS(src) new /obj/item/clothing/head/HoS/beret(src) + new /obj/item/clothing/suit/mantle/armor(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/storage/lockbox/mindshield(src) new /obj/item/storage/box/flashbangs(src) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index c06e5d82244..154d4438530 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -245,20 +245,20 @@ /obj/structure/grille/proc/shock(mob/user, prb) if(!anchored || broken) // unanchored/broken grilles are never connected - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE if(!in_range(src, user))//To prevent TK and mech users from getting shocked - return 0 + return FALSE var/turf/T = get_turf(src) var/obj/structure/cable/C = T.get_cable_node() if(C) - if(electrocute_mob(user, C, src)) + if(electrocute_mob(user, C, src, 1, TRUE)) do_sparks(3, 1, src) - return 1 + return TRUE else - return 0 - return 0 + return FALSE + return FALSE /obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index e5c0fc85722..67ee4b6ac00 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -116,9 +116,9 @@ if(.) return if(!shockcd) - if(ismob(user)) + if(isliving(user)) var/mob/living/M = user - M.electrocute_act(15,"Energy Barrier", safety=1) + M.electrocute_act(15, "Energy Barrier", safety = TRUE) shockcd = TRUE addtimer(CALLBACK(src, .proc/cooldown), 5) @@ -130,6 +130,6 @@ return var/mob/living/M = AM - M.electrocute_act(15, "Energy Barrier", safety = 1) + M.electrocute_act(15, "Energy Barrier", safety = TRUE) shockcd = TRUE addtimer(CALLBACK(src, .proc/cooldown), 5) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index c6e3ab2e5bd..f0a0c89880f 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -2,8 +2,8 @@ CONTAINS: SAFES FLOOR SAFES -Safe Codes -Safe Internals +SAFE INTERNALS +SAFE CODES */ GLOBAL_LIST_EMPTY(safes) @@ -11,22 +11,26 @@ GLOBAL_LIST_EMPTY(safes) //SAFES /obj/structure/safe name = "\improper Safe" - desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms - 2 tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\"" + desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\"" icon = 'icons/obj/structures.dmi' icon_state = "safe" - anchored = 1 - density = 1 - var/open = FALSE //is the safe open? + + anchored = TRUE + density = TRUE + resistance_flags = LAVA_PROOF | FIRE_PROOF + unacidable = TRUE + + var/open = FALSE var/locked = TRUE - var/tumbler_1_pos //the tumbler position- from 0 to 72 - var/tumbler_1_open //the tumbler position to open at- 0 to 72 - var/tumbler_2_pos - var/tumbler_2_open - var/open_pos - var/dial = 0 //where is the dial pointing? - var/space = 0 //the combined w_class of everything in the safe - var/maxspace = 24 //the maximum combined w_class of stuff in the safe - var/combo_to_open //so admins know the code + var/dial = 0 // The position the dial is pointing to. + + var/number_of_tumblers = 3 // The amount of tumblers that will be generated. + var/list/tumblers = list() // The list of tumbler dial positions that need to be hit. + var/list/current_tumbler_index = 1 // The index in the tumblers list of the tumbler dial position that needs to be hit. + + var/space = 0 // The combined w_class of everything in the safe. + var/maxspace = 24 // The maximum combined w_class of stuff in the safe. + var/obj/item/thermal_drill/drill = null var/drill_timer var/time_to_drill @@ -34,63 +38,81 @@ GLOBAL_LIST_EMPTY(safes) var/drill_start_time var/drill_x_offset = -13 var/drill_y_offset = -3 - var/knownby = list() + var/known_by = list() + var/image/progress_bar + var/image/drill_overlay + +/obj/structure/safe/Initialize(mapload) + . = ..() -/obj/structure/safe/New() GLOB.safes += src - tumbler_2_pos = rand(0, 99) // first value in the combination set first - tumbler_2_open = rand(0, 99) - tumbler_1_pos = rand(0, 99) - do - tumbler_1_open = rand(0, 99) - while(tumbler_1_open > Wrap(tumbler_2_open +48, 0, 100) && tumbler_1_open < Wrap(tumbler_2_open + 53, 0, 100)) // prevents a combination that wont open - do - open_pos = rand(0,99) - while(open_pos > Wrap(tumbler_1_open - 2, 0, 100) && open_pos < Wrap(tumbler_1_open + 2, 0, 100)) // prevents a combination that wont open - var/num1 = tumbler_2_open + 54 - if(num1 > 99) - num1 = num1 - 100 - var/num2 = tumbler_1_open + 98 - if(num2 > 99) - num2 = num2 - 100 + for(var/i in 1 to number_of_tumblers) + tumblers.Add(rand(0, 99)) - combo_to_open = "[num1] - [num2]" - - -/obj/structure/safe/Initialize() - ..() for(var/obj/item/I in loc) if(space >= maxspace) return if(I.w_class + space <= maxspace) space += I.w_class - I.loc = src + I.forceMove(src) +/obj/structure/safe/Destroy() + GLOB.safes -= src + drill?.soundloop?.stop() + drill?.forceMove(loc) + drill = null + + qdel(progress_bar) + qdel(drill_overlay) + return ..() + +/obj/structure/safe/process() + if(drill_timer) + cut_overlay(progress_bar) + progress_bar = image('icons/effects/progessbar.dmi', src, "prog_bar_[round((((world.time - drill_start_time) / time_to_drill) * 100), 5)]", HUD_LAYER) + add_overlay(progress_bar) + if(prob(15)) + drill.spark_system.start() + +/obj/structure/safe/examine(mob/user) + . = ..() + + to_chat(user, "This model appears to have [number_of_tumblers] tumblers.") + if(open) + to_chat(user, "The inside of the the door has numbers written on it: [get_combination()]") + +/obj/structure/safe/blob_act() + return + +/obj/structure/safe/ex_act(severity) + return + +/obj/structure/safe/examine_status(mob/user) + return /obj/structure/safe/proc/check_unlocked() - if(tumbler_1_pos == tumbler_1_open && tumbler_2_pos == tumbler_2_open && dial == open_pos) + if(current_tumbler_index > number_of_tumblers) locked = FALSE + visible_message("[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!") return TRUE + locked = TRUE return FALSE -/obj/structure/safe/proc/make_noise(turns, turns_total, tum1 = 0, tum2 = 0, mob/user, canhear) - if(user && canhear) - if(turns == 2) - to_chat(user, "The sounds from [src] are too fast and blend together.") - if(tum1 && (turns_total == 1 || prob(10))) // So multi turns dont super spam the chat - to_chat(user, "You hear a [pick("clack", "scrape", "clank")] from [src].") - if(tum2 && (turns_total == 1 || prob(10))) // So multi turns dont super spam the chat - to_chat(user, "You hear a [pick("click", "chink", "clink")] from [src].") - if(tumbler_1_pos == tumbler_1_open && turns_total == 1 && tum1) // You cant hear tumblers if you spin fast! - to_chat(user, "You hear a [pick("tonk", "krunk", "plunk")] from [src].") - if(tumbler_2_pos == tumbler_2_open && turns_total == 1 && tum2) // You cant hear tumblers if you spin fast! - to_chat(user, "You hear a [pick("tink", "krink", "plink")] from [src].") - if(!locked) - if(user) - visible_message("[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!") +/obj/structure/safe/proc/get_combination() + var/combination = "" + var/looped = 0 + + for(var/tumbler in tumblers) + looped++ + combination += "[tumbler]" + + if(looped < LAZYLEN(tumblers)) + combination += ", " + + return combination /obj/structure/safe/update_icon() if(open) @@ -103,21 +125,32 @@ GLOBAL_LIST_EMPTY(safes) icon_state = "[initial(icon_state)]-broken" else icon_state = initial(icon_state) - overlays.Cut() - if(istype(drill, /obj/item/thermal_drill/diamond_drill)) + + var/list/overlays_to_cut = list(drill_overlay) + if(!drill_timer) + overlays_to_cut += progress_bar + + cut_overlay(overlays_to_cut) + + if(istype(drill, /obj/item/thermal_drill)) + var/drill_icon = istype(drill, /obj/item/thermal_drill/diamond_drill) ? "d" : "h" if(drill_timer) - overlays += image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_d-drill-on", pixel_x = drill_x_offset, pixel_y = drill_y_offset) + drill_overlay = image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_[drill_icon]-drill-on", pixel_x = drill_x_offset, pixel_y = drill_y_offset) else - overlays += image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_d-drill-off", pixel_x = drill_x_offset, pixel_y = drill_y_offset) - else if(istype(drill, /obj/item/thermal_drill)) - if(drill_timer) - overlays += image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_h-drill-on", pixel_x = drill_x_offset, pixel_y = drill_y_offset) - else - overlays += image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_h-drill-off", pixel_x = drill_x_offset, pixel_y = drill_y_offset) + drill_overlay = image(icon = 'icons/effects/drill.dmi', icon_state = "[initial(icon_state)]_[drill_icon]-drill-off", pixel_x = drill_x_offset, pixel_y = drill_y_offset) + + add_overlay(drill_overlay) + +/obj/structure/safe/attack_ghost(mob/user) + if(..() || drill) + return TRUE + + ui_interact(user) /obj/structure/safe/attack_hand(mob/user) if(..()) return TRUE + if(drill) switch(alert("What would you like to do?", "Thermal Drill", "Turn [drill_timer ? "Off" : "On"]", "Remove Drill", "Cancel")) if("Turn On") @@ -145,7 +178,6 @@ GLOBAL_LIST_EMPTY(safes) return else ui_interact(user) - return /obj/structure/safe/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) @@ -161,30 +193,39 @@ GLOBAL_LIST_EMPTY(safes) for(var/obj/O in contents) contents_names[++contents_names.len] = list("name" = O.name, "index" = contents.Find(O), "sprite" = O.icon_state) user << browse_rsc(icon(O.icon, O.icon_state), "[O.icon_state].png") - else - contents_names = list(list("name" = "you're"), list("name" = "a"), list("name" = "cheater")) data["dial"] = dial data["open"] = open data["locked"] = locked - data["rotation"] = "[-dial*3.6]deg" + data["rotation"] = "[-dial * 3.6]deg" data["contents"] = contents_names return data +/obj/structure/safe/proc/notify_user(user, canhear, sounds, total_ticks, current_tick) + if(!canhear) + return + + if(current_tick == 2) + to_chat(user, "The sounds from [src] are too fast and blend together.") + + if(total_ticks == 1 || prob(10)) + to_chat(user, "You hear a [pick(sounds)] from [src].") /obj/structure/safe/Topic(href, href_list) if(..()) return TRUE - var/canhear = 0 - if(!ishuman(usr)) - to_chat(usr, "You don't have hands to operate the safe!") - return FALSE + var/mob/user = usr + if(!user.IsAdvancedToolUser() && !isobserver(user)) + to_chat(user, "You're not able to operate the safe.") + return - var/mob/living/carbon/human/user = usr - if(istype(user.l_hand, /obj/item/clothing/accessory/stethoscope) || istype(user.r_hand, /obj/item/clothing/accessory/stethoscope)) - canhear = 1 + var/canhear = FALSE + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.can_hear() && H.is_in_hands(/obj/item/clothing/accessory/stethoscope)) + canhear = TRUE if(href_list["open"]) if(check_unlocked() || open || broken) @@ -192,52 +233,65 @@ GLOBAL_LIST_EMPTY(safes) open = !open update_icon() else - to_chat(user, "You can't open [src], the lock is engaged!") - .= TRUE - SSnanoui.update_uis(src) + to_chat(user, "You can't open [src], as its lock is engaged!") - if(href_list["decrement"]) - var/ticks = text2num(href_list["decrement"]) + . = TRUE + + if(href_list["turnright"]) if(open) return + if(broken) - to_chat(user, "The dial will not turn, the mechanism is destroyed.") + to_chat(user, "The dial will not turn, as the mechanism is destroyed.") return - for(var/i=1 to ticks) - if(!check_unlocked()) - dial = Wrap(dial - 1, 0 ,100) - if(dial == tumbler_1_pos + 1 || dial == tumbler_1_pos - 99) - tumbler_1_pos = Wrap(tumbler_1_pos - 1, 0, 100) - make_noise(i, ticks, 1, 0, user, canhear) - if(tumbler_1_pos == tumbler_2_pos + 51 || tumbler_1_pos == tumbler_2_pos - 49) - tumbler_2_pos = Wrap(tumbler_2_pos - 1, 0, 100) - make_noise(0, ticks, 0, 1, user, canhear) + + var/ticks = text2num(href_list["turnright"]) + for(var/i = 1 to ticks) + dial = Wrap(dial - 1, 0, 100) + + var/invalid_turn = current_tumbler_index % 2 == 0 || current_tumbler_index > number_of_tumblers + if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset + current_tumbler_index = 1 + + if(!invalid_turn && dial == tumblers[current_tumbler_index]) + notify_user(user, canhear, list("tink", "krink", "plink"), ticks, i) + current_tumbler_index++ + else + notify_user(user, canhear, list("clack", "scrape", "clank"), ticks, i) + sleep(1) - check_unlocked() + check_unlocked(user, canhear) SSnanoui.update_uis(src) - make_noise(0, 0, 0, 0, user, canhear) - .= TRUE - if(href_list["increment"]) - var/ticks = text2num(href_list["increment"]) + . = TRUE + + if(href_list["turnleft"]) if(open) return + if(broken) - to_chat(user, "The dial will not turn, the mechanism is destroyed.") + to_chat(user, "The dial will not turn, as the mechanism is destroyed.") return - for(var/i=1 to ticks) - check_unlocked() + + var/ticks = text2num(href_list["turnleft"]) + for(var/i = 1 to ticks) dial = Wrap(dial + 1, 0, 100) - if(dial == tumbler_1_pos - 1 || dial == tumbler_1_pos + 99) - tumbler_1_pos = Wrap(tumbler_1_pos + 1, 0, 100) - make_noise(i, ticks, 1, 0, user, canhear) - if(tumbler_1_pos == tumbler_2_pos - 51 || tumbler_1_pos == tumbler_2_pos + 49) - tumbler_2_pos = Wrap(tumbler_2_pos + 1, 0, 100) - make_noise(0, ticks, 0, 1, user, canhear) + + var/invalid_turn = current_tumbler_index % 2 != 0 || current_tumbler_index > number_of_tumblers + if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset + current_tumbler_index = 1 + + if(!invalid_turn && dial == tumblers[current_tumbler_index]) + notify_user(user, canhear, list("tonk", "krunk", "plunk"), ticks, i) + current_tumbler_index++ + else + notify_user(user, canhear, list("click", "chink", "clink"), ticks, i) + sleep(1) + check_unlocked(user, canhear) SSnanoui.update_uis(src) - make_noise(0, 0, 0, 0, user, canhear) - .= TRUE + + . = TRUE if(href_list["retrieve"]) var/index = text2num(href_list["retrieve"]) @@ -247,52 +301,7 @@ GLOBAL_LIST_EMPTY(safes) if(P && in_range(src, user)) user.put_in_hands(P) space -= P.w_class - SSnanoui.update_uis(src) - .= TRUE - - - updateUsrDialog() - return - - -/obj/structure/safe/attackby(obj/item/I, mob/user, params) - if(open) - if(broken && istype(I, /obj/item/safe_internals) && do_after(user, 2 SECONDS, target = src)) - to_chat(user, "You replace the broken mechanism.") - qdel(I) - broken = !broken - update_icon() - return - else if(I.w_class + space <= maxspace) - space += I.w_class - if(!user.drop_item()) - to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the safe!") - return - I.loc = src - to_chat(user, "You put [I] in [src].") - updateUsrDialog() - return - else - to_chat(user, "[I] won't fit in [src].") - return - else - if(istype(I, /obj/item/clothing/accessory/stethoscope)) - to_chat(user, "Hold [I] in one of your hands while you manipulate the dial!") - return - else if(istype(I, /obj/item/thermal_drill)) - if(drill) - to_chat(user, "There is already a drill attached!") - else if(do_after(user, 2 SECONDS, target = src)) - if(!user.drop_item()) - to_chat(user, "[I] is stuck to your hand, you cannot put it in the safe!") - return - I.loc = src - drill = I - time_to_drill = 300 SECONDS * drill.time_multiplier - update_icon() - else - to_chat(user, "You can't put [I] in into the safe while it is closed!") - return + . = TRUE /obj/structure/safe/proc/drill_open() broken = TRUE @@ -301,50 +310,58 @@ GLOBAL_LIST_EMPTY(safes) update_icon() processing_objects.Remove(src) -/obj/structure/safe/blob_act() - return - -/obj/structure/safe/ex_act(severity) - return - -/obj/structure/safe/examine_status(mob/user) - return - -/obj/structure/safe/Destroy() - GLOB.safes -= src - drill?.soundloop?.stop() - return ..() - -/obj/structure/safe/process() - if(drill_timer) - overlays -= bar - bar = image('icons/effects/progessbar.dmi', src, "prog_bar_[round((((world.time - drill_start_time) / time_to_drill) * 100), 5)]", HUD_LAYER) - overlays += bar - if(prob(15)) - drill.spark_system.start() - -/obj/structure/safe/examine(mob/user) - ..() +/obj/structure/safe/attackby(obj/item/I, mob/user, params) if(open) - to_chat(user, "On the inside of the the door is [combo_to_open]") + if(broken && istype(I, /obj/item/safe_internals) && do_after(user, 2 SECONDS, target = src)) + to_chat(user, "You replace the broken mechanism.") + qdel(I) + broken = !broken + update_icon() + else if(I.w_class + space <= maxspace) + if(!user.drop_item()) + to_chat(user, "\The [I] is stuck to your hand, you cannot put it in the safe!") + return + space += I.w_class + I.forceMove(src) + to_chat(user, "You put [I] in [src].") + else + to_chat(user, "[I] won't fit in [src].") + else + if(istype(I, /obj/item/clothing/accessory/stethoscope)) + to_chat(user, "Hold [I] in one of your hands while you manipulate the dial!") + return + else if(istype(I, /obj/item/thermal_drill)) + if(drill) + to_chat(user, "There is already a drill attached!") + else if(do_after(user, 2 SECONDS, target = src)) + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand, you cannot put it in the safe!") + return + I.forceMove(src) + drill = I + time_to_drill = 300 SECONDS * drill.time_multiplier + update_icon() + else + to_chat(user, "You can't put [I] into the safe while it is closed!") + return //FLOOR SAFES /obj/structure/safe/floor name = "floor safe" icon_state = "floorsafe" - density = 0 - level = 1 //underfloor - layer = 2.5 + density = FALSE + level = 1 //Under the floor + layer = LOW_OBJ_LAYER drill_x_offset = -1 drill_y_offset = 20 /obj/structure/safe/floor/Initialize() - ..() + . = ..() var/turf/T = loc hide(T.intact) -/obj/structure/safe/floor/hide(var/intact) - invisibility = intact ? 101 : 0 +/obj/structure/safe/floor/hide(intact) + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 /obj/item/safe_internals name = "safe internals" @@ -356,14 +373,14 @@ GLOBAL_LIST_EMPTY(safes) var/owner info = "

Safe Codes

" -/obj/item/paper/safe_code/New() - ..() - addtimer(CALLBACK(src, .proc/populate_codes), 10) +/obj/item/paper/safe_code/Initialize(mapload) + return INITIALIZE_HINT_LATELOAD -/obj/item/paper/safe_code/proc/populate_codes() +/obj/item/paper/safe_code/LateInitialize(mapload) + . = ..() for(var/safe in GLOB.safes) var/obj/structure/safe/S = safe - if(owner in S.knownby) - info += "
The combination for the safe located in the [get_area(S).name] is: [S.combo_to_open]
" + if(owner in S.known_by) + info += "
The combination for the safe located in the [get_area(S).name] is: [S.get_combination()]
" info_links = info update_icon() \ No newline at end of file diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 88adc9643ba..6f531f5c14c 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -256,18 +256,18 @@ /obj/structure/statue/diamond hardness = 10 material_drop_type = /obj/item/stack/sheet/mineral/diamond - desc = "This is a very expensive diamond statue" + desc = "This is a very expensive diamond statue." /obj/structure/statue/diamond/captain - name = "statue of THE captain." + name = "statue of THE captain" icon_state = "cap" /obj/structure/statue/diamond/ai1 - name = "statue of the AI hologram." + name = "statue of the AI hologram" icon_state = "ai1" /obj/structure/statue/diamond/ai2 - name = "statue of the AI core." + name = "statue of the AI core" icon_state = "ai2" /obj/structure/statue/bananium diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 72469e2ebfb..acacb4e9153 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -269,51 +269,37 @@ obj/structure/windoor_assembly/Destroy() density = TRUE //Shouldn't matter but just incase to_chat(user, "You finish the windoor.") - + var/obj/machinery/door/window/windoor if(secure) - var/obj/machinery/door/window/brigdoor/windoor = new /obj/machinery/door/window/brigdoor(src.loc) + windoor = new /obj/machinery/door/window/brigdoor(src.loc) if(facing == "l") windoor.icon_state = "leftsecureopen" windoor.base_state = "leftsecure" else windoor.icon_state = "rightsecureopen" windoor.base_state = "rightsecure" - windoor.setDir(dir) - windoor.density = FALSE - - if(electronics.one_access) - windoor.req_one_access = electronics.conf_access - else - windoor.req_access = electronics.conf_access - windoor.electronics = src.electronics - electronics.forceMove(windoor) - if(created_name) - windoor.name = created_name - qdel(src) - windoor.close() - - else - var/obj/machinery/door/window/windoor = new /obj/machinery/door/window(loc) + windoor = new /obj/machinery/door/window(loc) if(facing == "l") windoor.icon_state = "leftopen" windoor.base_state = "left" else windoor.icon_state = "rightopen" windoor.base_state = "right" - windoor.setDir(dir) - windoor.density = FALSE + windoor.setDir(dir) + windoor.density = FALSE - if(electronics.one_access) - windoor.req_one_access = electronics.conf_access - else - windoor.req_access = electronics.conf_access - windoor.electronics = src.electronics - electronics.forceMove(windoor) - if(created_name) - windoor.name = created_name - qdel(src) - windoor.close() + if(electronics.one_access) + windoor.req_one_access = electronics.conf_access + else + windoor.req_access = electronics.conf_access + windoor.electronics = src.electronics + electronics.forceMove(windoor) + electronics = null + if(created_name) + windoor.name = created_name + qdel(src) + windoor.close() else return ..() diff --git a/code/game/sound.dm b/code/game/sound.dm index 9e0a28493bd..3846e2edeaa 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -5,6 +5,9 @@ var/turf/turf_source = get_turf(source) + if(!turf_source) + return + //allocate a channel if necessary now so its the same for everyone channel = channel || open_sound_channel() @@ -18,13 +21,17 @@ var/mob/M = P if(!M || !M.client) continue + + var/turf/T = get_turf(M) // These checks need to be changed if z-levels are ever further refactored + if(!T) + continue + if(T.z != turf_source.z) + continue + var/distance = get_dist(M, turf_source) if(distance <= maxdistance) - var/turf/T = get_turf(M) - - if(T && T.z == turf_source.z) - M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S) + M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S) /mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S) if(!client || !can_hear()) @@ -153,4 +160,4 @@ soundin = pick('sound/effects/bone_break_1.ogg', 'sound/effects/bone_break_2.ogg', 'sound/effects/bone_break_3.ogg', 'sound/effects/bone_break_4.ogg', 'sound/effects/bone_break_5.ogg', 'sound/effects/bone_break_6.ogg') if("honkbot_e") soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bcreep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg') - return soundin + return soundin \ No newline at end of file diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 51549c1a563..b74ec4107a0 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -35,7 +35,10 @@ else wet_overlay = image('icons/effects/water.dmi', src, "wet_floor_static") else - wet_overlay = image('icons/effects/water.dmi', src, "wet_static") + if(wet_setting >= TURF_WET_ICE) + wet_overlay = image('icons/effects/water.dmi', src, "ice_floor") + else + wet_overlay = image('icons/effects/water.dmi', src, "wet_static") overlays += wet_overlay spawn(rand(790, 820)) // Purely so for visual effect @@ -74,20 +77,26 @@ switch(src.wet) if(TURF_WET_WATER) - if(!(M.slip("wet floor", 4, 2, tilesSlipped = 0, walkSafely = 1))) + if(!(M.slip("the wet floor", 4, 2, tilesSlipped = 0, walkSafely = 1))) M.inertia_dir = 0 return if(TURF_WET_LUBE) //lube - M.slip("floor", 0, 5, tilesSlipped = 3, walkSafely = 0, slipAny = 1) + M.slip("the floor", 0, 5, tilesSlipped = 3, walkSafely = 0, slipAny = 1) if(TURF_WET_ICE) // Ice - if(!(prob(30) && M.slip("icy floor", 4, 2, tilesSlipped = 1, walkSafely = 1))) + if(M.slip("the icy floor", 4, 2, tilesSlipped = 0, walkSafely = 0)) M.inertia_dir = 0 + if(prob(5)) + var/obj/item/organ/external/affected = M.get_organ("head") + if(affected) + M.apply_damage(5, BRUTE, "head") + M.visible_message("[M] hits their head on the ice!") + playsound(src, 'sound/weapons/genhit1.ogg', 50, 1) if(TURF_WET_PERMAFROST) // Permafrost - M.slip("icy floor", 0, 5, tilesSlipped = 1, walkSafely = 0, slipAny = 1) + M.slip("the frosted floor", 0, 5, tilesSlipped = 1, walkSafely = 0, slipAny = 1) /turf/simulated/ChangeTurf(var/path) . = ..() diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 6b3dc1e93ff..07c2bb8a8d6 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -91,8 +91,7 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3"," return /turf/simulated/floor/proc/update_icon() - if(air) - update_visuals() + update_visuals() overlays -= current_overlay if(current_overlay) overlays.Add(current_overlay) diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 22a74ceed46..f1172435b1b 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -232,7 +232,7 @@ temperature = TCMB thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 700000 + heat_capacity = HEAT_CAPACITY_VACUUM /turf/simulated/floor/plating/airless/catwalk/New() ..() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 42f19fb2f7f..f007aebfff1 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -7,7 +7,7 @@ temperature = TCMB thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 700000 + heat_capacity = HEAT_CAPACITY_VACUUM var/destination_z var/destination_x diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index a35047bb9ad..9325d3a08b5 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -4,25 +4,21 @@ var/global/mentor_ooc_colour = "#0099cc" var/global/moderator_ooc_colour = "#184880" var/global/admin_ooc_colour = "#b82e00" -/client/verb/ooc(msg as text) +//Checks if the client already has a text input open +/client/proc/checkTyping() + return (prefs.toggles & TYPING_ONCE && typing) + +/client/verb/ooc(msg = "" as text) set name = "OOC" set category = "OOC" - + if(!mob) return if(IsGuestKey(key)) to_chat(src, "Guests may not use OOC.") return - msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) - if(!msg) - return - - if(!(prefs.toggles & CHAT_OOC)) - to_chat(src, "You have OOC muted.") - return - - if(!check_rights(R_ADMIN|R_MOD,0)) + if(!check_rights(R_ADMIN|R_MOD, 0)) if(!config.ooc_allowed) to_chat(src, "OOC is globally muted.") return @@ -32,6 +28,19 @@ var/global/admin_ooc_colour = "#b82e00" if(prefs.muted & MUTE_OOC) to_chat(src, "You cannot use OOC (muted).") return + + if(!msg) + msg = typing_input(src.mob, "", "ooc \"text\"") + + msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) + if(!msg) + return + + if(!(prefs.toggles & CHAT_OOC)) + to_chat(src, "You have OOC muted.") + return + + if(!check_rights(R_ADMIN|R_MOD,0)) if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN)) return if(findtext(msg, "byond://")) @@ -150,7 +159,7 @@ var/global/admin_ooc_colour = "#b82e00" feedback_add_details("admin_verb","ROC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/verb/looc(msg as text) +/client/verb/looc(msg = "" as text) set name = "LOOC" set desc = "Local OOC, seen only by those in view." set category = "OOC" @@ -161,14 +170,6 @@ var/global/admin_ooc_colour = "#b82e00" to_chat(src, "Guests may not use OOC.") return - msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) - if(!msg) - return - - if(!(prefs.toggles & CHAT_LOOC)) - to_chat(src, "You have LOOC muted.") - return - if(!check_rights(R_ADMIN|R_MOD,0)) if(!config.looc_allowed) to_chat(src, "LOOC is globally muted.") @@ -179,6 +180,19 @@ var/global/admin_ooc_colour = "#b82e00" if(prefs.muted & MUTE_OOC) to_chat(src, "You cannot use LOOC (muted).") return + + if(!msg) + msg = typing_input(src.mob, "Local OOC, seen only by those in view.", "looc \"text\"") + + msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) + if(!msg) + return + + if(!(prefs.toggles & CHAT_LOOC)) + to_chat(src, "You have LOOC muted.") + return + + if(!check_rights(R_ADMIN|R_MOD,0)) if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN)) return if(findtext(msg, "byond://")) diff --git a/code/game/verbs/randomtip.dm b/code/game/verbs/randomtip.dm new file mode 100644 index 00000000000..25cc996c8fe --- /dev/null +++ b/code/game/verbs/randomtip.dm @@ -0,0 +1,16 @@ +/client/verb/randomtip() + set category = "OOC" + set name = "Give Random Tip" + set desc = "Shows you a random tip" + + var/m + + var/list/randomtips = file2list("strings/tips.txt") + var/list/memetips = file2list("strings/sillytips.txt") + if(randomtips.len && prob(95)) + m = pick(randomtips) + else if(memetips.len) + m = pick(memetips) + + if(m) + to_chat(src, "Tip: [html_encode(m)]") diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index 06b168da042..46d5c4e36ba 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -1,7 +1,7 @@ /mob/var/suiciding = 0 /mob/living/carbon/human/proc/do_suicide(damagetype, byitem) - var/threshold = (config.health_threshold_crit + config.health_threshold_dead) / 2 + var/threshold = check_death_method() ? ((HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) / 2) : (HEALTH_THRESHOLD_DEAD - 50) var/dmgamt = maxHealth - threshold var/damage_mod = 1 @@ -52,6 +52,9 @@ /mob/living/carbon/human/verb/suicide() set hidden = 1 + be_suicidal() + +/mob/living/carbon/human/proc/be_suicidal(forced = FALSE) if(stat == DEAD) to_chat(src, "You're already dead!") return @@ -69,20 +72,39 @@ to_chat(src, "You're already committing suicide! Be patient!") return - var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") - if(confirm == "Yes") - suiciding = 1 + var/confirm = null + if(!forced) + confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") + + if(forced || (confirm == "Yes")) + suiciding = TRUE var/obj/item/held_item = get_active_hand() if(held_item) var/damagetype = held_item.suicide_act(src) if(damagetype) if(damagetype & SHAME) adjustStaminaLoss(200) - suiciding = 0 + suiciding = FALSE + return + if(damagetype & OBLITERATION) // Does it gib or something? Don't deal damage return do_suicide(damagetype, held_item) return + else + for(var/obj/O in orange(1, src)) + if(O.suicidal_hands) + continue + var/damagetype = O.suicide_act(src) + if(damagetype) + if(damagetype & SHAME) + adjustStaminaLoss(200) + suiciding = FALSE + return + if(damagetype & OBLITERATION) + return + do_suicide(damagetype, O) + return to_chat(viewers(src), "[src] [replacetext(pick(dna.species.suicide_messages), "their", p_their())] It looks like [p_theyre()] trying to commit suicide.") do_suicide(0) diff --git a/code/game/world.dm b/code/game/world.dm index 52f12a10c4e..4681f46498a 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -31,13 +31,15 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG Master.Initialize(10, FALSE) processScheduler = new - master_controller = new /datum/controller/game_controller() spawn(1) processScheduler.deferSetupFor(/datum/controller/process/ticker) processScheduler.setup() - master_controller.setup() + if(!syndicate_code_phrase) + syndicate_code_phrase = generate_code_phrase() + if(!syndicate_code_response) + syndicate_code_response = generate_code_phrase() if(using_map && using_map.name) map_name = "[using_map.name]" else @@ -322,6 +324,7 @@ var/world_topic_spam_protect_time = world.timeofday //kick_clients_in_lobby("The round came to an end with you in the lobby.", 1) processScheduler.stop() + Master.Shutdown() //run SS shutdowns shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. for(var/client/C in GLOB.clients) diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index dd46725ff26..5eec9d76bdd 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -70,6 +70,11 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = if(banned_mob.client) computerid = banned_mob.client.computer_id ip = banned_mob.client.address + else + if(banned_mob.lastKnownIP) + ip = banned_mob.lastKnownIP + if(banned_mob.computer_id) + computerid = banned_mob.computer_id else if(banckey) ckey = ckey(banckey) computerid = bancid diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index ce76dc4e282..c15600f7bb6 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -28,6 +28,11 @@ var/global/nologevent = 0 if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS)) to_chat(C, msg) +/proc/message_mentorTicket(var/msg) + for(var/client/C in GLOB.admins) + if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob)) + if(C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS)) + to_chat(C, msg) /proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify) if(!M || !M.ckey) @@ -316,7 +321,7 @@ var/global/nologevent = 0 if(CHANNEL.is_admin_channel) dat+="[CHANNEL.channel_name]
" else - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
" dat+={"

Refresh
Back "} @@ -400,7 +405,7 @@ var/global/nologevent = 0 dat+="No feed channels found active...
" else for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
" dat+="
Cancel" if(11) dat+={" @@ -413,7 +418,7 @@ var/global/nologevent = 0 dat+="No feed channels found active...
" else for(var/datum/feed_channel/CHANNEL in news_network.network_channels) - dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
" + dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
" dat+="
Back" if(12) @@ -671,8 +676,9 @@ var/global/nologevent = 0 alert("Unable to start the game as it is not set up.") return if(ticker.current_state == GAME_STATE_PREGAME) - if(alert(usr, "Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes") - return + if(config.start_now_confirmation) + if(alert(usr, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes") + return ticker.current_state = GAME_STATE_SETTING_UP log_admin("[key_name(usr)] has started the game.") message_admins("[key_name_admin(usr)] has started the game.") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 0c4dd38ef5f..e7078cb6877 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -107,6 +107,7 @@ var/list/admin_verbs_event = list( /client/proc/toggle_random_events, /client/proc/toggle_random_events, /client/proc/toggle_ert_calling, + /client/proc/show_tip, /client/proc/cmd_admin_change_custom_event, /client/proc/cmd_admin_custom_event_info, /client/proc/cmd_view_custom_event_info, @@ -205,6 +206,8 @@ var/list/admin_verbs_mentor = list( /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ + /client/proc/openMentorTicketUI, + /client/proc/toggleMentorTicketLogs, /client/proc/cmd_mentor_say /* mentor say*/ // cmd_mentor_say is added/removed by the toggle_mentor_chat verb ) @@ -219,10 +222,10 @@ var/list/admin_verbs_snpc = list( /client/proc/hide_snpc_verbs ) var/list/admin_verbs_ticket = list( - /client/proc/openTicketUI, + /client/proc/openAdminTicketUI, /client/proc/toggleticketlogs, - /client/proc/resolveAllTickets, - /client/proc/openUserUI + /client/proc/resolveAllAdminTickets, + /client/proc/resolveAllMentorTickets ) /client/proc/on_holder_add() @@ -678,24 +681,6 @@ var/list/admin_verbs_ticket = list( feedback_add_details("admin_verb","OT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/kill_air() // -- TLE - set category = "Debug" - set name = "Kill Air" - set desc = "Toggle Air Processing" - - if(!check_rights(R_DEBUG)) - return - - if(air_processing_killed) - air_processing_killed = 0 - to_chat(usr, "Enabled air processing.") - else - air_processing_killed = 1 - to_chat(usr, "Disabled air processing.") - feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(usr)] used 'kill air'.") - message_admins("[key_name_admin(usr)] used 'kill air'.", 1) - /client/proc/deadmin_self() set name = "De-admin self" set category = "Admin" @@ -885,7 +870,7 @@ var/list/admin_verbs_ticket = list( return var/list/jobs = list() - for(var/datum/job/J in job_master.occupations) + for(var/datum/job/J in SSjobs.occupations) if(J.current_positions >= J.total_positions && J.total_positions != -1) jobs += J.title if(!jobs.len) @@ -893,7 +878,7 @@ var/list/admin_verbs_ticket = list( return var/job = input("Please select job slot to free", "Free Job Slot") as null|anything in jobs if(job) - job_master.FreeRole(job) + SSjobs.FreeRole(job) log_admin("[key_name(usr)] has freed a job slot for [job].") message_admins("[key_name_admin(usr)] has freed a job slot for [job].") @@ -940,6 +925,20 @@ var/list/admin_verbs_ticket = list( else to_chat(usr, "You now will get admin log messages.") +/client/proc/toggleMentorTicketLogs() + set name = "Toggle Mentor Ticket Messgaes" + set category = "Preferences" + + if(!check_rights(R_MENTOR)) + return + + prefs.toggles ^= CHAT_NO_MENTORTICKETLOGS + prefs.save_preferences(src) + if(prefs.toggles & CHAT_NO_MENTORTICKETLOGS) + to_chat(usr, "You now won't get mentor ticket messages.") + else + to_chat(usr, "You now will get mentor ticket messages.") + /client/proc/toggleticketlogs() set name = "Toggle Admin Ticket Messgaes" set category = "Preferences" diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 0a943e6a170..f50bae146c3 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -477,6 +477,9 @@ else dat += "Blob not found!" dat += "" + + if(ticker.mode.blob_overminds.len) + dat += check_role_table("Blob Overminds", ticker.mode.blob_overminds) if(ticker.mode.changelings.len) dat += check_role_table("Changelings", ticker.mode.changelings) @@ -545,6 +548,16 @@ if(spider_minds.len) dat += check_role_table("Terror Spiders", spider_minds) + var/count_eggs = 0 + var/count_spiderlings = 0 + for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in ts_egg_list) + if(is_station_level(E.z)) + count_eggs += E.spiderling_number + for(var/obj/structure/spider/spiderling/terror_spiderling/L in ts_spiderling_list) + if(!L.stillborn && is_station_level(L.z)) + count_spiderlings += 1 + dat += "
Growing TS on-station: [count_eggs] egg[count_eggs != 1 ? "s" : ""], [count_spiderlings] spiderling[count_spiderlings != 1 ? "s" : ""].
" + if(ticker.mode.ert.len) dat += check_role_table("ERT", ticker.mode.ert) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index fe487ae6431..cec31ffc2ac 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -113,7 +113,9 @@ Japanese Animes Mode   Egalitarian Station Mode
Summon Guns   - Summon Magic + Summon Magic   + Summon Revolver Duel   + Summon Suicidal Revolver Duel
Roll the Dice

diff --git a/code/modules/admin/tickets/adminticketsverbs.dm b/code/modules/admin/tickets/adminticketsverbs.dm index f203ef501e8..9ad1f722b08 100644 --- a/code/modules/admin/tickets/adminticketsverbs.dm +++ b/code/modules/admin/tickets/adminticketsverbs.dm @@ -1,8 +1,8 @@ //Verbs -/client/proc/openTicketUI() +/client/proc/openAdminTicketUI() - set name = "Open Ticket Interface" + set name = "Open Admin Ticket Interface" set category = "Admin" if(!holder || !check_rights(R_ADMIN)) @@ -10,8 +10,8 @@ SStickets.showUI(usr) -/client/proc/resolveAllTickets() - set name = "Resolve All Open Tickets" +/client/proc/resolveAllAdminTickets() + set name = "Resolve All Open Admin Tickets" set category = "Admin" if(!holder || !check_rights(R_ADMIN)) @@ -22,12 +22,7 @@ SStickets.resolveAllOpenTickets() -/client/proc/openUserUI() - - set name = "My Tickets" +/client/verb/openAdminUserUI() + set name = "My Admin Tickets" set category = "Admin" - - if(!holder || !check_rights(R_ADMIN)) - return - SStickets.userDetailUI(usr) diff --git a/code/modules/admin/tickets/mentorticketsverbs.dm b/code/modules/admin/tickets/mentorticketsverbs.dm new file mode 100644 index 00000000000..765a1afb9da --- /dev/null +++ b/code/modules/admin/tickets/mentorticketsverbs.dm @@ -0,0 +1,28 @@ +//Verbs + +/client/proc/openMentorTicketUI() + + set name = "Open Mentor Ticket Interface" + set category = "Admin" + + if(!holder || !check_rights(R_MENTOR)) + return + + SSmentor_tickets.showUI(usr) + +/client/proc/resolveAllMentorTickets() + set name = "Resolve All Open Mentor Tickets" + set category = "Admin" + + if(!holder || !check_rights(R_ADMIN)) + return + + if(alert("Are you sure you want to resolve ALL open tickets?","Resolve all open tickets?","Yes","No") != "Yes") + return + + SSmentor_tickets.resolveAllOpenTickets() + +/client/verb/openMentorUserUI() + set name = "My Mentor Tickets" + set category = "Admin" + SSmentor_tickets.userDetailUI(usr) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 03d2940b32d..88d10abde98 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -32,6 +32,12 @@ var/ticketID = text2num(href_list["openadminticket"]) SStickets.showDetailUI(usr, ticketID) + if(href_list["openmentorticket"]) + if(!check_rights(R_MENTOR|R_MOD|R_ADMIN)) + return + var/ticketID = text2num(href_list["openmentorticket"]) + SSmentor_tickets.showDetailUI(usr, ticketID) + if(href_list["stickyban"]) stickyban(href_list["stickyban"],href_list) @@ -485,8 +491,8 @@ if(!M.ckey) //sanity to_chat(usr, "This mob has no ckey") return - if(!job_master) - to_chat(usr, "Job Master has not been setup!") + if(!SSjobs) + to_chat(usr, "SSjobs has not been setup!") return var/dat = "" @@ -506,7 +512,7 @@ jobs += "Command Positions" for(var/jobPos in command_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -527,7 +533,7 @@ jobs += "Security Positions" for(var/jobPos in security_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -548,7 +554,7 @@ jobs += "Engineering Positions" for(var/jobPos in engineering_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -569,7 +575,7 @@ jobs += "Medical Positions" for(var/jobPos in medical_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -590,7 +596,7 @@ jobs += "Science Positions" for(var/jobPos in science_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -611,7 +617,7 @@ jobs += "Support Positions" for(var/jobPos in support_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -632,7 +638,7 @@ jobs += "Non-human Positions" for(var/jobPos in nonhuman_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -701,7 +707,7 @@ jobs += "Whitelisted Positions" for(var/jobPos in whitelisted_positions) if(!jobPos) continue - var/datum/job/job = job_master.GetJob(jobPos) + var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue if(jobban_isbanned(M, job.title)) @@ -737,8 +743,8 @@ var/ban_ckey_param = href_list["dbbanaddckey"] - if(!job_master) - to_chat(usr, "Job Master has not been setup!") + if(!SSjobs) + to_chat(usr, "SSjobs has not been setup!") return //get jobs for department if specified, otherwise just returnt he one job in a list. @@ -747,50 +753,50 @@ if("commanddept") for(var/jobPos in command_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("securitydept") for(var/jobPos in security_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("engineeringdept") for(var/jobPos in engineering_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("medicaldept") for(var/jobPos in medical_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("sciencedept") for(var/jobPos in science_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("supportdept") for(var/jobPos in support_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("nonhumandept") joblist += "pAI" for(var/jobPos in nonhuman_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title if("whitelistdept") for(var/jobPos in whitelisted_positions) if(!jobPos) continue - var/datum/job/temp = job_master.GetJob(jobPos) + var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title else @@ -999,15 +1005,7 @@ var/reason = input(usr,"Please state the reason","Reason") as message|null if(!reason) return - switch(alert(usr,"IP ban?",,"Yes","No","Cancel")) - if("Cancel") - return - if("Yes") - M = admin_ban_mobsearch(M, ban_ckey_param, usr) - AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) - if("No") - M = admin_ban_mobsearch(M, ban_ckey_param, usr) - AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) + AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].") to_chat(M, "This is a permanent ban.") if(config.banappeals) @@ -1546,21 +1544,12 @@ check_antagonists() else if(href_list["take_question"]) - var/mob/M = locateUID(href_list["take_question"]) - var/is_mhelp = href_list["is_mhelp"] - if(ismob(M)) - var/helptype = "ADMINHELP" - if(is_mhelp) - helptype = "MENTORHELP" - var/take_msg = "[helptype]: [key_name_hidden(usr.client)] is attending to [key_name(M)]'s question." - for(var/client/X in GLOB.admins) - if(check_rights(R_ADMIN, 0, X.mob)) - to_chat(X, take_msg) - else if(is_mhelp && check_rights(R_MOD|R_MENTOR, 0, X.mob)) - to_chat(X, take_msg) - to_chat(M, "Your question is being attended to by [key_name_hidden(usr.client, null, 0)]. Thanks for your patience!") - else - to_chat(usr, "Unable to locate mob.") + var/index = text2num(href_list["take_question"]) + + if(href_list["is_mhelp"]) + SSmentor_tickets.takeTicket(index) + else //Ahelp + SStickets.takeTicket(index) else if(href_list["cult_nextobj"]) if(alert(usr, "Validate the current Cult objective and unlock the next one?", "Cult Cheat Code", "Yes", "No") != "Yes") @@ -1889,7 +1878,7 @@ var/logmsg = null switch(punishment) if("Lightning bolt") - M.electrocute_act(5, "Lightning Bolt", safety=1) + M.electrocute_act(5, "Lightning Bolt", safety = TRUE, override = TRUE) playsound(get_turf(M), 'sound/magic/lightningshock.ogg', 50, 1, -1) M.adjustFireLoss(75) M.Weaken(5) @@ -2843,11 +2832,19 @@ if("guns") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","SG") - usr.rightandwrong(0) + usr.rightandwrong(FALSE) if("magic") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","SM") - usr.rightandwrong(1) + usr.rightandwrong(TRUE) + if("revolver") + feedback_inc("admin_secrets_fun_used", 1) + feedback_add_details("admin_secrets_fun_used", "SRD") + usr.rightandwrong(FALSE, revolver_fight = TRUE) + if("fakerevolver") + feedback_inc("admin_secrets_fun_used", 1) + feedback_add_details("admin_secrets_fun_used", "SFD") + usr.rightandwrong(FALSE, fake_revolver_fight = TRUE) if("tdomereset") var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel") if(delete_mobs == "Cancel") @@ -2938,11 +2935,11 @@ usr << browse(dat, "window=lawchanges;size=800x500") if("list_job_debug") var/dat = "Job Debug info.
" - if(job_master) - for(var/line in job_master.job_debug) + if(SSjobs) + for(var/line in SSjobs.job_debug) dat += "[line]
" dat+= "*******

" - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(!job) continue dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions]
" usr << browse(dat, "window=jobdebug;size=600x500") @@ -3032,7 +3029,7 @@ M.req_one_access = list(access_brig,access_engine) message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.") if("infinite_sec") - var/datum/job/J = job_master.GetJob("Security Officer") + var/datum/job/J = SSjobs.GetJob("Security Officer") if(!J) return J.total_positions = -1 J.spawn_positions = -1 diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 1baf6bf0ee8..a1f56c52c78 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -103,31 +103,46 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," if(check_rights(R_MENTOR, 0, X.mob)) mentorholders += X continue + var/ticketNum // Holder for the ticket number + var/prunedmsg ="[src]: [msg]" // Message without links + var/datum/ticket/T + var/isMhelp = selected_type == "Mentorhelp" + var/span + if(isMhelp) + span = "" + if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket + T = SSmentor_tickets.checkForOpenTicket(src) + else + ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned. + else //Ahelp + span = "" + if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket + T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open + else + ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned. + + if(T) + ticketNum = T.ticketNum // ticketNum is the number of their ticket. + T.addResponse(src, msg) + + msg = "[span][selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (TICKET) [ai_found ? "(CL)" : ""] (TAKE) : [span][msg]" + if(isMhelp) + //Open a new adminticket and inform the user. + SSmentor_tickets.newTicket(src, prunedmsg, msg) + for(var/client/X in mentorholders + modholders + adminholders) + if(X.prefs.sound & SOUND_MENTORHELP) + X << 'sound/effects/adminhelp.ogg' + to_chat(X, msg) + else //Ahelp + //Open a new adminticket and inform the user. + SStickets.newTicket(src, prunedmsg, msg) + for(var/client/X in modholders + adminholders) + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' + window_flash(X) + to_chat(X, msg) - switch(selected_type) - if("Mentorhelp") - msg = "[selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (TAKE) : [msg]" - for(var/client/X in mentorholders + modholders + adminholders) - if(X.prefs.sound & SOUND_MENTORHELP) - X << 'sound/effects/adminhelp.ogg' - to_chat(X, msg) - if("Adminhelp") - var/ticketNum // Holder for the ticket number - var/prunedmsg ="[usr.client]: [msg]" // Message without links - if(SStickets.checkForOpenTicket(usr)) // If user already has an open ticket - var/datum/admin_ticket/T = SStickets.checkForOpenTicket(usr) // Make T equal to the ticket they have open - ticketNum = T.ticketNum // ticketNum is the number of their ticket. - T.addResponse(usr.client, msg) - else - ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned. - msg = "[selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (TICKET) [ai_found ? " (CL)" : ""](TAKE) : [msg]" - //Open a new adminticket and inform the user. - SStickets.newTicket(src, prunedmsg, msg) - for(var/client/X in modholders + adminholders) - if(X.prefs.sound & SOUND_ADMINHELP) - X << 'sound/effects/adminhelp.ogg' - window_flash(X) - to_chat(X, msg) + //show it to the person adminhelping too to_chat(src, "[selected_type]
: [original_msg]") diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 5303480e905..e9d813c1439 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -182,23 +182,28 @@ else if(check_rights(R_ADMIN|R_MOD, 0, X.mob)) to_chat(X, "[type]: [key_name(src, TRUE, type)]->[key_name(C, TRUE, type)]: [emoji_msg]") - - if(type == "Mentorhelp") - return + //Check if the mob being PM'd has any open admin tickets. var/tickets = list() - tickets = SStickets.checkForTicket(C) + if(type == "Mentorhelp") + tickets = SSmentor_tickets.checkForTicket(C) + else + tickets = SStickets.checkForTicket(C) if(tickets) - for(var/datum/admin_ticket/i in tickets) + for(var/datum/ticket/i in tickets) i.addResponse(src, msg) // Add this response to their open tickets. return - - if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets - tickets = SStickets.checkForTicket(src) - if(tickets) - for(var/datum/admin_ticket/i in tickets) - i.addResponse(src, msg) - return + if(type == "Mentorhelp") + if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets + tickets = SSmentor_tickets.checkForTicket(src) + else // Ahelp + if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets + tickets = SStickets.checkForTicket(src) + + if(tickets) + for(var/datum/ticket/i in tickets) + i.addResponse(src, msg) + return /client/proc/cmd_admin_irc_pm() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2b96f7d3290..3492061f1f6 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -612,7 +612,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/datum/job/jobdatum if(dresscode == "as job...") var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs() - jobdatum = job_master.GetJob(jobname) + jobdatum = SSjobs.GetJob(jobname) feedback_add_details("admin_verb", "SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! if(dostrip) diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 8b8a2b58a52..93389acbdd8 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -83,9 +83,9 @@ "_default" = "NO_FILTER" ) var/output = "Radio Report
" - for(var/fq in radio_controller.frequencies) + for(var/fq in SSradio.frequencies) output += "Freq: [fq]
" - var/list/datum/radio_frequency/fqs = radio_controller.frequencies[fq] + var/list/datum/radio_frequency/fqs = SSradio.frequencies[fq] if(!fqs) output += "  ERROR
" continue diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 24ce21276e7..15ee321656c 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -435,8 +435,8 @@ Traitors and the like can also be revived with the previous role mostly intact. //Now for special roles and equipment. switch(new_character.mind.special_role) if("traitor") - job_master.AssignRank(new_character, new_character.mind.assigned_role, 0) - job_master.EquipRank(new_character, new_character.mind.assigned_role, 1) + SSjobs.AssignRank(new_character, new_character.mind.assigned_role, 0) + SSjobs.EquipRank(new_character, new_character.mind.assigned_role, 1) ticker.mode.equip_traitor(new_character) if("Wizard") new_character.loc = pick(wizardstart) @@ -466,8 +466,8 @@ Traitors and the like can also be revived with the previous role mostly intact. call(/datum/game_mode/proc/add_law_zero)(new_character) //Add aliens. else - job_master.AssignRank(new_character, new_character.mind.assigned_role, 0) - job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. + SSjobs.AssignRank(new_character, new_character.mind.assigned_role, 0) + SSjobs.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. //Announces the character on all the systems, based on the record. if(!issilicon(new_character))//If they are not a cyborg/AI. @@ -662,11 +662,11 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_ADMIN)) return - if(job_master) + if(SSjobs) var/currentpositiontally var/totalpositiontally to_chat(src, "Job Name: Filled job slot / Total job slots (Free job slots)") - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) to_chat(src, "[job.title]: [job.current_positions] / \ [job.total_positions == -1 ? "UNLIMITED" : job.total_positions] \ ([job.total_positions == -1 ? "UNLIMITED" : job.total_positions - job.current_positions])") @@ -1020,6 +1020,31 @@ Traitors and the like can also be revived with the previous role mostly intact. log_admin("Admin [key_name(src)] has disabled ERT calling.") message_admins("Admin [key_name_admin(usr)] has disabled ERT calling.", 1) +/client/proc/show_tip() + set category = "Admin" + set name = "Show Custom Tip" + set desc = "Sends a tip (that you specify) to all players. After all \ + you're the experienced player here." + + if(!check_rights(R_ADMIN)) + return + + var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null + if(!input) + return + + if(!ticker) + return + + ticker.selected_tip = input + + // If we've already tipped, then send it straight away. + if(ticker.tipped) + ticker.send_tip_of_the_round() + + message_admins("[key_name_admin(usr)] sent a Tip of the round.") + log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") + /client/proc/modify_goals() set category = "Event" set name = "Modify Station Goals" diff --git a/code/modules/admin/verbs/tripAI.dm b/code/modules/admin/verbs/tripAI.dm index 0da0dfc42f6..10ad3f07020 100644 --- a/code/modules/admin/verbs/tripAI.dm +++ b/code/modules/admin/verbs/tripAI.dm @@ -6,8 +6,8 @@ to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.") return - if(job_master && ticker) - var/datum/job/job = job_master.GetJob("AI") + if(SSjobs && ticker) + var/datum/job/job = SSjobs.GetJob("AI") if(!job) to_chat(usr, "Unable to locate the AI job") return diff --git a/code/modules/antagonists/_common/antag_hud.dm b/code/modules/antagonists/_common/antag_hud.dm index 693b0b9450d..89ad9af15ab 100644 --- a/code/modules/antagonists/_common/antag_hud.dm +++ b/code/modules/antagonists/_common/antag_hud.dm @@ -1,5 +1,5 @@ /datum/atom_hud/antag - hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD) + hud_icons = list(SPECIALROLE_HUD) var/self_visible = TRUE /datum/atom_hud/antag/hidden @@ -38,16 +38,6 @@ if(M.mind || new_icon_state) //in mindless mobs, only null is acceptable, otherwise we're antagging a mindless mob, meaning we should runtime M.mind.antag_hud_icon_state = new_icon_state -//Nations Icons -/proc/set_nations_hud(mob/M, new_icon_state) - if(!istype(M)) - CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") - var/image/holder = M.hud_list[NATIONS_HUD] - if(holder) - holder.icon_state = new_icon_state - if(M.mind || new_icon_state) //in mindless mobs, only null is acceptable, otherwise we're antagging a mindless mob, meaning we should runtime - M.mind.antag_hud_icon_state = new_icon_state - //MIND PROCS //these are called by mind.transfer_to() /datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud) diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 937c831dfbf..5e434887ee0 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -10,73 +10,115 @@ /obj/item/antag_spawner/proc/equip_antag(mob/target) return - -/obj/item/antag_spawner/borg_tele - name = "syndicate cyborg teleporter" - desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field." +///////////BORGS AND OPERATIVES +/obj/item/antag_spawner/nuke_ops + name = "syndicate operative teleporter" + desc = "A single-use teleporter designed to quickly reinforce operatives in the field." icon = 'icons/obj/device.dmi' icon_state = "locator" - var/checking = FALSE - var/TC_cost = 0 var/borg_to_spawn - var/upload_mind - var/list/possible_types = list("Assault", "Medical", "Saboteur") + var/checking = FALSE -/obj/item/antag_spawner/borg_tele/attack_self(mob/user) +/obj/item/antag_spawner/nuke_ops/proc/before_candidate_search(user) + return TRUE + +/obj/item/antag_spawner/nuke_ops/proc/check_usability(mob/user) if(used) to_chat(user, "[src] is out of power!") - return + return FALSE if(!(user.mind in ticker.mode.syndicates)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(checking) - to_chat(user, "[src] is already checking for possible borgs.") - return - borg_to_spawn = input("What type of borg would you like to teleport?", "Cyborg Type", type) as null|anything in possible_types - if(!borg_to_spawn || checking || used) - return - upload_mind = input("Would you like to continue playing as an operative or take over the cyborg? (Another player will control your old self)", "Play as") as null|anything in list("Nuclear Operative", "Syndicate Cyborg") - if(!upload_mind || checking || used) - return - if(upload_mind == "Nuclear Operative") - checking = TRUE - to_chat(user, "The device is now checking for possible borgs.") - var/list/borg_candidates = pollCandidates("Do you want to play as a Syndicate [borg_to_spawn] borg?", ROLE_OPERATIVE, 1) - if(borg_candidates.len > 0 && !used) - checking = FALSE - used = TRUE - var/mob/M = pick(borg_candidates) - var/client/C = M.client - spawn_antag(C, get_turf(loc), "syndieborg") - qdel(src) - else - checking = FALSE - to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.") - return - else if(upload_mind == "Syndicate Cyborg") - checking = TRUE - to_chat(user, "You attempt to upload your consciousness into a new syndicate cyborg.") - var/list/nuclear_candidates = pollCandidates("Do you want to play as the Syndicate Nuclear Operative [user.real_name]?", ROLE_OPERATIVE, 1) - if(nuclear_candidates.len > 0 && !used) - checking = FALSE - used = TRUE - var/mob/M = pick(nuclear_candidates) - var/client/nukeop_client = M.client - var/client/borg_client = user.client - spawn_antag(borg_client, get_turf(loc), "syndieborg") - user.key = nukeop_client.key - ticker.mode.greet_syndicate(user.mind) - qdel(src) - else - checking = FALSE - to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.") - return + to_chat(user, "The device is already connecting to Syndicate command. Please wait.") + return FALSE + return TRUE -/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "") - if(!borg_to_spawn) //If there's no type at all, let it still be used but don't do anything +/obj/item/antag_spawner/nuke_ops/attack_self(mob/user) + if(!(check_usability(user))) + return + + var/continue_proc = before_candidate_search(user) + if(!continue_proc) + return + + checking = TRUE + + to_chat(user, "You activate [src] and wait for confirmation.") + var/list/nuke_candidates = pollCandidates("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg" : "operative"]?", ROLE_OPERATIVE, TRUE, 150) + if(LAZYLEN(nuke_candidates)) + checking = FALSE + if(QDELETED(src) || !check_usability(user)) + return + used = TRUE + var/mob/dead/observer/G = pick(nuke_candidates) + spawn_antag(G.client, get_turf(src), user.mind) + do_sparks(4, TRUE, src) + qdel(src) + else + checking = FALSE + to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") + +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) + var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) + + var/agent_number = LAZYLEN(ticker.mode.syndicates) + M.real_name = "[syndicate_name()] Operative #[agent_number]" + + set_syndicate_values(C, M) + ticker.mode.create_syndicate(M.mind) + ticker.mode.equip_syndicate(M, 0) + ticker.mode.update_syndicate_id(M.mind, FALSE) + +/obj/item/antag_spawner/nuke_ops/proc/set_syndicate_values(client/C, mob/living/M) + M.key = C.key + + ticker.mode.syndicates += M.mind + ticker.mode.update_synd_icons_added(M.mind) + + M.mind.assigned_role = SPECIAL_ROLE_NUKEOPS + M.mind.special_role = SPECIAL_ROLE_NUKEOPS + M.mind.offstation_role = TRUE + + M.faction = list("syndicate") + ticker.mode.forge_syndicate_objectives(M.mind) + ticker.mode.greet_syndicate(M.mind) + +//////SYNDICATE BORG +/obj/item/antag_spawner/nuke_ops/borg_tele + name = "syndicate cyborg teleporter" + desc = "A single-use teleporter designed to quickly reinforce operatives in the field." + var/switch_roles = FALSE + +/obj/item/antag_spawner/nuke_ops/borg_tele/assault + name = "syndicate assault cyborg teleporter" + borg_to_spawn = "Assault" + +/obj/item/antag_spawner/nuke_ops/borg_tele/medical + name = "syndicate medical teleporter" + borg_to_spawn = "Medical" + +/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + name = "syndicate saboteur teleporter" + borg_to_spawn = "Saboteur" + +/obj/item/antag_spawner/nuke_ops/borg_tele/before_candidate_search(mob/user) + var/switch_roles_choice = input("Would you like to continue playing as an operative or take over as the cyborg? If you play as the cyborg, another player will control your old self.", "Play As") as null|anything in list("Nuclear Operative", "Syndicate Cyborg") + if(!switch_roles_choice || !(check_usability(user))) + return FALSE + + if(switch_roles_choice == "Syndicate Cyborg") + switch_roles = TRUE + else + switch_roles = FALSE + + return TRUE + +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, datum/mind/user) + if(!(user in ticker.mode.syndicates)) used = FALSE return - do_sparks(4, 1, src) + var/mob/living/silicon/robot/R switch(borg_to_spawn) if("Medical") @@ -85,11 +127,29 @@ R = new /mob/living/silicon/robot/syndicate/saboteur(T) else R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default - R.key = C.key - ticker.mode.syndicates += R.mind - ticker.mode.update_synd_icons_added(R.mind) - R.mind.special_role = SPECIAL_ROLE_NUKEOPS - R.faction = list("syndicate") + + var/brainfirstname = pick(GLOB.first_names_male) + if(prob(50)) + brainfirstname = pick(GLOB.first_names_female) + var/brainopslastname = pick(GLOB.last_names) + if(syndicate_name()) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = syndicate_name() + var/brainopsname = "[brainfirstname] [brainopslastname]" + + R.mmi.name = "[initial(R.mmi.name)]: [brainopsname]" + R.mmi.brainmob.real_name = brainopsname + R.mmi.brainmob.name = brainopsname + + if(!switch_roles) + set_syndicate_values(C, R) + else + var/mob/living/L = user.current + set_syndicate_values(user.current.client, R) + + L.key = C.key + ticker.mode.greet_syndicate(L.mind) + +///////////SLAUGHTER DEMON /obj/item/antag_spawner/slaughter_demon //Warning edgiest item in the game name = "vial of blood" @@ -149,7 +209,6 @@ to_chat(S, "Objective #[1]: [KillDaWiz.explanation_text]") to_chat(S, "Objective #[2]: [KillDaCrew.explanation_text]") - /obj/item/antag_spawner/slaughter_demon/laughter name = "vial of tickles" desc = "A magically infused bottle of clown love, distilled from \ @@ -160,3 +219,61 @@ lurking just beyond the veil..." objective_verb = "Hug and Tickle" demon_type = /mob/living/simple_animal/slaughter/laughter + +///////////MORPH + +/obj/item/antag_spawner/morph + name = "vial of ooze" + desc = "A magically infused bottle of ooze, distilled by methods rather not be spoken of. Used to awaken an all-consuming monstrosity." + icon = 'icons/obj/wizard.dmi' + icon_state = "vialooze" + var/shatter_msg = "You shatter the bottle, no \ + turning back now!" + var/veil_msg = "The sludge is awake and seeps \ + away..." + var/objective_verb = "Eat" + var/mob/living/morph_type = /mob/living/simple_animal/hostile/morph + +/obj/item/antag_spawner/morph/attack_self(mob/user) + if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a morph from the Den.. + to_chat(user, "You should probably wait until you reach the station.") + return + + if(used) + to_chat(user, "This bottle already has a broken seal.") + return + used = TRUE + to_chat(user, "You break the seal on the bottle, calling upon the dire sludge to awaken...") + + var/list/candidates = pollCandidates("Do you want to play as a morph awakened by [user.real_name]?", ROLE_MORPH, 1, 100) + + if(candidates.len > 0) + var/mob/C = pick(candidates) + spawn_antag(C, get_turf(src.loc), initial(morph_type.name), user) + to_chat(user, "[shatter_msg]") + to_chat(user, "[veil_msg]") + playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) + qdel(src) + else + used = FALSE + to_chat(user, "The sludge does not respond to your attempt to awake it. Perhaps you should try again later.") + +/obj/item/antag_spawner/morph/spawn_antag(client/C, turf/T, type = "", mob/user) + var/mob/living/simple_animal/hostile/morph/M = new /mob/living/simple_animal/hostile/morph(pick(xeno_spawn)) + M.key = C.key + M.mind.assigned_role = SPECIAL_ROLE_MORPH + M.mind.special_role = SPECIAL_ROLE_MORPH + to_chat(M, M.playstyle_string) + ticker.mode.traitors += M.mind + var/datum/objective/assassinate/KillDaWiz = new /datum/objective/assassinate + KillDaWiz.owner = M.mind + KillDaWiz.target = user.mind + KillDaWiz.explanation_text = "[objective_verb] [user.real_name], the one who was foolish enough to awake you." + M.mind.objectives += KillDaWiz + var/datum/objective/KillDaCrew = new /datum/objective + KillDaCrew.owner = M.mind + KillDaCrew.explanation_text = "[objective_verb] everyone and everything else while you're at it." + M.mind.objectives += KillDaCrew + to_chat(M, "Objective #[1]: [KillDaWiz.explanation_text]") + to_chat(M, "Objective #[2]: [KillDaCrew.explanation_text]") + M << 'sound/magic/mutate.ogg' diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 6228df02af3..addc6f847ab 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -20,17 +20,17 @@ /obj/item/assembly/signaler/New() ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/item/assembly/signaler/Initialize() ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) /obj/item/assembly/signaler/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() @@ -151,13 +151,13 @@ return TRUE /obj/item/assembly/signaler/proc/set_frequency(new_frequency) - if(!radio_controller) + if(!SSradio) sleep(20) - if(!radio_controller) + if(!SSradio) return - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT) // Embedded signaller used in anomalies. /obj/item/assembly/signaler/anomaly diff --git a/code/modules/buildmode/submodes/link.dm b/code/modules/buildmode/submodes/link.dm index 608bea17833..136ffad6433 100644 --- a/code/modules/buildmode/submodes/link.dm +++ b/code/modules/buildmode/submodes/link.dm @@ -46,17 +46,17 @@ if(!M.id || M.id == "") M.id = input(user, "Please select an ID for the button", "Buildmode", "") if(!M.id || M.id == "") - goto(line_jump) + goto line_jump if(P.id_tag == M.id && P.id_tag && P.id_tag != "") P.id_tag = null to_chat(user, "[P] unlinked.") - goto(line_jump) + goto line_jump if(!M.normaldoorcontrol) if(link_lines.len && alert(user, "Warning: This will disable links to connected pod doors. Continue?", "Buildmode", "Yes", "No") == "No") - goto(line_jump) + goto line_jump M.normaldoorcontrol = 1 if(P.id_tag && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No") - goto(line_jump) + goto line_jump P.id_tag = M.id if(istype(link_obj, /obj/machinery/door_control) && istype(object, /obj/machinery/door/poddoor)) var/obj/machinery/door_control/M = link_obj @@ -64,21 +64,21 @@ if(!M.id || M.id == "") M.id = input(user, "Please select an ID for the button", "Buildmode", "") if(!M.id || M.id == "") - goto(line_jump) + goto line_jump if(P.id_tag == M.id && P.id_tag && P.id_tag != "") P.id_tag = null to_chat(user, "[P] unlinked.") - goto(line_jump) + goto line_jump if(M.normaldoorcontrol) if(link_lines.len && alert(user, "Warning: This will disable links to connected airlocks. Continue?", "Buildmode", "Yes", "No") == "No") - goto(line_jump) + goto line_jump M.normaldoorcontrol = 0 if(!M.id || M.id == "") M.id = input(user, "Please select an ID for the button", "Buildmode", "") if(!M.id || M.id == "") - goto(line_jump) + goto line_jump if(P.id_tag && P.id_tag != 1 && alert(user, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No") - goto(line_jump) + goto line_jump P.id_tag = M.id line_jump // For the goto diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index c88347a305b..00900fe5fd1 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -19,6 +19,8 @@ var/area = null var/time_died_as_mouse = null //when the client last died as a mouse + var/typing = FALSE // Prevents typing window stacking + var/adminhelped = 0 var/gc_destroyed //Time when this object was destroyed. @@ -65,25 +67,6 @@ // Set on login. var/datum/media_manager/media = null - ///////////////////////////////////////////////////////////////////// - //adv. hotkey mode vars, code using them in /interface/interface.dm// - ///////////////////////////////////////////////////////////////////// - - var/hotkeytype = "QWERTY" //what set of hotkeys is in use(defaulting to QWERTY because I can't be bothered to make this save on SQL) - var/hotkeyon = 0 //is the hotkey on? - - var/hotkeylist = list( //list defining hotkey types, look at lists in place for structure if adding any if the future - "QWERTY" = list( - "on" = "hotkeymode", - "off" = "macro"), - "AZERTY" = list( - "on" = "AZERTYon", - "off" = "AZERTYoff"), - "Cyborg" = list( - "on" = "borghotkeymode", - "off" = "borgmacro") - ) - var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index ac9a88aaa08..a6216c87b1a 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -78,6 +78,8 @@ C = M.client if(!C) // Might be a stealthmin ID, so pass it in straight C = href_list["priv_msg"] + else if(C.UID() != href_list["priv_msg"]) + C = null // 404 client not found. Let cmd_admin_pm handle the error cmd_admin_pm(C, null, href_list["type"]) return diff --git a/code/modules/client/preference/loadout/loadout_suit.dm b/code/modules/client/preference/loadout/loadout_suit.dm index ae43a10ee89..3d6b5ded994 100644 --- a/code/modules/client/preference/loadout/loadout_suit.dm +++ b/code/modules/client/preference/loadout/loadout_suit.dm @@ -158,3 +158,46 @@ /datum/gear/suit/purplesuit display_name = "suit jacket, purple" path = /obj/item/clothing/suit/storage/lawyer/purpjacket + +//Mantles! +/datum/gear/suit/mantle + display_name = "mantle" + path = /obj/item/clothing/suit/mantle + +/datum/gear/suit/old_scarf + display_name = "old scarf" + path = /obj/item/clothing/suit/mantle/old + +/datum/gear/suit/regal_shawl + display_name = "regal shawl" + path = /obj/item/clothing/suit/mantle/regal + +/datum/gear/suit/captain_cloak + display_name = "mantle, captain" + path = /obj/item/clothing/suit/mantle/armor/captain + allowed_roles = list("Captain") + +/datum/gear/suit/ce_mantle + display_name = "mantle, chief engineer" + path = /obj/item/clothing/suit/mantle/chief_engineer + allowed_roles = list("Chief Engineer") + +/datum/gear/suit/cmo_mantle + display_name = "mantle, chief medical officer" + path = /obj/item/clothing/suit/mantle/labcoat/chief_medical_officer + allowed_roles = list("Chief Medical Officer") + +/datum/gear/suit/armored_shawl + display_name = "mantle, head of security" + path = /obj/item/clothing/suit/mantle/armor + allowed_roles = list("Head of Security") + +/datum/gear/suit/hop_shawl + display_name = "mantle, head of personnel" + path = /obj/item/clothing/suit/mantle/armor/head_of_personnel + allowed_roles = list("Head of Personnel") + +/datum/gear/suit/rd_mantle + display_name = "mantle, research director" + path = /obj/item/clothing/suit/mantle/labcoat + allowed_roles = list("Research Director") diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index caf98b866cc..22894aaa691 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -576,7 +576,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts /datum/preferences/proc/SetChoices(mob/user, limit = 13, list/splitJobs = list("Civilian","Research Director","AI","Bartender"), width = 760, height = 790) - if(!job_master) + if(!SSjobs) return //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. @@ -597,8 +597,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. var/datum/job/lastJob - if(!job_master) return - for(var/datum/job/job in job_master.occupations) + if(!SSjobs) + return + for(var/datum/job/job in SSjobs.occupations) if(job.admin_only) continue @@ -802,7 +803,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 0 /datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl) - var/datum/job/job = job_master.GetJob(role) + var/datum/job/job = SSjobs.GetJob(role) if(!job) user << browse(null, "window=mob_occupation") @@ -908,7 +909,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts player_alt_titles[job.title] = new_title /datum/preferences/proc/SetJob(mob/user, role) - var/datum/job/job = job_master.GetJob(role) + var/datum/job/job = SSjobs.GetJob(role) if(!job) user << browse(null, "window=mob_occupation") ShowChoices(user) diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 6800a63f669..b355d921016 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -55,7 +55,7 @@ ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style)) default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot)) - toggles = sanitize_integer(toggles, 0, 524287, initial(toggles)) + toggles = sanitize_integer(toggles, 0, 2097151, initial(toggles)) sound = sanitize_integer(sound, 0, 65535, initial(sound)) UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color)) UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha)) diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index 2899432501a..703de37468e 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -231,3 +231,15 @@ else to_chat(usr, "You have enabled karma gains.") return + +/client/verb/toggle_popup_limiter() + set name = "Toggle Text Popup Limiter" + set category = "Preferences" + set desc = "Will let you limit the text input popups to one at a time." + prefs.toggles ^= TYPING_ONCE + prefs.save_preferences(src) + if(prefs.toggles & TYPING_ONCE) + to_chat(usr, "You have enabled text popup limiting.") + else + to_chat(usr, "You have disabled text popup limiting.") + return diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 35c5243de64..b527bb2717d 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -532,6 +532,10 @@ actions_types = list(/datum/action/item_action/toggle) up = 0 tint = 0 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/tajblind/eng name = "industrial veil" diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index fb4f3736d6c..d778ea5e63a 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -165,6 +165,10 @@ flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/hud/security/tajblind/attack_self() toggle_veil() @@ -177,6 +181,10 @@ flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/hud/health/tajblind/attack_self() toggle_veil() diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index f7d8fe3ee38..7a65d579b8e 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -12,6 +12,9 @@ description_antag = "These are a pair of power gloves, and can be used to fire bolts of electricity while standing over powered power cables." var/old_mclick_override var/datum/middleClickOverride/power_gloves/mclick_override = new /datum/middleClickOverride/power_gloves + var/last_shocked = 0 + var/shock_delay = 40 + var/unlimited_power = FALSE // Does this really need explanation? /obj/item/clothing/gloves/color/yellow/power/equipped(mob/user, slot) if(!ishuman(user)) @@ -21,7 +24,10 @@ if(H.middleClickOverride) old_mclick_override = H.middleClickOverride H.middleClickOverride = mclick_override - to_chat(H, "You feel electricity begin to build up in [src].") + if(!unlimited_power) + to_chat(H, "You feel electricity begin to build up in [src].") + else + to_chat(H, "You feel like you have UNLIMITED POWER!!") /obj/item/clothing/gloves/color/yellow/power/dropped(mob/user, slot) if(!ishuman(user)) @@ -34,6 +40,12 @@ else H.middleClickOverride = null +/obj/item/clothing/gloves/color/yellow/power/unlimited + name = "UNLIMITED POWER gloves" + desc = "These gloves possess UNLIMITED POWER." + shock_delay = 0 + unlimited_power = TRUE + /obj/item/clothing/gloves/color/yellow/fake desc = "These gloves will protect the wearer from electric shock. They don't feel like rubber..." siemens_coefficient = 1 diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index b6179258d9e..4a51349e165 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -16,25 +16,39 @@ "Grey" = 'icons/mob/species/grey/head.dmi' ) -/obj/item/clothing/head/hardhat/attack_self(mob/user) +/obj/item/clothing/head/hardhat/attack_self(mob/living/user) + toggle_helmet_light(user) + +/obj/item/clothing/head/hardhat/proc/toggle_helmet_light(mob/living/user) on = !on + if(on) + turn_on(user) + else + turn_off(user) + update_icon() + +/obj/item/clothing/head/hardhat/update_icon() icon_state = "hardhat[on]_[item_color]" item_state = "hardhat[on]_[item_color]" - if(on) - set_light(brightness_on) - else - set_light(0) - + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + H.update_inv_head() for(var/X in actions) var/datum/action/A = X A.UpdateButtonIcon() + ..() -/obj/item/clothing/head/hardhat/extinguish_light() +/obj/item/clothing/head/hardhat/proc/turn_on(mob/user) + set_light(brightness_on) + +/obj/item/clothing/head/hardhat/proc/turn_off(mob/user) + set_light(0) + +/obj/item/clothing/head/hardhat/extinguish_light(mob/living/user) if(on) on = FALSE - set_light(0) - icon_state = "hardhat0_[item_color]" - item_state = "hardhat0_[item_color]" + turn_off(user) + update_icon() visible_message("[src]'s light fades and turns off.") /obj/item/clothing/head/hardhat/orange @@ -78,7 +92,7 @@ flags = STOPSPRESSUREDMAGE flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE heat_protection = HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT cold_protection = HEAD min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT species_fit = list("Grey") diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 77fcd03c7df..231a353e153 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -99,12 +99,13 @@ ) /obj/item/clothing/mask/muzzle/tapegag/dropped(mob/user) - var/obj/item/trash/tapetrash/TT = new(drop_location(src)) + var/obj/item/trash/tapetrash/TT = new transfer_fingerprints_to(TT) user.transfer_fingerprints_to(TT) + user.put_in_active_hand(TT) playsound(src, 'sound/items/poster_ripped.ogg', 40, 1) - ..() user.emote("scream") + ..() /obj/item/clothing/mask/muzzle/safety name = "safety muzzle" @@ -491,5 +492,6 @@ /obj/item/clothing/mask/cursedclown/suicide_act(mob/user) user.visible_message("[user] gazes into the eyes of [src]. [src] gazes back!") spawn(10) - user.gib() - return BRUTELOSS + if(user) + user.gib() + return OBLITERATION diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 2fbf38a7e07..1131f1ee648 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -58,7 +58,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/ert/commander/gamma name = "elite emergency response team commander helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammacommander" item_color = "gammacommander" species_fit = null @@ -71,7 +71,7 @@ /obj/item/clothing/suit/space/hardsuit/ert/commander/gamma name = "elite emergency response team commander suit" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gcommander" species_fit = null @@ -85,7 +85,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/ert/security/gamma name = "elite emergency response team security helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammasecurity" item_color = "gammasecurity" species_fit = null @@ -98,7 +98,7 @@ /obj/item/clothing/suit/space/hardsuit/ert/security/gamma name = "elite emergency response team security suit" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gsecurity" species_fit = null @@ -113,7 +113,7 @@ //Engineer /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer/gamma name = "elite emergency response team engineer helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammaengineer" item_color = "gammaengineer" species_fit = null @@ -126,7 +126,7 @@ /obj/item/clothing/suit/space/hardsuit/ert/engineer/gamma name = "elite emergency response team engineer suit" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gengineer" species_fit = null @@ -139,7 +139,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/ert/medical/gamma name = "elite emergency response team medical helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammamedical" item_color = "gammamedical" species_fit = null @@ -151,7 +151,7 @@ /obj/item/clothing/suit/space/hardsuit/ert/medical/gamma name = "elite emergency response team medical suit" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gmedical" species_fit = null @@ -164,7 +164,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/ert/janitor/gamma name = "elite emergency response team janitor helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "hardsuit0-gammajanitor" item_color = "gammajanitor" species_fit = null @@ -176,7 +176,7 @@ /obj/item/clothing/suit/space/hardsuit/ert/janitor/gamma name = "elite emergency response team janitor suit" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT icon_state = "ert_gjanitor" species_fit = null @@ -186,7 +186,7 @@ desc = "A helmet worn by those who deal with paranormal threats for a living." icon_state = "hardsuit0-ert_paranormal" item_color = "ert_paranormal" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null actions_types = list() has_camera = 0 @@ -195,7 +195,7 @@ name = "paranormal response team suit" desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats." icon_state = "hardsuit-paranormal" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null actions_types = list() diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 1d19a145af8..382ff910277 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -291,7 +291,7 @@ item_color = "white" armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90) heat_protection = HEAD //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT /obj/item/clothing/suit/space/hardsuit/elite icon_state = "hardsuit-white" @@ -300,7 +300,7 @@ item_state = "ce_hardsuit" armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 90) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //Mining hardsuit /obj/item/clothing/head/helmet/space/hardsuit/mining @@ -436,7 +436,7 @@ item_color = "syndielite" armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70) heat_protection = HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/attack_self(mob/user) @@ -455,7 +455,7 @@ item_color = "syndielite" armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null /obj/item/clothing/suit/space/hardsuit/syndi/elite/attack_self(mob/user) @@ -497,7 +497,7 @@ unacidable = TRUE //No longer shall our kind be foiled by lone chemists with spray bottles! armor = list(melee = 40, bullet = 40, laser = 40, energy = 20, bomb = 35, bio = 100, rad = 50) heat_protection = HEAD //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT species_fit = list("Grey") sprite_sheets = list( "Grey" = 'icons/mob/species/grey/helmet.dmi' @@ -514,7 +514,7 @@ armor = list(melee = 40, bullet = 40, laser = 40, energy = 20, bomb = 35, bio = 100, rad = 50) allowed = list(/obj/item/teleportation_scroll,/obj/item/tank) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT sprite_sheets = null magical = TRUE @@ -565,7 +565,7 @@ item_color = "atmos" armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) heat_protection = HEAD //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT /obj/item/clothing/suit/space/hardsuit/atmos desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding." @@ -574,7 +574,7 @@ item_state = "atmos_hardsuit" armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //Singuloth armor /obj/item/clothing/head/helmet/space/hardsuit/singuloth diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index cbf7a0a0910..8a79b192d0c 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -44,7 +44,7 @@ icon_state = "deathsquad" item_state = "deathsquad" armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 vision_flags = SEE_MOBS helmet_goggles_invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these @@ -58,7 +58,7 @@ item_state = "swat_suit" allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/kitchen/knife/combat) armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 strip_delay = 130 diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 02742940456..57588f29d62 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -112,14 +112,14 @@ name = "plasmaman atmospheric suit" icon_state = "plasmamanAtmos_suit" armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT /obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech name = "plasmaman atmospheric helmet" icon_state = "plasmamanAtmos_helmet0" base_state = "plasmamanAtmos_helmet" armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0) - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT flash_protect = 2 /obj/item/clothing/suit/space/eva/plasmaman/engineer @@ -137,14 +137,14 @@ /obj/item/clothing/suit/space/eva/plasmaman/engineer/ce name = "plasmaman chief engineer suit" icon_state = "plasmaman_CE" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT /obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/ce name = "plasmaman chief engineer helmet" icon_state = "plasmaman_CE_helmet0" base_state = "plasmaman_CE_helmet" - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT flash_protect = 2 //SERVICE diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index a138f71eec7..5723cdff52c 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -75,7 +75,7 @@ obj/item/clothing/head/helmet/space/syndicate/black/strike name = "Syndicate Strike Team commando helmet" desc = "A heavily armored black helmet that is only given to high-ranking Syndicate operatives." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) //Matches DS gear. - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 /obj/item/clothing/suit/space/syndicate/black @@ -87,7 +87,7 @@ obj/item/clothing/suit/space/syndicate/black/strike name = "Syndicate Strike Team commando space suit" desc = "A heavily armored, black space suit that is only given to high-ranking Syndicate operatives." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) //Matches DS gear. - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 //Black-green syndicate space suit @@ -148,7 +148,7 @@ obj/item/clothing/head/helmet/space/syndicate/black/red/strike name = "Syndicate Strike Team leader helmet" desc = "A heavily armored, black and red space helmet that is only given to elite Syndicate operatives, it looks particularly menacing." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) //Matches DS gear. - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 /obj/item/clothing/suit/space/syndicate/black/red @@ -160,7 +160,7 @@ obj/item/clothing/suit/space/syndicate/black/red/strike name = "Syndicate Strike Team leader space suit" desc = "A heavily armored, black and red space suit that is only given to elite Syndicate operatives, it looks particularly menacing." armor = list(melee = 80, bullet = 80, laser = 50, energy = 50, bomb = 100, bio = 100, rad = 100) //Matches DS gear. - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT unacidable = 1 diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 3b59e5e2d16..2d20a1d2937 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -59,7 +59,6 @@ "Vox" = 'icons/mob/species/vox/suit.dmi' ) - /obj/item/clothing/suit/captunic/capjacket name = "captain's uniform jacket" desc = "A less formal jacket for everyday captain use." @@ -72,6 +71,13 @@ "Vox" = 'icons/mob/species/vox/suit.dmi' ) +/obj/item/clothing/suit/mantle/armor/captain + name = "captain's cloak" + desc = "An armor-plated piece of fashion for the ruling elite. Protect your upper half in style." + icon_state = "capmantle" + item_state = "capmantle" + armor = list(melee = 50, bullet = 40, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + //Chaplain /obj/item/clothing/suit/hooded/chaplain_hoodie name = "chaplain hoodie" @@ -151,6 +157,21 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO allowed = list(/obj/item/kitchen/knife) +//Chief Engineer +/obj/item/clothing/suit/mantle/chief_engineer + name = "chief engineer's mantle" + desc = "A slick, authoritative cloak designed for the Chief Engineer." + icon_state = "cemantle" + item_state = "cemantle" + allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd) + +//Chief Medical Officer +/obj/item/clothing/suit/mantle/labcoat/chief_medical_officer + name = "chief medical officer's mantle" + desc = "An absorbent, clean cover found on the shoulders of the Chief Medical Officer." + icon_state = "cmomantle" + item_state = "cmomantle" + //Detective /obj/item/clothing/suit/storage/det_suit name = "coat" @@ -159,7 +180,7 @@ item_state = "det_suit" blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/reagent_containers/spray/pepper,/obj/item/flashlight,/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/detective_scanner,/obj/item/taperecorder) + allowed = list(/obj/item/tank/emergency_oxygen, /obj/item/reagent_containers/spray/pepper, /obj/item/flashlight, /obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/detective_scanner, /obj/item/taperecorder) armor = list(melee = 25, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS @@ -259,6 +280,29 @@ blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|ARMS +//Head of Security +/obj/item/clothing/suit/mantle/armor + name = "armored shawl" + desc = "A reinforced shawl, worn by the Head of Security. Do you dare take up their mantle?" + icon_state = "hosmantle" + item_state = "hosmantle" + allowed = list(/obj/item/gun/energy, /obj/item/reagent_containers/spray/pepper, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/flashlight/seclite, /obj/item/melee/classic_baton/telescopic, /obj/item/kitchen/knife/combat) + armor = list(melee = 30, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0) + min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT + heat_protection = UPPER_TORSO|ARMS + max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + strip_delay = 60 + put_on_delay = 40 + burn_state = FIRE_PROOF + +//Head of Personnel +/obj/item/clothing/suit/mantle/armor/head_of_personnel + name = "head of personnel's shawl" + desc = "An armored shawl for the head of personnel. It's remarkably well kept." + icon_state = "hopmantle" + item_state = "hopmantle" + armor = list(melee = 25, bullet = 15, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) + //Internal Affairs /obj/item/clothing/suit/storage/internalaffairs name = "\improper Internal Affairs jacket" @@ -320,3 +364,12 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) + +//Research Director +/obj/item/clothing/suit/mantle/labcoat + name = "research director's mantle" + desc = "A tweed mantle, worn by the Research Director. Smells like science." + icon_state = "rdmantle" + item_state = "rdmantle" + allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/food/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/rad_laser) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 0) \ No newline at end of file diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 9ce1953379b..3499bce8e49 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -875,7 +875,7 @@ cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = UPPER_TORSO | LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT slowdown = -10 siemens_coefficient = 0 var/on = 0 @@ -972,3 +972,26 @@ name = "ladies red victorian coat" icon_state = "ladiesredvictoriancoat" item_state = "ladiesredvictoriancoat" + +//Mantles! +/obj/item/clothing/suit/mantle + name = "mantle" + desc = "A heavy quilted mantle, for keeping your shoulders warm and stylish." + icon_state = "mantle" + item_state = "mantle" + body_parts_covered = UPPER_TORSO|ARMS + cold_protection = UPPER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + +/obj/item/clothing/suit/mantle/regal + name = "regal shawl" + desc = "A fancy shawl for nobility, made from high quality materials." + icon_state = "regal_mantle" + item_state = "regal_mantle" + +/obj/item/clothing/suit/mantle/old + name = "old wrap" + desc = "A tattered fabric wrap, faded over the years. Smells faintly of cigars." + icon_state = "old_mantle" + item_state = "old_mantle" + diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 7f1ebfc101a..267a3c86802 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -51,7 +51,7 @@ desc = "An expensive firesuit that protects against even the most deadly of station fires. Designed to protect even if the wearer is set aflame." icon_state = "atmos_firesuit" item_state = "firesuit_atmos" - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 7147b64349c..6ad3bd70d55 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -204,7 +204,7 @@ cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | HEAD min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = UPPER_TORSO | LOWER_TORSO|LEGS|FEET|ARMS|HANDS | HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT slowdown = -10 siemens_coefficient = 0 burn_state = LAVA_PROOF diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 198a3e46de9..a6da9d4391e 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -16,4 +16,11 @@ icon_state = "tactifool" item_state = "bl_suit" item_color = "tactifool" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) \ No newline at end of file + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/under/syndicate/sniper + name = "Tactical turtleneck suit" + desc = "A double seamed tactical turtleneck disguised as a civilian grade silk suit. Intended for the most formal operator. The collar is really sharp." + icon_state = "really_black_suit" + item_state = "bl_suit" + item_color = "black_suit" \ No newline at end of file diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 236c9c81f6c..4aa89dcf18f 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -154,7 +154,7 @@ /obj/item/fluff/rsik_katana/suicide_act(mob/user) user.visible_message("[user] tries to stab [src] into [user.p_their()] stomach! Except [src] shatters! [user.p_they(TRUE)] look[user.p_s()] as if [user.p_they()] might die from the shame.") - return(BRUTELOSS) + return BRUTELOSS /obj/item/crowbar/fluff/zelda_creedy_1 // Zomgponies: Griffin Rowley name = "Zelda's Crowbar" diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 7ea71547123..6f23bbc5fcd 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -9,7 +9,7 @@ var/turf/T = pick(blobstart) if(!T) return kill() - var/list/candidates = pollCandidates("Do you want to play as a blob?", ROLE_BLOB, 1) + var/list/candidates = pollCandidates("Do you want to play as a blob infested mouse?", ROLE_BLOB, 1) if(!candidates.len) return kill() var/list/vents = list() diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 8c099f22a91..d8d1f46ad9b 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -1,12 +1,18 @@ /datum/event/grid_check //NOTE: Times are measured in master controller ticks! announceWhen = 5 - + /datum/event/grid_check/setup() endWhen = rand(30,120) /datum/event/grid_check/start() power_failure(0) - + var/sound/S = sound('sound/effects/powerloss.ogg') + for(var/mob/living/M in GLOB.player_list) + var/turf/T = get_turf(M) + if(!M.client || !is_station_level(T.z)) + continue + SEND_SOUND(M, S) + /datum/event/grid_check/announce() event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') diff --git a/code/modules/examine/descriptions/weapons.dm b/code/modules/examine/descriptions/weapons.dm index 98f60d01ac4..286391f1387 100644 --- a/code/modules/examine/descriptions/weapons.dm +++ b/code/modules/examine/descriptions/weapons.dm @@ -55,6 +55,11 @@ then click where you want to fire. After firing, you will need to pump the gun, by clicking on the gun in your hand. To reload, load more shotgun \ shells into the gun." +/obj/item/toy/russian_revolver/trick_revolver //oh no + description_info = "This is a ballistic weapon. To fire the weapon, have your gun mode set to 'fire', \ + then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropriate ammo. The description \ + will tell you what caliber you need." + //******* //*Melee* //******* diff --git a/code/modules/examine/examine.dm b/code/modules/examine/examine.dm index 0956877d202..f39cb562ec8 100644 --- a/code/modules/examine/examine.dm +++ b/code/modules/examine/examine.dm @@ -60,12 +60,3 @@ stat(null,"[description_holders["fluff"]]") //Yellow, fluff-related text. if(description_holders["antag"]) stat(null,"[description_holders["antag"]]") //Red, malicious antag-related text - -//override examinate verb to update description holders when things are examined -/mob/examinate(atom/A as mob|obj|turf in view()) - if(..()) - return 1 - - var/is_antag = (isAntag(src) || isobserver(src)) //ghosts don't have minds - if(client) - client.update_description_holders(A, is_antag) diff --git a/code/modules/fish/fish_items.dm b/code/modules/fish/fish_items.dm index 63a4b668930..a0882ae5df8 100644 --- a/code/modules/fish/fish_items.dm +++ b/code/modules/fish/fish_items.dm @@ -25,9 +25,9 @@ throw_speed = 3 throw_range = 7 - suicide_act(mob/user) //"A tiny net is a death sentence: it's a net and it's tiny!" https://www.youtube.com/watch?v=FCI9Y4VGCVw - to_chat(viewers(user), "[user] places the [src.name] on top of [user.p_their()] head, [user.p_their()] fingers tangled in the netting! It looks like [user.p_theyre()] trying to commit suicide.") - return(OXYLOSS) +/obj/item/fish_net/suicide_act(mob/user) //"A tiny net is a death sentence: it's a net and it's tiny!" https://www.youtube.com/watch?v=FCI9Y4VGCVw + to_chat(viewers(user), "[user] places the [src.name] on top of [user.p_their()] head, [user.p_their()] fingers tangled in the netting! It looks like [user.p_theyre()] trying to commit suicide.") + return OXYLOSS /obj/item/fishfood name = "fish food can" @@ -51,9 +51,9 @@ throw_range = 7 attack_verb = list("scrubbed", "brushed", "scraped") - suicide_act(mob/user) - to_chat(viewers(user), "[user] is vigorously scrubbing [user.p_them()]self raw with the [name]! It looks like [user.p_theyre()] trying to commit suicide.") - return(BRUTELOSS|FIRELOSS) +/obj/item/tank_brush/suicide_act(mob/user) + to_chat(viewers(user), "[user] is vigorously scrubbing [user.p_them()]self raw with the [name]! It looks like [user.p_theyre()] trying to commit suicide.") + return BRUTELOSS|FIRELOSS ////////////////////////////////////////////// // Fish Items // diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 7dcb5301d43..855ac60666b 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -738,7 +738,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_ for(var/mob/living/carbon/human/H in GLOB.living_mob_list) humans += H person = pick(humans) - target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ") + target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ") qdel(src) /obj/effect/hallucination/message diff --git a/code/modules/flufftext/TextFilters.dm b/code/modules/flufftext/TextFilters.dm index 7ff5a2fd0a5..02a02a6f5b2 100644 --- a/code/modules/flufftext/TextFilters.dm +++ b/code/modules/flufftext/TextFilters.dm @@ -64,9 +64,8 @@ proc/Ellipsis(original_msg, chance = 50) if(chance <= 0) return "..." if(chance >= 100) return original_msg - var/list - words = splittext(original_msg," ") - new_words = list() + var/list/words = splittext(original_msg," ") + var/list/new_words = list() var/new_msg = "" diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 52a4a9dcd35..785231a588d 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -11,6 +11,7 @@ possible_transfer_amounts = list(5,10,15,20,25,30,50) volume = 50 burn_state = FIRE_PROOF + antable = FALSE /obj/item/reagent_containers/food/drinks/New() ..() diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index 0ecff55cba0..e931db813cf 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -13,10 +13,42 @@ var/transfer_efficiency = 1.0 var/instant_application = 0 //if we want to bypass the forcedfeed delay var/taste = TRUE//whether you can taste eating from this + var/antable = TRUE // Will ants come near it? + var/ant_location = null + var/ant_timer = null burn_state = FLAMMABLE container_type = INJECTABLE -/obj/item/reagent_containers/food/New() - ..() +/obj/item/reagent_containers/food/Initialize(mapload) + . = ..() pixel_x = rand(-5, 5) //Randomizes postion pixel_y = rand(-5, 5) + if(antable) + ant_location = get_turf(src) + ant_timer = addtimer(CALLBACK(src, .proc/check_for_ants), 3000, TIMER_STOPPABLE) + +/obj/item/reagent_containers/food/Destroy() + ant_location = null + if(ant_timer) + deltimer(ant_timer) + return ..() + +/obj/item/reagent_containers/food/proc/check_for_ants() + if(!antable) + return + var/turf/T = get_turf(src) + if(isturf(loc) && !locate(/obj/structure/table) in T) + if(ant_location == T) + if(prob(15)) + if(!locate(/obj/effect/decal/ants) in T) + new /obj/effect/decal/ants(T) + antable = FALSE + desc += " It appears to be infested with ants. Yuck!" + reagents.add_reagent("ants", 1) // Don't eat things with ants in i you weirdo. + if(ant_timer) + deltimer(ant_timer) + else + ant_location = T + if(ant_timer) + deltimer(ant_timer) + ant_timer = addtimer(CALLBACK(src, .proc/check_for_ants), 3000, TIMER_STOPPABLE) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 64a585e9051..d512e3888a9 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -131,7 +131,7 @@ user.name = newname user.real_name = newname desc = "Salt. From dead crew, presumably." - return (TOXLOSS) + return TOXLOSS /obj/item/reagent_containers/food/condiment/peppermill name = "pepper mill" diff --git a/code/modules/food_and_drinks/food/foods/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm index d06f1eeb77b..9e4407d9602 100644 --- a/code/modules/food_and_drinks/food/foods/seafood.dm +++ b/code/modules/food_and_drinks/food/foods/seafood.dm @@ -97,6 +97,24 @@ bitesize = 3 list_reagents = list("nutriment" = 2) +/obj/item/reagent_containers/food/snacks/shrimp_skewer + name = "shrimp skewer" + desc = "Four shrimp lightly grilled on a skewer. Yummy!" + trash = /obj/item/stack/rods + icon = 'icons/obj/food/seafood.dmi' + icon_state = "shrimpskewer" + bitesize = 3 + list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/fish_skewer + name = "fish skewer" + desc = "A whole fish battered and grilled on a skewer. Hope you're hungry!" + trash = /obj/item/stack/rods + icon = 'icons/obj/food/seafood.dmi' + icon_state = "fishskewer" + bitesize = 3 + list_reagents = list("protein" = 6, "vitamin" = 4) + /obj/item/reagent_containers/food/snacks/sliceable/Ebi_maki name = "ebi makiroll" desc = "A large unsliced roll of Ebi Sushi." diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index c5bcd22a885..edcb85e0d15 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -24,6 +24,18 @@ idle_power_usage = 2 active_power_usage = 500 +/obj/machinery/gibber/suicide_act(mob/user) + if(occupant || locked) + return FALSE + user.visible_message("[user] climbs into [src] and turns it on!") + user.Stun(10) + user.forceMove(src) + occupant = user + update_icon() + feedinTopanim() + addtimer(CALLBACK(src, .proc/startgibbing, user), 33) + return OBLITERATION + /obj/machinery/gibber/Destroy() if(contents.len) for(var/atom/movable/A in contents) @@ -145,7 +157,7 @@ set name = "Empty Gibber" set src in oview(1) - if(usr.stat != CONSCIOUS) + if(usr.incapacitated()) return go_out() diff --git a/code/modules/food_and_drinks/recipes/recipes_grill.dm b/code/modules/food_and_drinks/recipes/recipes_grill.dm index 921c2c86e99..e5c4cb6bce5 100644 --- a/code/modules/food_and_drinks/recipes/recipes_grill.dm +++ b/code/modules/food_and_drinks/recipes/recipes_grill.dm @@ -226,3 +226,22 @@ /obj/item/reagent_containers/food/snacks/catfishmeat, ) result = /obj/item/reagent_containers/food/snacks/sushi_Tai + +/datum/recipe/grill/shrimp_skewer + items = list( + /obj/item/reagent_containers/food/snacks/shrimp, + /obj/item/reagent_containers/food/snacks/shrimp, + /obj/item/reagent_containers/food/snacks/shrimp, + /obj/item/reagent_containers/food/snacks/shrimp, + /obj/item/stack/rods, + ) + result = /obj/item/reagent_containers/food/snacks/shrimp_skewer + +/datum/recipe/grill/fish_skewer + reagents = list("flour" = 10) + items = list( + /obj/item/reagent_containers/food/snacks/salmonmeat, + /obj/item/reagent_containers/food/snacks/salmonmeat, + /obj/item/stack/rods, + ) + result = /obj/item/reagent_containers/food/snacks/fish_skewer \ No newline at end of file diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index 81fbe20e3d4..44c572b34e7 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -133,6 +133,13 @@ ) result = /obj/item/reagent_containers/food/snacks/baseballburger +/datum/recipe/microwave/cheeseburger + items = list( + /obj/item/reagent_containers/food/snacks/monkeyburger, + /obj/item/reagent_containers/food/snacks/cheesewedge, + ) + result = /obj/item/reagent_containers/food/snacks/cheeseburger + /datum/recipe/microwave/hotdog items = list( /obj/item/reagent_containers/food/snacks/bun, diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 7acd3efc961..371822643a1 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -8,35 +8,36 @@ /mob/proc/bee_friendly() - return 0 + return FALSE /mob/living/simple_animal/hostile/poison/bees/bee_friendly() - return 1 + return TRUE /mob/living/simple_animal/bot/bee_friendly() if(paicard) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/diona/bee_friendly() - return 1 + return TRUE /mob/living/carbon/human/bee_friendly() if(isdiona(src)) //bees pollinate plants, duh. - return 1 + return TRUE if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL))) - return 1 - return 0 + return TRUE + return FALSE /obj/structure/beebox name = "apiary" - desc = "Dr Miles Manners is just your average Wasp themed super hero by day, but by night he becomes DR BEES!" + desc = "Dr. Miles Manners is just your average wasp-themed super hero by day, but by night he becomes DR. BEES!" icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "beebox" - anchored = 1 - density = 1 + anchored = TRUE + density = TRUE + max_integrity = 300 var/mob/living/simple_animal/hostile/poison/bees/queen/queen_bee = null var/list/bees = list() //bees owned by the box, not those inside it var/list/honeycombs = list() @@ -44,8 +45,8 @@ var/bee_resources = 0 -/obj/structure/beebox/New() - ..() +/obj/structure/beebox/Initialize(mapload) + . = ..() processing_objects.Add(src) @@ -66,12 +67,11 @@ var/random_reagent = FALSE -/obj/structure/beebox/premade/New() - ..() - +/obj/structure/beebox/premade/Initialize(mapload) + . = ..() var/datum/reagent/R = null if(random_reagent) - R = get_random_reagent_id() + R = GLOB.chemical_reagents_list[get_random_reagent_id()] queen_bee = new(src) queen_bee.beehome = src @@ -83,7 +83,7 @@ honey_frames += HF for(var/i in 1 to get_max_bees()) - var/mob/living/simple_animal/hostile/poison/bees/worker/B = new(src) + var/mob/living/simple_animal/hostile/poison/bees/B = new(src) bees += B B.beehome = src B.assign_reagent(R) @@ -93,7 +93,7 @@ /obj/structure/beebox/process() - if(queen_bee && (!queen_bee.beegent || !queen_bee.beegent.can_synth)) + if(queen_bee) if(bee_resources >= BEE_RESOURCE_HONEYCOMB_COST) if(honeycombs.len < get_max_honeycomb()) bee_resources = max(bee_resources-BEE_RESOURCE_HONEYCOMB_COST, 0) @@ -109,7 +109,7 @@ if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee) if(!freebee) bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0) - var/mob/living/simple_animal/hostile/poison/bees/worker/B = new(src) + var/mob/living/simple_animal/hostile/poison/bees/B = new(get_turf(src)) B.beehome = src B.assign_reagent(queen_bee.beegent) bees += B @@ -152,14 +152,16 @@ if(istype(I, /obj/item/honey_frame)) var/obj/item/honey_frame/HF = I if(honey_frames.len < BEEBOX_MAX_FRAMES) + if(!user.unEquip(HF)) + return visible_message("[user] adds a frame to the apiary.") - user.unEquip(HF) HF.forceMove(src) honey_frames += HF else to_chat(user, "There's no room for anymore frames in the apiary!") + return - if(istype(I, /obj/item/wrench)) + if(iswrench(I)) if(default_unfasten_wrench(user, I, time = 20)) return @@ -169,25 +171,27 @@ return var/obj/item/queen_bee/qb = I - user.unEquip(qb) if(!qb.queen.beegent || (qb.queen.beegent && qb.queen.beegent.can_synth)) + if(!user.unEquip(qb)) + return qb.queen.forceMove(src) bees += qb.queen queen_bee = qb.queen qb.queen = null else visible_message("The [qb] refuses to settle down. Maybe it's something to do with its reagent?") + return if(queen_bee) visible_message("[user] sets [qb] down inside the apiary, making it [user.p_their()] new home.") var/relocated = 0 for(var/b in bees) - var/mob/living/simple_animal/hostile/poison/bees/worker/B = b + var/mob/living/simple_animal/hostile/poison/bees/B = b if(B.reagent_incompatible(queen_bee)) bees -= B B.beehome = null if(B.loc == src) - B.forceMove(get_turf(src)) + B.forceMove(drop_location()) relocated++ if(relocated) to_chat(user, "This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!") @@ -196,6 +200,8 @@ to_chat(user, "The queen bee disappeared! bees disappearing has been in the news lately...") qdel(qb) + return + return ..() /obj/structure/beebox/attack_hand(mob/user) @@ -208,7 +214,7 @@ if(B.isqueen) continue if(B.loc == src) - B.forceMove(get_turf(src)) + B.forceMove(drop_location()) B.target = user bees = TRUE if(bees) @@ -254,3 +260,16 @@ QB.forceMove(get_turf(src)) visible_message("[user] removes the queen from the apiary.") queen_bee = null + +/obj/structure/beebox/deconstruct(disassembled = TRUE) + new /obj/item/stack/sheet/wood(loc, 20) + for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) + if(B.loc == src) + B.forceMove(drop_location()) + for(var/obj/item/honey_frame/HF in honey_frames) + HF.forceMove(drop_location()) + honey_frames -= HF + qdel(src) + +/obj/structure/beebox/unwrenched + anchored = FALSE \ No newline at end of file diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index 4515b3ad75f..dd56ade79be 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -30,13 +30,13 @@ playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) sleep(25) if(!user) - return (OXYLOSS) + return OXYLOSS user.say("BANG!") sleep(25) if(!user) - return (OXYLOSS) + return OXYLOSS user.visible_message("[user] laughs so hard [user.p_they()] begin[user.p_s()] to suffocate!") - return (OXYLOSS) + return OXYLOSS /obj/item/grown/bananapeel seed = /obj/item/seeds/banana @@ -52,7 +52,7 @@ /obj/item/grown/bananapeel/suicide_act(mob/user) user.visible_message("[user] is deliberately slipping on the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS // Mimana - invisible sprites are totally a feature! diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm index eea80e17e60..64b84649770 100644 --- a/code/modules/hydroponics/grown/kudzu.dm +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -24,7 +24,7 @@ /obj/item/seeds/kudzu/suicide_act(mob/user) user.visible_message("[user] swallows the pack of kudzu seeds! It looks like [user.p_theyre()] trying to commit suicide..") plant(user) - return (BRUTELOSS) + return BRUTELOSS /obj/item/seeds/kudzu/proc/plant(mob/user) if(istype(user.loc, /turf/space)) diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 8c4ed2b029c..444939ca861 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -45,7 +45,7 @@ /obj/item/grown/nettle/suicide_act(mob/user) user.visible_message("[user] is eating some of the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") - return (BRUTELOSS|TOXLOSS) + return BRUTELOSS|TOXLOSS /obj/item/grown/nettle/pickup(mob/living/user) ..() @@ -95,7 +95,8 @@ force = round((5 + seed.potency / 2.5), 1) /obj/item/grown/nettle/death/pickup(mob/living/carbon/user) - if(..() && ishuman(user)) // If the pickup succeeded and is humanoid + . = ..() + if(. && ishuman(user)) // If the pickup succeeded and is humanoid var/mob/living/carbon/human/H = user if(!H.gloves && prob(50)) user.Paralyse(5) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index a3453585817..14080c62bba 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -34,7 +34,7 @@ /obj/item/reagent_containers/spray/weedspray/suicide_act(mob/user) user.visible_message("[user] is huffing the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") - return (TOXLOSS) + return TOXLOSS /obj/item/reagent_containers/spray/pestspray // -- Skie desc = "It's some pest eliminator spray! Do not inhale!" @@ -56,7 +56,7 @@ /obj/item/reagent_containers/spray/pestspray/suicide_act(mob/user) user.visible_message("[user] is huffing the [src.name]! It looks like [user.p_theyre()] trying to commit suicide.") - return (TOXLOSS) + return TOXLOSS /obj/item/cultivator name = "cultivator" @@ -91,7 +91,7 @@ /obj/item/hatchet/suicide_act(mob/user) user.visible_message("[user] is chopping at [user.p_them()]self with the [name]! It looks like [user.p_theyre()] trying to commit suicide.") playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/hatchet/unathiknife name = "duelling knife" @@ -126,7 +126,7 @@ if(affecting) affecting.droplimb(1, DROPLIMB_SHARP) playsound(loc, pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg'), 50, 1, -1) - return (BRUTELOSS) + return BRUTELOSS /obj/item/scythe/pre_attackby(atom/A, mob/living/user, params) if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user)) diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 2e95d21e10b..ef450f4a52f 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -234,14 +234,14 @@ /datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) var/power = G.seed.potency*rate if(prob(power)) - C.electrocute_act(round(power), G, 1, 1) + C.electrocute_act(round(power), G, 1, TRUE) /datum/plant_gene/trait/cell_charge/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target) - if(iscarbon(target)) + if(isliving(target)) var/mob/living/carbon/C = target var/power = G.seed.potency*rate if(prob(power)) - C.electrocute_act(round(power), G, 1, 1) + C.electrocute_act(round(power), G, 1, TRUE) /datum/plant_gene/trait/cell_charge/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) if(!G.reagents.total_volume) diff --git a/code/modules/logic/logic_base.dm b/code/modules/logic/logic_base.dm index 519c47c408b..952001e87f7 100644 --- a/code/modules/logic/logic_base.dm +++ b/code/modules/logic/logic_base.dm @@ -42,7 +42,7 @@ if(tamperproof) //doing this during New so we don't have to worry about forgetting to set these vars during editting / defining unacidable = 1 ..() - if(radio_controller) + if(SSradio) set_frequency(frequency) component_parts = list() var/obj/item/circuitboard/logic_gate/LG = new(null) @@ -55,14 +55,14 @@ set_frequency(frequency) /obj/machinery/logic_gate/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_LOGIC) + radio_connection = SSradio.add_object(src, frequency, RADIO_LOGIC) return /obj/machinery/logic_gate/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm index 54f9ac97cd9..b57e7fc4f98 100644 --- a/code/modules/martial_arts/cqc.dm +++ b/code/modules/martial_arts/cqc.dm @@ -1,4 +1,4 @@ -#define SLAM_COMBO "HG" +#define SLAM_COMBO "GH" #define KICK_COMBO "HH" #define RESTRAIN_COMBO "GG" #define PRESSURE_COMBO "DG" @@ -8,15 +8,24 @@ name = "CQC" help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 + var/just_a_cook = FALSE + var/static/list/areas_under_siege = typecacheof(list(/area/crew_quarters/kitchen, + /area/crew_quarters/cafeteria, + /area/crew_quarters/bar)) -/datum/martial_art/cqc/can_use(mob/living/carbon/human/H) - if(istype(H.gloves, /obj/item/clothing/gloves/fingerless/rapid)) - return FALSE - return ..() +/datum/martial_art/cqc/under_siege + name = "Close Quarters Cooking" + just_a_cook = TRUE /datum/martial_art/cqc/proc/drop_restraining() restraining = FALSE +/datum/martial_art/cqc/can_use(mob/living/carbon/human/H) + var/area/A = get_area(H) + if(just_a_cook && !(is_type_in_typecache(A, areas_under_siege))) + return FALSE + return ..() + /datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE @@ -44,22 +53,23 @@ /datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE - if(!D.stat || !D.weakened) + if(!D.weakened && !D.resting && !D.lying) D.visible_message("[A] slams [D] into the ground!", \ "[A] slams you into the ground!") playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1) D.apply_damage(10, BRUTE) D.Weaken(6) add_attack_logs(A, D, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL) - else //if target can't be slammed, do a regular grab attack then clear the streak - streak = "" - grab_act(A, D) - streak = "" + return TRUE + streak = "" + harm_act(A, D) + streak = "" return TRUE /datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE + var/success = FALSE if(!D.stat || !D.weakened) D.visible_message("[A] kicks [D] back!", \ "[A] kicks you back!") @@ -68,17 +78,20 @@ D.throw_at(throw_target, 1, 14, A) D.apply_damage(10, BRUTE) add_attack_logs(A, D, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) - if(D.weakened && !D.stat) - D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \ - "[A] kicks your head, knocking you out!") - playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) - D.SetSleeping(15) - D.adjustBrainLoss(15, 150) - add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) - else //if target can't be kicked, do a regular harm attack then clear the streak - streak = "" - harm_act(A, D) - streak = "" + success = TRUE + if(D.weakened && !D.stat) + D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \ + "[A] kicks your head, knocking you out!") + playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) + D.SetSleeping(15) + D.adjustBrainLoss(15) + add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) + success = TRUE + if(success) + return TRUE + streak = "" + harm_act(A, D) + streak = "" return TRUE /datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -103,6 +116,10 @@ restraining = TRUE addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) add_attack_logs(A, D, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL) + return TRUE + streak = "" + harm_act(A, D) + streak = "" return TRUE /datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -118,10 +135,10 @@ D.adjustStaminaLoss(50) D.apply_damage(25, BRUTE) add_attack_logs(A, D, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL) - else //if target can't be hit, do a regular harm attack then clear the streak - streak = "" - harm_act(A, D) - streak = "" + return TRUE + streak = "" + harm_act(A, D) + streak = "" return TRUE /datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -133,6 +150,8 @@ var/obj/item/grab/G = D.grabbedby(A, 1) if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab + add_attack_logs(A, D, "Melee attacked with martial-art [src] : aggressively grabbed", ATKLOG_ALL) + return TRUE /datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) @@ -141,8 +160,9 @@ add_to_streak("H", D) if(check_streak(A, D)) return TRUE + add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL) A.do_attack_animation(D) - var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched") + var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched", "Big Bossed") var/bonus_damage = 13 if(D.weakened || D.resting || D.lying) bonus_damage += 5 @@ -154,7 +174,7 @@ playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) D.visible_message("[A] [picked_hit_type] [D]!", \ "[A] [picked_hit_type] you!") - add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL) + add_attack_logs(A, D, "Melee attacked with martial-art [src] : [picked_hit_type]", ATKLOG_ALL) if(A.resting && !D.stat && !D.weakened) D.visible_message("[A] leg sweeps [D]!", \ "[A] leg sweeps you!") @@ -168,24 +188,36 @@ if(!can_use(A)) return FALSE add_to_streak("D", D) + var/obj/item/I = null if(check_streak(A, D)) return TRUE - if(!restraining) - D.visible_message("[A] strikes [D]'s jaw with their hand!", \ - "[A] strikes your jaw, disorienting you!") - playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - D.Jitter(2) - D.apply_damage(5, BRUTE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarm", ATKLOG_ALL) - if(restraining) + var/obj/item/grab/G = A.get_inactive_hand() + if(restraining && istype(G) && G.affecting == D) D.visible_message("[A] puts [D] into a chokehold!", \ "[A] puts you into a chokehold!") D.SetSleeping(20) restraining = FALSE - add_attack_logs(A, D, "Knocked out with martial-art [src] : Choke hold", ATKLOG_ALL) + if(G.state < GRAB_NECK) + G.state = GRAB_NECK + return TRUE else restraining = FALSE - return FALSE + + if(prob(65)) + if(!D.stat || !D.weakened || !restraining) + I = D.get_active_hand() + D.visible_message("[A] strikes [D]'s jaw with their hand!", \ + "[A] strikes your jaw, disorienting you!") + playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + if(I && D.drop_item()) + A.put_in_hands(I) + D.Jitter(2) + D.apply_damage(5, BRUTE) + else + D.visible_message("[A] attempted to disarm [D]!", "[A] attempted to disarm [D]!") + playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarmed [I ? " grabbing \the [I]" : ""]", ATKLOG_ALL) return TRUE /mob/living/carbon/human/proc/CQC_help() @@ -194,11 +226,10 @@ set category = "CQC" to_chat(usr, "You try to remember some of the basics of CQC.") - to_chat(usr, "Slam: Harm Grab. Slam opponent into the ground, knocking them down.") + to_chat(usr, "Slam: Grab, switch hands, Harm. Slam opponent into the ground, knocking them down.") to_chat(usr, "CQC Kick: Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.") - to_chat(usr, "Restrain: Grab Switch Hand Grab. Locks opponent into a restraining position, stunning them.") - to_chat(usr, "Choke Hold: Restrain Disarm. Knocks out an opponent you have restrained.") + to_chat(usr, "Restrain: Grab, switch hands, Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.") to_chat(usr, "Pressure: Disarm Grab. Decent stamina damage.") to_chat(usr, "Consecutive CQC: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.") - to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter melee attacks done to you.") \ No newline at end of file + to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") \ No newline at end of file diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index aed823b372b..2940e810ade 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -267,7 +267,7 @@ H.Weaken(4) if(H.staminaloss && !H.sleeping) var/total_health = (H.health - H.staminaloss) - if(total_health <= config.health_threshold_crit && !H.stat) + if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat) H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking [H.p_them()] out cold!", \ "[user] knocks you unconscious!") H.SetSleeping(30) diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 311d7387614..c3887fe4660 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -165,7 +165,7 @@ var/mob/living/carbon/human/H = user for(var/obj/item/W in H) H.unEquip(W) - var/datum/job/clown/C = job_master.GetJob("Clown") + var/datum/job/clown/C = SSjobs.GetJob("Clown") C.equip(H) affected_targets.Add(H) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index a5bfcb02e4b..bfeecdef055 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -14,7 +14,3 @@ /mob/camera/experience_pressure_difference() return - -/mob/camera/Login() - ..() - update_interface() diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 0990b085264..b44d8421b80 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -7,5 +7,3 @@ if(GLOB.non_respawnable_keys[ckey]) can_reenter_corpse = 0 GLOB.respawnable_list -= src - - update_interface() \ No newline at end of file diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index e91c79e46c9..dfd4e1e3332 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -26,6 +26,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi var/ghostvision = 1 //is the ghost able to see things humans can't? var/seedarkness = 1 var/data_hud_seen = FALSE //this should one of the defines in __DEFINES/hud.dm + var/ghost_orbit = GHOST_ORBIT_CIRCLE /mob/dead/observer/New(var/mob/body=null, var/flags=1) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF @@ -49,7 +50,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi T = get_turf(body) //Where is the body located? attack_log = body.attack_log //preserve our attack logs by copying them to our ghost - var/mutable_appearance/MA = copy_appearance(body) + var/mutable_appearance/MA = copy_appearance(body) if(body.mind && body.mind.name) MA.name = body.mind.name else if(body.real_name) @@ -139,15 +140,14 @@ Works together with spawning an observer, noted above. var/client/C = U.client for(var/mob/living/carbon/human/target in target_list) C.images += target.hud_list[SPECIALROLE_HUD] - //C.images += target.hud_list[NATIONS_HUD] for(var/mob/living/silicon/target in target_list) C.images += target.hud_list[SPECIALROLE_HUD] - //C.images += target.hud_list[NATIONS_HUD] - return 1 /mob/proc/ghostize(var/flags = GHOST_CAN_REENTER) if(key) + if(player_logged) //if they have disconnected we want to remove their SSD overlay + overlays -= image('icons/effects/effects.dmi', icon_state = "zzz_glow") if(GLOB.non_respawnable_keys[ckey]) flags &= ~GHOST_CAN_REENTER var/mob/dead/observer/ghost = new(src, flags) //Transfer safety to observer spawning proc. @@ -177,30 +177,44 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(P) if(TOO_EARLY_TO_GHOST) warningmsg = "It's too early in the shift to enter cryo" - // If it's not too early, we'll skip straight to ghosting out without penalty else if(suiciding && TOO_EARLY_TO_GHOST) warningmsg = "You have committed suicide too early in the round" else if(stat != DEAD) warningmsg = "You are alive" + if(isAI(src)) + warningmsg = "You are a living AI! You should probably use OOC -> Wipe Core instead." else if(GLOB.non_respawnable_keys[ckey]) warningmsg = "You have lost your right to respawn" - if(!warningmsg) - ghostize(1) - else + if(warningmsg) var/response var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)" response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost") if(response != "Ghost") - return //didn't want to ghost after-all - StartResting() - var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 - ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly. + return + + if(stat == CONSCIOUS) + if(!is_admin_level(z)) + player_ghosted = 1 + if(mind && mind.special_role) + message_admins("[key_name_admin(src)] has ghosted while alive, with special_role: [mind.special_role]") + + if(warningmsg) + // Not respawnable + var/mob/dead/observer/ghost = ghostize(0) // 0 parameter stops them re-entering their body + ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly. + else + // Respawnable + ghostize(1) + + // If mob in morgue tray, update tray var/obj/structure/morgue/Morgue = locate() in M.loc if(istype(M.loc, /obj/structure/morgue)) Morgue = M.loc if(Morgue) Morgue.update() + + // If mob in cryopod, despawn mob if(P) if(!P.control_computer) P.find_control_computer(urgent=1) @@ -208,7 +222,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp P.despawn_occupant() return - /mob/dead/observer/Move(NewLoc, direct) following = null dir = direct @@ -399,8 +412,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/follow(input in getmobs()) set category = "Ghost" - set name = "Follow" // "Haunt" - set desc = "Follow and haunt a mob." + set name = "Orbit" // "Haunt" + set desc = "Follow and orbit a mob." var/target = getmobs()[input] if(!target) return @@ -417,22 +430,37 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(target != src) if(following && following == target) return + + var/icon/I = icon(target.icon,target.icon_state,target.dir) + + var/orbitsize = (I.Width()+I.Height())*0.5 + + if(orbitsize == 0) + orbitsize = 40 + + orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25) + + var/rot_seg + + switch(ghost_orbit) + if(GHOST_ORBIT_TRIANGLE) + rot_seg = 3 + if(GHOST_ORBIT_SQUARE) + rot_seg = 4 + if(GHOST_ORBIT_PENTAGON) + rot_seg = 5 + if(GHOST_ORBIT_HEXAGON) + rot_seg = 6 + else //Circular + rot_seg = 36 //360/10 bby, smooth enough aproximation of a circle + following = target to_chat(src, "Now following [target]") - if(ismob(target)) - forceMove(get_turf(target)) - var/mob/M = target - M.following_mobs += src - else - spawn(0) - while(target && following == target && client) - var/turf/T = get_turf(target) - if(!T) - break - // To stop the ghost flickering. - if(loc != T) - forceMove(T) - sleep(15) + orbit(target,orbitsize, FALSE, 20, rot_seg) + +/mob/dead/observer/orbit() + setDir(2)//reset dir so the right directional sprites show up + return ..() /mob/proc/update_following() . = get_turf(src) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index e53e3c9fd4d..471f82c1511 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -35,7 +35,7 @@ /mob/proc/put_in_l_hand(var/obj/item/W) if(!put_in_hand_check(W)) return 0 - if(!l_hand) + if(!l_hand && has_left_hand()) W.forceMove(src) //TODO: move to equipped? l_hand = W W.layer = 20 //TODO: move to equipped? @@ -51,7 +51,7 @@ /mob/proc/put_in_r_hand(var/obj/item/W) if(!put_in_hand_check(W)) return 0 - if(!r_hand) + if(!r_hand && has_right_hand()) W.forceMove(src) r_hand = W W.layer = 20 diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 8a7c017818a..25b188911ad 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -523,7 +523,9 @@ flags = RESTRICTED | HIVEMIND /datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask) - if(speaker.mind && speaker.mind.special_role) + if(speaker.mind && speaker.mind.special_role == SPECIAL_ROLE_SHADOWLING) + ..(speaker,"[message]", "([speaker.mind.special_role]) [speaker]") + else if(speaker.mind && speaker.mind.special_role) ..(speaker, message, "([speaker.mind.special_role]) [speaker]") else ..(speaker, message) diff --git a/code/modules/mob/living/carbon/_defines.dm b/code/modules/mob/living/carbon/_defines.dm index 483502965da..a5a524f86ed 100644 --- a/code/modules/mob/living/carbon/_defines.dm +++ b/code/modules/mob/living/carbon/_defines.dm @@ -1,6 +1,5 @@ -//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick! -#define HUMAN_MAX_OXYLOSS 3 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. -#define HUMAN_CRIT_MAX_OXYLOSS ( (tickerProcess.getLastTickerTimeDuration()) / 3) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks. +//NOTE: Breathing happens once EVERY OTHER TICK. +#define HUMAN_MAX_OXYLOSS 5 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. #define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point #define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index 6012a8fb7f3..3af2250bbbd 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -46,13 +46,13 @@ if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP SetSilence(0) else //ALIVE. LIGHTS ARE ON - if(health < config.health_threshold_dead || !get_int_organ(/obj/item/organ/internal/brain)) + if(health < HEALTH_THRESHOLD_DEAD && check_death_method() || !get_int_organ(/obj/item/organ/internal/brain)) death() SetSilence(0) return 1 //UNCONSCIOUS. NO-ONE IS HOME - if((getOxyLoss() > 50) || (config.health_threshold_crit >= health)) + if((getOxyLoss() > 50) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method())) if(health <= 20 && prob(1)) emote("gasp") if(!reagents.has_reagent("epinephrine")) diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 44287493718..bdc2ee31f77 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -18,7 +18,7 @@ if(stat == DEAD) //If we mostly took damage from fire - if(fireloss > 125) + if(getFireLoss() > 125) icon_state = "alien[caste]_husked" pixel_y = 0 else diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index a64750ad93d..5ebaaffac0c 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -93,6 +93,9 @@ /mob/living/carbon/alien/larva/show_inv(mob/user as mob) return +/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) + return FALSE + /* Commented out because it's duplicated in life.dm /mob/living/carbon/alien/larva/proc/grow() // Larvae can grow into full fledged Xenos if they survive long enough -- TLE if(icon_state == "larva_l" && !canmove) // This is a shit death check. It is made of shit and death. Fix later. diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index a4b783e08fb..a0668db8327 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -19,7 +19,7 @@ return 1 //UNCONSCIOUS. NO-ONE IS HOME - if( (getOxyLoss() > 25) || (config.health_threshold_crit >= health) ) + if((getOxyLoss() > 25) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method())) //if( health <= 20 && prob(1) ) // spawn(0) // emote("gasp") diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 03675f282e5..087ca959902 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -1,7 +1,7 @@ /obj/item/organ/internal/brain name = "brain" health = 400 //They need to live awhile longer than other organs. - max_damage = 200 + max_damage = 120 icon_state = "brain2" force = 1.0 w_class = WEIGHT_CLASS_SMALL @@ -100,6 +100,19 @@ log_debug("Multibrain shenanigans at ([target.x],[target.y],[target.z]), mob '[target]'") ..(target, special = special) +/obj/item/organ/internal/brain/receive_damage(amount, silent = 0) //brains are special; if they receive damage by other means, we really just want the damage to be passed ot the owner and back onto the brain. + if(owner) + owner.adjustBrainLoss(amount) + +/obj/item/organ/internal/brain/necrotize(update_sprite = TRUE) //Brain also has special handling for when it necrotizes + damage = max_damage + status |= ORGAN_DEAD + processing_objects -= src + if(dead_icon && !is_robotic()) + icon_state = dead_icon + if(owner && vital) + owner.setBrainLoss(120) + /obj/item/organ/internal/brain/prepare_eat() return // Too important to eat. diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 2ac3b3c4d6b..d0cf06f1bf7 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -32,7 +32,7 @@ . = ..() if(.) - if(!container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life))) + if(!container && (health < HEALTH_THRESHOLD_DEAD && check_death_method() || ((world.time - timeofhostdeath) > config.revival_brain_life))) death() return 0 diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm index c294a11c999..6528d9c252e 100644 --- a/code/modules/mob/living/carbon/brain/robotic_brain.dm +++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm @@ -161,7 +161,7 @@ if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) to_chat(O, "You are job banned from this role.") return - to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") + to_chat(O, "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") ghost_volunteers.Add(O) diff --git a/code/modules/mob/living/carbon/brain/update_status.dm b/code/modules/mob/living/carbon/brain/update_status.dm index 431d1eea0c3..6fec51bb07b 100644 --- a/code/modules/mob/living/carbon/brain/update_status.dm +++ b/code/modules/mob/living/carbon/brain/update_status.dm @@ -3,12 +3,12 @@ return // if(health <= min_health) if(stat == DEAD) - if(container && health > config.health_threshold_dead) + if(container && health > HEALTH_THRESHOLD_DEAD) update_revive() create_debug_log("revived, trigger reason: [reason]") return else - if(!container || health <= config.health_threshold_dead) + if(!container || health <= HEALTH_THRESHOLD_DEAD && check_death_method()) // Considered "dead" without any external apparatus death() create_debug_log("died, trigger reason: [reason]") diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index d72e5b6e2af..277bbbd8789 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -134,43 +134,48 @@ M.forceMove(get_turf(src)) visible_message("[M] bursts out of [src]!") -/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0) +/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage) if(status_flags & GODMODE) //godmode - return 0 + return FALSE if(NO_SHOCK in mutations) //shockproof - return 0 + return FALSE if(tesla_shock && tesla_ignore) return FALSE shock_damage *= siemens_coeff - if(shock_damage<1 && !override) - return 0 + if(dna && dna.species) + shock_damage *= dna.species.siemens_coeff + if(shock_damage < 1 && !override) + return FALSE if(reagents.has_reagent("teslium")) shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging! - take_overall_damage(0,shock_damage, TRUE, used_weapon = "Electrocution") - shock_internal_organs(shock_damage) + if(illusion) + adjustStaminaLoss(shock_damage) + else + take_overall_damage(0, shock_damage, TRUE, used_weapon = "Electrocution") + shock_internal_organs(shock_damage) visible_message( - "[src] was shocked by \the [source]!", \ - "You feel a powerful shock coursing through your body!", \ - "You hear a heavy electrical crack." \ - ) + "[src] was shocked by \the [source]!", + "You feel a powerful shock coursing through your body!", + "You hear a heavy electrical crack.") AdjustJitter(1000) //High numbers for violent convulsions do_jitter_animation(jitteriness) AdjustStuttering(2) - if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) + if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun) Stun(2) spawn(20) AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less - if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) + if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun) Stun(3) Weaken(3) if(shock_damage > 200) src.visible_message( - "[src] was arc flashed by the [source]!", \ - "The [source] arc flashes and electrocutes you!", \ - "You hear a lightning-like crack!" \ - ) + "[src] was arc flashed by the [source]!", + "The [source] arc flashes and electrocutes you!", + "You hear a lightning-like crack!") playsound(loc, 'sound/effects/eleczap.ogg', 50, 1, -1) - explosion(src.loc,-1,0,2,2) + explosion(loc, -1, 0, 2, 2) + if(override) return override else @@ -209,7 +214,7 @@ /mob/living/carbon/proc/help_shake_act(mob/living/carbon/M) add_attack_logs(M, src, "Shaked", ATKLOG_ALL) - if(health >= config.health_threshold_crit) + if(health >= HEALTH_THRESHOLD_CRIT) if(src == M && ishuman(src)) var/mob/living/carbon/human/H = src visible_message( \ diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 5d816ed625e..4ecd81e1338 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -22,9 +22,8 @@ var/wetlevel = 0 //how wet the mob is - var/failed_last_breath = FALSE //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks. var/co2overloadtime = null var/dreaming = 0 //How many dream images we have left to send var/nightmare = 0 - blood_volume = BLOOD_VOLUME_NORMAL + blood_volume = BLOOD_VOLUME_NORMAL \ No newline at end of file diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 473715367b4..c0dba9b77e5 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -4,22 +4,15 @@ if(!iscarbon(target)) //something is bypassing the give arguments, no clue what, adding a sanity check JIC to_chat(usr, "Wait a second... \the [target] HAS NO HANDS! AHH!")//cheesy messages ftw + return + if(target.incapacitated() || usr.incapacitated() || target.client == null) return - if(target.stat == 2 || usr.stat == 2|| target.client == null) - return - var/obj/item/I - if(!usr.hand && usr.r_hand == null) - to_chat(usr, " You don't have anything in your right hand to give to [target.name]") - return - if(usr.hand && usr.l_hand == null) - to_chat(usr, " You don't have anything in your left hand to give to [target.name]") - return - if(usr.hand) - I = usr.l_hand - else if(!usr.hand) - I = usr.r_hand + + var/obj/item/I = get_active_hand() + if(!I) + to_chat(usr, " You don't have anything in your hand to give to [target.name]") return if((I.flags & NODROP) || (I.flags & ABSTRACT)) to_chat(usr, "That's not exactly something you can give.") @@ -29,35 +22,30 @@ if("Yes") if(!I) return + if(target.incapacitated() || usr.incapacitated()) + return if(!Adjacent(target)) to_chat(usr, " You need to stay in reaching distance while giving an object.") to_chat(target, " [usr.name] moved too far away.") return - if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I)) + if((I.flags & NODROP) || (I.flags & ABSTRACT)) + to_chat(usr, "[I] stays stuck to your hand when you try to give it!") + to_chat(target, "[I] stays stuck to [usr.name]'s hand when you try to take it!") + return + if(I != get_active_hand()) to_chat(usr, " You need to keep the item in your active hand.") - to_chat(target, " [usr.name] seem to have given up on giving \the [I.name] to you.") + to_chat(target, " [usr.name] seem to have given up on giving [I] to you.") return if(target.r_hand != null && target.l_hand != null) to_chat(target, " Your hands are full.") to_chat(usr, " Their hands are full.") return - else - usr.drop_item() - if(target.r_hand == null) - target.r_hand = I - else - target.l_hand = I - I.loc = target - I.layer = 20 - I.plane = HUD_PLANE + usr.unEquip(I) + target.put_in_hands(I) I.add_fingerprint(target) - src.update_inv_l_hand() - src.update_inv_r_hand() - target.update_inv_l_hand() - target.update_inv_r_hand() - target.visible_message(" [usr.name] handed \the [I.name] to [target.name].") + target.visible_message(" [usr.name] handed [I] to [target.name].") I.on_give(usr, target) if("No") - target.visible_message(" [usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.") + target.visible_message(" [usr.name] tried to hand [I] to [target.name] but [target.name] didn't want it.") else to_chat(usr, " [target.name]'s hands are full.") diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 3e1c874a067..442d7aaf044 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -680,6 +680,14 @@ message = "[src] trembles." m_type = 1 + if("shudder", "shudders") + message = "[src] shudders." + m_type = 1 + + if("bshake", "bshakes") + message = "[src] shakes." + m_type = 1 + if("sneeze", "sneezes") if(miming) message = "[src] sneezes." diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 03726353022..aa714f0d527 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -363,7 +363,7 @@ for(var/datum/data/record/R in data_core.security) if(R.fields["id"] == E.fields["id"]) criminal = R.fields["criminal"] - var/criminal_status = hasHUD(user, "read_only_security") ? "\[[criminal]\]" : "\[[criminal]\]" + var/criminal_status = hasHUD(user, "read_only_security") ? "\[[criminal]\]" : "\[[criminal]\]" msg += "Criminal status: [criminal_status]\n" msg += "Security records: \[View\] \[Add comment\]\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5550378984a..bd5817e8867 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -198,12 +198,6 @@ stat("Total Blood", "[mind.vampire.bloodtotal]") stat("Usable Blood", "[mind.vampire.bloodusable]") - if(mind.nation) - stat("Nation Name", "[mind.nation.current_name ? "[mind.nation.current_name]" : "[mind.nation.default_name]"]") - stat("Nation Leader", "[mind.nation.current_leader ? "[mind.nation.current_leader]" : "None"]") - stat("Nation Heir", "[mind.nation.heir ? "[mind.nation.heir]" : "None"]") - - if(istype(loc, /obj/spacepod)) // Spacdpods! var/obj/spacepod/S = loc stat("Spacepod Charge", "[istype(S.battery) ? "[(S.battery.charge / S.battery.maxcharge) * 100]" : "No cell detected"]") @@ -557,13 +551,8 @@ dna.species.update_sight(src) -//Removed the horrible safety parameter. It was only being used by ninja code anyways. -//Now checks siemens_coefficient of the affected area by default -/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0) - if(status_flags & GODMODE) //godmode - return 0 - if(NO_SHOCK in mutations) //shockproof - return 0 +//Added a safety check in case you want to shock a human mob directly through electrocute_act. +/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) if(tesla_shock) var/total_coeff = 1 if(gloves) @@ -581,20 +570,18 @@ siemens_coeff = 0 else if(!safety) var/gloves_siemens_coeff = 1 - var/species_siemens_coeff = 1 if(gloves) var/obj/item/clothing/gloves/G = gloves gloves_siemens_coeff = G.siemens_coefficient - if(dna.species) - species_siemens_coeff = dna.species.siemens_coeff - siemens_coeff = gloves_siemens_coeff * species_siemens_coeff - if(undergoing_cardiac_arrest()) + siemens_coeff = gloves_siemens_coeff + if(undergoing_cardiac_arrest() && !illusion) if(shock_damage * siemens_coeff >= 1 && prob(25)) set_heartattack(FALSE) if(stat == CONSCIOUS) to_chat(src, "You feel your heart beating again!") - . = ..() + dna.species.spec_electrocute_act(src, shock_damage, source, siemens_coeff, safety, override, tesla_shock, illusion, stun) + . = ..(shock_damage, source, siemens_coeff, safety, override, tesla_shock, illusion, stun) /mob/living/carbon/human/Topic(href, href_list) if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr)) @@ -1651,6 +1638,9 @@ Eyes need to have significantly high darksight to shine unless the mob has the X ..() /mob/living/carbon/human/proc/do_cpr(mob/living/carbon/human/H) + if(H == src) + to_chat(src, "You cannot perform CPR on yourself!") + return if(H.stat == DEAD || (H.status_flags & FAKEDEATH)) to_chat(src, "[H.name] is dead!") return @@ -1662,25 +1652,29 @@ Eyes need to have significantly high darksight to shine unless the mob has the X return if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted)) to_chat(src, "Remove your mask first!") - return 0 + return if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.mask_adjusted)) to_chat(src, "Remove [H.p_their()] mask first!") - return 0 - visible_message("[src] is trying to perform CPR on [H.name]!", \ - "You try to perform CPR on [H.name]!") + return + if(H.receiving_cpr) // To prevent spam stacking + to_chat(src, "They are already receiving CPR!") + return + visible_message("[src] is trying to perform CPR on [H.name]!", "You try to perform CPR on [H.name]!") + H.receiving_cpr = TRUE if(do_mob(src, H, 40)) - if(H.health > config.health_threshold_dead && H.health <= config.health_threshold_crit) - var/suff = min(H.getOxyLoss(), 7) - H.adjustOxyLoss(-suff) + if(H.health <= HEALTH_THRESHOLD_CRIT) + H.adjustOxyLoss(-15) + H.SetLoseBreath(0) + H.AdjustParalysis(-1) H.updatehealth("cpr") - visible_message("[src] performs CPR on [H.name]!", \ - "You perform CPR on [H.name].") + visible_message("[src] performs CPR on [H.name]!", "You perform CPR on [H.name].") to_chat(H, "You feel a breath of fresh air enter your lungs. It feels good.") - to_chat(src, "Repeat at least every 7 seconds.") + H.receiving_cpr = FALSE add_attack_logs(src, H, "CPRed", ATKLOG_ALL) - return 1 + return TRUE else + H.receiving_cpr = FALSE to_chat(src, "You need to stay still while performing CPR!") /mob/living/carbon/human/canBeHandcuffed() @@ -1696,7 +1690,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X return FALSE /mob/living/carbon/human/InCritical() - return (health <= config.health_threshold_crit && stat == UNCONSCIOUS) + return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS) /mob/living/carbon/human/IsAdvancedToolUser() @@ -2000,4 +1994,4 @@ Eyes need to have significantly high darksight to shine unless the mob has the X var/obj/item/organ/internal/lantern/O = get_int_organ(/obj/item/organ/internal/lantern) if(O && O.glowing) O.toggle_biolum(TRUE) - visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.") + visible_message("[src] is engulfed in shadows and fades into the darkness.", "A sense of dread washes over you as you suddenly dim dark.") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index b858cca130a..d7a9bde2cef 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -15,7 +15,7 @@ health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute //TODO: fix husking - if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD) + if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD) ChangeToHusk() update_stat("updatehealth([reason])") med_hud_set_health() @@ -31,7 +31,10 @@ if(sponge) if(dna.species && amount > 0) amount = amount * dna.species.brain_mod - sponge.receive_damage(amount, 1) + sponge.damage = Clamp(sponge.damage + amount, 0, 120) + if(sponge.damage >= 120) + visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") + death() if(updating) update_stat("adjustBrainLoss") return STATUS_UPDATE_STAT @@ -45,7 +48,10 @@ if(sponge) if(dna.species && amount > 0) amount = amount * dna.species.brain_mod - sponge.damage = min(max(amount, 0), (maxHealth*2)) + sponge.damage = Clamp(amount, 0, 120) + if(sponge.damage >= 120) + visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") + death() if(updating) update_stat("setBrainLoss") return STATUS_UPDATE_STAT @@ -171,11 +177,17 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/adjustOxyLoss(amount) + if(NO_BREATHE in dna.species.species_traits) + oxyloss = 0 + return FALSE if(dna.species && amount > 0) amount = amount * dna.species.oxy_mod . = ..() /mob/living/carbon/human/setOxyLoss(amount) + if(NO_BREATHE in dna.species.species_traits) + oxyloss = 0 + return FALSE if(dna.species && amount > 0) amount = amount * dna.species.oxy_mod . = ..() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 84764bfddaa..c1d61338dcd 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -157,7 +157,7 @@ emp_act return 1 return 0 -/mob/living/carbon/human/check_block() +/mob/living/carbon/human/proc/check_block() if(martial_art && prob(martial_art.block_chance) && martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) return TRUE @@ -220,6 +220,10 @@ emp_act if(check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration)) return 0 + if(check_block()) + visible_message("[src] blocks [I]!") + return FALSE + if(istype(I,/obj/item/card/emag)) emag_act(user, affecting) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 22a9d40f6fd..987041bc7ad 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,7 @@ var/global/default_martial_art = new/datum/martial_art /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD,GLAND_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD) //Marking colour and style var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000. @@ -64,6 +64,7 @@ var/global/default_martial_art = new/datum/martial_art var/check_mutations=0 // Check mutations on next life tick var/heartbeat = 0 + var/receiving_cpr = FALSE var/fire_dmi = 'icons/mob/OnFire.dmi' var/fire_sprite = "Standing" diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index bb9ae87bdc7..69dfa740b09 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -166,7 +166,7 @@ return var/list/jobs[0] - for(var/datum/job/j in job_master.occupations) + for(var/datum/job/j in SSjobs.occupations) if(j.title != "AI" && j.title != "Cyborg") jobs[j.title] = j jobs = sortAssoc(jobs) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 7d83c7eaa1d..79b41e47cc3 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -434,11 +434,11 @@ if(slot_l_hand) if(l_hand) return 0 - return 1 + return !incapacitated() if(slot_r_hand) if(r_hand) return 0 - return 1 + return !incapacitated() if(slot_wear_mask) if(wear_mask) return 0 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8d0261528ed..903c8ef80d3 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -10,10 +10,8 @@ update_mutations() check_mutations=0 - handle_shock() handle_pain() handle_heartbeat() - handle_heartattack() handle_drunk() dna.species.handle_life(src) @@ -39,6 +37,17 @@ if(life_tick == 1) regenerate_icons() // Make sure the inventory updates + handle_ghosted() + +/mob/living/carbon/human/proc/handle_ghosted() + if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained()) + if(key) + player_ghosted = 0 + else + player_ghosted++ + if(player_ghosted % 150 == 0) + force_cryo_human(src) + /mob/living/carbon/human/calculate_affecting_pressure(var/pressure) ..() var/pressure_difference = abs( pressure - ONE_ATMOSPHERE ) @@ -141,15 +150,6 @@ if(3) emote("drool") - if(getBrainLoss() >= 100 && stat != DEAD) //you lapse into a coma and die without immediate aid; RIP. -Fox - Weaken(20) - AdjustLoseBreath(10) - AdjustSilence(2) - - if(getBrainLoss() >= 120 && stat != DEAD) //they died from stupidity--literally. -Fox - visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") - death() - /mob/living/carbon/human/handle_mutations_and_radiation() for(var/datum/dna/gene/gene in dna_genes) if(!gene.block) @@ -242,12 +242,10 @@ var/obj/item/organ/internal/L = get_organ_slot("lungs") if(!L || L && (L.status & ORGAN_DEAD)) - if(health >= config.health_threshold_crit) + if(health >= HEALTH_THRESHOLD_CRIT) adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1) else if(!(NOCRITDAMAGE in dna.species.species_traits)) - adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) - - failed_last_breath = TRUE + adjustOxyLoss(HUMAN_MAX_OXYLOSS) if(dna.species) var/datum/species/S = dna.species @@ -270,7 +268,7 @@ // USED IN DEATHWHISPERS /mob/living/carbon/human/proc/isInCrit() // Health is in deep shit and we're not already dead - return health <= 0 && stat != 2 + return health <= HEALTH_THRESHOLD_CRIT && stat != DEAD /mob/living/carbon/human/get_breath_from_internal(volume_needed) //making this call the parent would be far too complicated @@ -405,7 +403,7 @@ if(on_fire) var/thermal_protection = get_thermal_protection() - if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT) return if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT) bodytemperature += 11 @@ -791,6 +789,69 @@ handle_organs() + if(getBrainLoss() >= 120 || (health + (getOxyLoss() / 2)) <= -500) + death() + return + + if(getBrainLoss() >= 100) // braindeath + AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25) + Weaken(30) + + if(!check_death_method()) + if(health <= HEALTH_THRESHOLD_DEAD) + var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01) + if(prob(deathchance)) + death() + return + + if(health <= HEALTH_THRESHOLD_CRIT) + if(prob(5)) + emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver")) + AdjustStuttering(5, bound_lower = 0, bound_upper = 5) + EyeBlurry(5) + if(prob(7)) + AdjustConfused(2) + if(prob(5)) + Paralyse(2) + switch(health) + if(-INFINITY to -100) + adjustOxyLoss(1) + if(prob(health * -0.1)) + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.set_heartattack(TRUE) + if(prob(health * -0.2)) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + Paralyse(5) + if(-99 to -80) + adjustOxyLoss(1) + if(prob(4)) + to_chat(src, "Your chest hurts...") + Paralyse(2) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + if(-79 to -50) + adjustOxyLoss(1) + if(prob(10)) + var/datum/disease/D = new /datum/disease/critical/shock + ForceContractDisease(D) + if(prob(health * -0.08)) + var/datum/disease/D = new /datum/disease/critical/heart_failure + ForceContractDisease(D) + if(prob(6)) + to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!") + Weaken(3) + if(prob(3)) + Paralyse(2) + if(-49 to 0) + adjustOxyLoss(1) + if(prob(3)) + var/datum/disease/D = new /datum/disease/critical/shock + ForceContractDisease(D) + if(prob(5)) + to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!") + Weaken(3) else //dead SetSilence(0) @@ -944,12 +1005,12 @@ if(prob(2)) var/obj/item/clothing/mask/M = H.wear_mask if(M && (M.flags_cover & MASKCOVERSMOUTH)) - return + continue if(NO_BREATHE in H.dna.species.species_traits) - return //no puking if you can't smell! + continue //no puking if you can't smell! // Humans can lack a mind datum, y'know if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner")) - return //too cool for puke + continue //too cool for puke to_chat(H, "You smell something foul...") H.fakevomit() @@ -962,7 +1023,7 @@ return if(H.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people. - if(shock_stage >= 10 || istype(get_turf(src), /turf/space)) + if(isinspace()) //PULSE_THREADY - maximum value for pulse, currently it 5. //High pulse value corresponds to a fast rate of heartbeat. //Divided by 2, otherwise it is too slow. @@ -980,7 +1041,7 @@ if(pulse == PULSE_NONE) return - if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space)) + if(pulse >= PULSE_2FAST || isinspace()) //PULSE_THREADY - maximum value for pulse, currently it 5. //High pulse value corresponds to a fast rate of heartbeat. //Divided by 2, otherwise it is too slow. @@ -999,7 +1060,7 @@ */ /mob/living/carbon/human/proc/can_heartattack() - if(NO_BLOOD in dna.species.species_traits) + if((NO_BLOOD in dna.species.species_traits) && !dna.species.forced_heartattack) return FALSE if(NO_INTORGANS in dna.species.species_traits) return FALSE @@ -1026,13 +1087,16 @@ heart.beating = !status -/mob/living/carbon/human/proc/handle_heartattack() +/mob/living/carbon/human/handle_heartattack() if(!can_heartattack() || !undergoing_cardiac_arrest() || reagents.has_reagent("corazone")) return - AdjustLoseBreath(2, bound_lower = 0, bound_upper = 3) - adjustOxyLoss(5) - Paralyse(4) - adjustBruteLoss(2) + if(getOxyLoss()) + adjustBrainLoss(3) + else if(prob(10)) + adjustBrainLoss(1) + Weaken(5) + AdjustLoseBreath(20, bound_lower = 0, bound_upper = 25) + adjustOxyLoss(20) diff --git a/code/modules/mob/living/carbon/human/logout.dm b/code/modules/mob/living/carbon/human/logout.dm index c7e76343c38..2dae7ea5b9a 100644 --- a/code/modules/mob/living/carbon/human/logout.dm +++ b/code/modules/mob/living/carbon/human/logout.dm @@ -1,4 +1,4 @@ /mob/living/carbon/human/Logout() ..() - if(mind.active && stat != DEAD) + if(mind && mind.active && stat != DEAD) overlays += image('icons/effects/effects.dmi', icon_state = "zzz_glow") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index ff8083f8093..1be6fc60a25 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -91,7 +91,7 @@ var/obj/item/organ/internal/L = get_organ_slot("lungs") if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD)) return FALSE - if(oxyloss > 10 || losebreath >= 4) + if(getOxyLoss() > 10 || losebreath >= 4) emote("gasp") return FALSE if(mind) diff --git a/code/modules/mob/living/carbon/human/shock.dm b/code/modules/mob/living/carbon/human/shock.dm deleted file mode 100644 index e2d5dd79cec..00000000000 --- a/code/modules/mob/living/carbon/human/shock.dm +++ /dev/null @@ -1,75 +0,0 @@ -/mob/living/carbon/human/var/traumatic_shock = 0 -/mob/living/carbon/human/var/shock_stage = 0 - -// proc to find out in how much pain the mob is at the moment -/mob/living/carbon/human/proc/updateshock() - traumatic_shock = getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss() - - // broken or ripped off organs will add quite a bit of pain - for(var/thing in bodyparts) - var/obj/item/organ/external/BP = thing - if(BP.status & ORGAN_BROKEN && !(BP.status & ORGAN_SPLINTED) || BP.open) - traumatic_shock += 15 - - if(reagents) - for(var/datum/reagent/R in reagents.reagent_list) - if(R.shock_reduction) - traumatic_shock = max(0, traumatic_shock - R.shock_reduction) // now you too can varedit cyanide to reduce shock by 1000 - Iamgoofball - if(drunk) - traumatic_shock = max(0, traumatic_shock - 10) - - return traumatic_shock - -/mob/living/carbon/human/proc/handle_shock() - if(status_flags & GODMODE) //godmode - return - if(NO_PAIN in dna.species.species_traits) - return - - updateshock() - - if(health <= config.health_threshold_softcrit)// health 0 makes you immediately collapse - shock_stage = max(shock_stage, 61) - - if(traumatic_shock >= 100) - shock_stage += 1 - else - shock_stage = min(shock_stage, 160) - shock_stage = max(shock_stage-1, 0) - return - - if(shock_stage == 10) - to_chat(src, ""+pick("It hurts so much!", "You really need some painkillers..", "Dear god, the pain!")) - - if(shock_stage >= 30) - if(shock_stage == 30) - custom_emote(1,"is having trouble keeping [p_their()] eyes open.") - EyeBlurry(2) - Stuttering(5) - - if(shock_stage == 40) - to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")) - - if(shock_stage >=60) - if(shock_stage == 60) - custom_emote(1,"falls limp.") - if(prob(2)) - to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")) - Weaken(20) - - if(shock_stage >= 80) - if(prob(5)) - to_chat(src, ""+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")) - Weaken(20) - - if(shock_stage >= 120) - if(prob(2)) - to_chat(src, ""+pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")) - Paralyse(5) - - if(shock_stage == 150) - custom_emote(1,"can no longer stand, collapsing!") - Weaken(20) - - if(shock_stage >= 150) - Weaken(20) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 1335c8e2d57..d9a501d2251 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -91,6 +91,8 @@ var/is_small var/show_ssd = 1 + var/forced_heartattack = FALSE //Some species have blood, but we still want them to have heart attacks + var/dies_at_threshold = FALSE // Do they die or get knocked out at specific thresholds, or do they go through complex crit? var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them var/has_gender = TRUE var/blacklisted = FALSE @@ -255,8 +257,6 @@ . += (health_deficiency / 75) else . += (health_deficiency / 25) - if(H.shock_stage >= 10) - . += 3 . += 2 * H.stance_damage //damaged/missing feet or legs is slow if((hungry >= 70) && !flight) @@ -298,11 +298,8 @@ // (Slime People changing color based on the reagents they consume) /datum/species/proc/handle_life(mob/living/carbon/human/H) if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations)) - H.setOxyLoss(0) - H.SetLoseBreath(0) - var/takes_crit_damage = (!(NOCRITDAMAGE in species_traits)) - if((H.health <= config.health_threshold_crit) && takes_crit_damage) + if((H.health <= HEALTH_THRESHOLD_CRIT) && takes_crit_damage) H.adjustBruteLoss(1) return @@ -312,17 +309,20 @@ /datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). return +/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + return + /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.help_act(user, target))//adminfu only... return TRUE - if(target.health >= config.health_threshold_crit && !(target.status_flags & FAKEDEATH)) + if(target.health >= HEALTH_THRESHOLD_CRIT && !(target.status_flags & FAKEDEATH)) target.help_shake_act(user) return TRUE else user.do_cpr(target) /datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - if(target.check_block()) //cqc + if(target.check_block()) target.visible_message("[target] blocks [user]'s grab attempt!") return FALSE if(attacker_style && attacker_style.grab_act(user, target)) @@ -351,7 +351,7 @@ add_attack_logs(user, target, "vampirebit") return //end vampire codes - if(target.check_block()) //cqc + if(target.check_block()) target.visible_message("[target] blocks [user]'s attack!") return FALSE if(attacker_style && attacker_style.harm_act(user, target)) @@ -396,7 +396,7 @@ SEND_SIGNAL(target, COMSIG_PARENT_ATTACKBY) /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) - if(target.check_block()) //cqc + if(target.check_block()) target.visible_message("[target] blocks [user]'s disarm attempt!") return FALSE if(attacker_style && attacker_style.disarm_act(user, target)) @@ -524,6 +524,7 @@ miss_sound = 'sound/weapons/slashmiss.ogg' sharp = TRUE animation_type = ATTACK_EFFECT_CLAW + var/has_been_sharpened = FALSE /datum/unarmed_attack/bite attack_verb = list("chomp") @@ -539,7 +540,7 @@ return FALSE /datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H) - return 100 - ((NO_PAIN in species_traits) ? 0 : H.traumatic_shock) - H.getStaminaLoss() + return H.health - H.getStaminaLoss() /datum/species/proc/handle_hud_icons(mob/living/carbon/human/H) if(!H.client) diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index cf1492e8408..64c5a4aa0b3 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -16,8 +16,7 @@ ) species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE) - - oxy_mod = 0 + dies_at_threshold = TRUE clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS dietflags = DIET_OMNI diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm index 82def809a4b..bccbeb6c5a7 100644 --- a/code/modules/mob/living/carbon/human/species/diona.dm +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -32,6 +32,7 @@ water and other radiation." species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) + dies_at_threshold = TRUE clothing_flags = HAS_SOCKS default_hair_colour = "#000000" has_gender = FALSE @@ -39,8 +40,6 @@ taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE skinned_type = /obj/item/stack/sheet/wood - oxy_mod = 0 - body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not blood_color = "#004400" flesh_color = "#907E4A" diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 032af8ea3b9..e790181188e 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -6,10 +6,10 @@ deform = 'icons/mob/human_races/r_golem.dmi' species_traits = list(NO_BREATHE, NO_BLOOD, NO_PAIN, RADIMMUNE, VIRUSIMMUNE, NOGUNS) + dies_at_threshold = TRUE brute_mod = 0.45 //55% damage reduction burn_mod = 0.45 tox_mod = 0.45 - oxy_mod = 0 dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG @@ -163,6 +163,8 @@ if(H.bodytemperature > 850 && H.on_fire && prob(25)) explosion(get_turf(H), 1, 2, 4, flame_range = 5) + msg_admin_attack("Plasma Golem ([H.name]) exploded with radius 1, 2, 4 (flame_range: 5) at ([H.x],[H.y],[H.z]). User Ckey: [key_name_admin(H)]", ATKLOG_FEW) + log_game("Plasma Golem ([H.name]) exploded with radius 1, 2, 4 (flame_range: 5) at ([H.x],[H.y],[H.z]). User Ckey: [key_name_admin(H)]", ATKLOG_FEW) if(H) H.gib() if(H.fire_stacks < 2) //flammable @@ -533,23 +535,26 @@ check_flags = AB_CHECK_CONSCIOUS button_icon_state = "blink" icon_icon = 'icons/mob/actions/actions.dmi' + var/activated = FALSE // To prevent spamming var/cooldown = 150 var/last_teleport = 0 var/tele_range = 6 /datum/action/innate/unstable_teleport/IsAvailable() if(..()) - if(world.time > last_teleport + cooldown) + if(world.time > last_teleport + cooldown && !activated) return 1 return 0 /datum/action/innate/unstable_teleport/Activate() + activated = TRUE var/mob/living/carbon/human/H = owner H.visible_message("[H] starts vibrating!", "You start charging your bluespace core...") playsound(get_turf(H), 'sound/weapons/flash.ogg', 25, 1) addtimer(CALLBACK(src, .proc/teleport, H), 15) /datum/action/innate/unstable_teleport/proc/teleport(mob/living/carbon/human/H) + activated = FALSE H.visible_message("[H] teleports!", "You teleport!") var/list/turfs = new/list() for(var/turf/T in orange(tele_range, H)) diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm index e5492e60293..5bb314c4f43 100644 --- a/code/modules/mob/living/carbon/human/species/grey.dm +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -56,6 +56,9 @@ /datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) if(R.id == "sacid") - H.reagents.del_reagent(R.id) - return 0 + H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) + return FALSE + if(R.id == "water") + H.adjustFireLoss(1) + return TRUE return ..() diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 88ed0a626cb..4f5a65c82a2 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -19,7 +19,6 @@ burn_mod = 2.28 // So they take 50% extra damage from brute/burn overall tox_mod = 0 clone_mod = 0 - oxy_mod = 0 death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..." species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_INTORGANS, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING) @@ -36,6 +35,7 @@ //Default styles for created mobs. default_hair = "Blue IPC Screen" + dies_at_threshold = TRUE can_revive_by_healing = 1 has_gender = FALSE reagent_tag = PROCESS_SYN diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm index 21d8a5c0012..fe8a5587017 100644 --- a/code/modules/mob/living/carbon/human/species/nucleation.dm +++ b/code/modules/mob/living/carbon/human/species/nucleation.dm @@ -13,8 +13,8 @@ language = "Sol Common" burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores brute_mod = 2 // damn, double wham, double dam - oxy_mod = 0 species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE) + dies_at_threshold = TRUE dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet //Default styles for created mobs. diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index a8fd532a3f1..35d02f82509 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -7,6 +7,7 @@ //language = "Clatter" species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING) + forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently* dietflags = DIET_OMNI reagent_tag = PROCESS_ORG @@ -187,6 +188,6 @@ H.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER) H.adjustPlasma(20) H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) - return 0 //Handling reagent removal on our own. Prevents plasma from dealing toxin damage to Plasmamen. + return FALSE //Handling reagent removal on our own. Prevents plasma from dealing toxin damage to Plasmamen. return ..() diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index df1ecd61484..fb7fd2ebda1 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -18,8 +18,7 @@ ) species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE) - - oxy_mod = 0 + dies_at_threshold = TRUE dietflags = DIET_OMNI //the mutation process allowed you to now digest all foods regardless of initial race reagent_tag = PROCESS_ORG diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm index 1ce7b5cd0e0..f65aedb530b 100644 --- a/code/modules/mob/living/carbon/human/species/shadowling.dm +++ b/code/modules/mob/living/carbon/human/species/shadowling.dm @@ -11,7 +11,6 @@ species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash burn_mod = 1.5 //1.5x burn damage, 2x is excessive - oxy_mod = 0 heatmod = 1.5 silent_steps = 1 @@ -63,7 +62,6 @@ species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_EXAMINE) burn_mod = 1.1 - oxy_mod = 0 heatmod = 1.1 /datum/species/shadow/ling/lesser/handle_life(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index 6a2b74fb671..0199722d1f4 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -11,10 +11,9 @@ flesh_color = "#E6E6C6" species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE) + dies_at_threshold = TRUE skinned_type = /obj/item/stack/sheet/bone - oxy_mod = 0 - dietflags = DIET_OMNI reagent_tag = PROCESS_ORG @@ -42,7 +41,7 @@ /datum/species/skeleton/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) // Crazylemon is still silly if(R.id == "milk") - H.heal_overall_damage(4,4) + H.heal_overall_damage(4, 4) if(prob(5)) // 5% chance per proc to find a random limb, and mend it var/list/our_organs = H.bodyparts.Copy() shuffle(our_organs) @@ -55,7 +54,7 @@ L.perma_injury = 0 break // We're only checking one limb here, bucko if(prob(3)) - H.say(pick("Thanks Mr Skeltal", "Thank for strong bones", "Doot doot!")) - return 1 + H.say(pick("Thanks Mr. Skeltal", "Thank for strong bones", "Doot doot!")) + return TRUE return ..() diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index 5631f600afc..b33ebc1f048 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -20,13 +20,13 @@ cold_level_3 = 200 coldmod = 3 - oxy_mod = 0 brain_mod = 2.5 male_cough_sounds = list('sound/effects/slime_squish.ogg') female_cough_sounds = list('sound/effects/slime_squish.ogg') species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN) + dies_at_threshold = TRUE clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_COLOR | NO_EYES dietflags = DIET_CARN @@ -83,7 +83,7 @@ H.update_body() ..() -/datum/species/slime/can_hear() // fucking snowflakes +/datum/species/slime/can_hear() // fucking snowflakes . = TRUE /datum/action/innate/slimecolor diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm index bc21dd1ee5f..f8485e8f9e9 100644 --- a/code/modules/mob/living/carbon/human/species/vox.dm +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -31,7 +31,7 @@ eyes = "vox_eyes_s" species_traits = list(NO_SCAN, IS_WHITELISTED, NOTRANSSTING) - clothing_flags = HAS_SOCKS + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS //Species-fitted 'em all. dietflags = DIET_OMNI bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS @@ -173,8 +173,9 @@ eyes = "blank_eyes" species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED) + clothing_flags = 0 //IDK if you've ever seen underwear on an Armalis, but it ain't pretty. bodyflags = HAS_TAIL - dietflags = DIET_OMNI //should inherit this from vox, this is here just in case + dies_at_threshold = TRUE blood_color = "#2299FC" flesh_color = "#808D11" diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm index 8c576f9e30e..6069da28f84 100644 --- a/code/modules/mob/living/carbon/human/species/wryn.dm +++ b/code/modules/mob/living/carbon/human/species/wryn.dm @@ -39,7 +39,7 @@ clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS dietflags = DIET_HERB //bees feed off nectar, so bee people feed off plants too - oxy_mod = 0 + dies_at_threshold = TRUE reagent_tag = PROCESS_ORG base_color = "#704300" diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index e7a65129017..30653023751 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -1,3 +1,9 @@ +/mob/living/carbon/human/SetLoseBreath(amount) + if(NO_BREATHE in dna.species.species_traits) + losebreath = 0 + return FALSE + . = ..() + /mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) if(dna.species) amount = amount * dna.species.stun_mod diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index ff93cd54b80..e55eee62dbc 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -254,17 +254,20 @@ var/global/list/damage_icon_parts = list() if(underwear && dna.species.clothing_flags & HAS_UNDERWEAR) var/datum/sprite_accessory/underwear/U = GLOB.underwear_list[underwear] if(U) - underwear_standing.Blend(new /icon(U.icon, "uw_[U.icon_state]_s"), ICON_OVERLAY) + var/u_icon = U.sprite_sheets && (dna.species.name in U.sprite_sheets) ? U.sprite_sheets[dna.species.name] : U.icon //Species-fit the undergarment. + underwear_standing.Blend(new /icon(u_icon, "uw_[U.icon_state]_s"), ICON_OVERLAY) if(undershirt && dna.species.clothing_flags & HAS_UNDERSHIRT) var/datum/sprite_accessory/undershirt/U2 = GLOB.undershirt_list[undershirt] if(U2) - underwear_standing.Blend(new /icon(U2.icon, "us_[U2.icon_state]_s"), ICON_OVERLAY) + var/u2_icon = U2.sprite_sheets && (dna.species.name in U2.sprite_sheets) ? U2.sprite_sheets[dna.species.name] : U2.icon + underwear_standing.Blend(new /icon(u2_icon, "us_[U2.icon_state]_s"), ICON_OVERLAY) if(socks && dna.species.clothing_flags & HAS_SOCKS) var/datum/sprite_accessory/socks/U3 = GLOB.socks_list[socks] if(U3) - underwear_standing.Blend(new /icon(U3.icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY) + var/u3_icon = U3.sprite_sheets && (dna.species.name in U3.sprite_sheets) ? U3.sprite_sheets[dna.species.name] : U3.icon + underwear_standing.Blend(new /icon(u3_icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY) if(underwear_standing) overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER) diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm index d8c26a91964..6228038c710 100644 --- a/code/modules/mob/living/carbon/human/update_stat.dm +++ b/code/modules/mob/living/carbon/human/update_stat.dm @@ -2,20 +2,11 @@ if(status_flags & GODMODE) return ..(reason) - if(stat != DEAD) - switch(getBrainLoss()) - if(100 to 120) - Weaken(20) - create_debug_log("collapsed from brain damage, trigger reason: [reason]") - if(120 to INFINITY) - visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") - death() - create_debug_log("died of brain damage, trigger reason: [reason]") - else + if(stat == DEAD) if(dna.species && dna.species.can_revive_by_healing) var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain) if(B) - if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && getBrainLoss()<120) + if((health >= (HEALTH_THRESHOLD_DEAD + HEALTH_THRESHOLD_CRIT) * 0.5) && getBrainLoss() < 120) update_revive() create_debug_log("revived from healing, trigger reason: [reason]") @@ -30,4 +21,7 @@ /mob/living/carbon/human/can_hear() . = TRUE // Fallback if we don't have a species if(dna.species) - . = dna.species.can_hear(src) \ No newline at end of file + . = dna.species.can_hear(src) + +/mob/living/carbon/human/check_death_method() + return dna.species.dies_at_threshold \ No newline at end of file diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 18e42c98d08..48d8137092a 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -27,8 +27,8 @@ //Start of a breath chain, calls breathe() /mob/living/carbon/handle_breathing(times_fired) - if(times_fired % 4 == 2 || failed_last_breath) - breathe() //Breathe per 4 ticks, unless suffocating + if(times_fired % 2 == 1) + breathe() //Breathe every other tick, unless suffocating else if(istype(loc, /obj/)) var/obj/location_as_object = loc @@ -47,13 +47,13 @@ var/datum/gas_mixture/breath - if(health <= config.health_threshold_crit) + if(health <= HEALTH_THRESHOLD_CRIT && check_death_method()) AdjustLoseBreath(1) //Suffocate if(losebreath > 0) AdjustLoseBreath(-1) - if(prob(10)) + if(prob(75)) emote("gasp") if(istype(loc, /obj/)) var/obj/loc_as_obj = loc @@ -97,7 +97,6 @@ //CRIT if(!breath || (breath.total_moles() == 0) || !lungs) adjustOxyLoss(1) - failed_last_breath = TRUE throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) return FALSE @@ -121,15 +120,12 @@ if(O2_partialpressure > 0) var/ratio = 1 - O2_partialpressure/safe_oxy_min adjustOxyLoss(min(5*ratio, 3)) - failed_last_breath = TRUE oxygen_used = breath.oxygen*ratio else adjustOxyLoss(3) - failed_last_breath = TRUE throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) else //Enough oxygen - failed_last_breath = FALSE adjustOxyLoss(-5) oxygen_used = breath.oxygen clear_alert("not_enough_oxy") @@ -406,35 +402,54 @@ handle_hud_icons_health_overlay() /mob/living/carbon/proc/handle_hud_icons_health_overlay() - if(stat == UNCONSCIOUS && health <= config.health_threshold_crit) - var/severity = 0 - switch(health) - if(-20 to -10) severity = 1 - if(-30 to -20) severity = 2 - if(-40 to -30) severity = 3 - if(-50 to -40) severity = 4 - if(-60 to -50) severity = 5 - if(-70 to -60) severity = 6 - if(-80 to -70) severity = 7 - if(-90 to -80) severity = 8 - if(-95 to -90) severity = 9 - if(-INFINITY to -95) severity = 10 - overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity) - else if(stat == CONSCIOUS) - clear_fullscreen("crit") - if(oxyloss) + if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT) + if(check_death_method()) var/severity = 0 - switch(oxyloss) - if(10 to 20) severity = 1 - if(20 to 25) severity = 2 - if(25 to 30) severity = 3 - if(30 to 35) severity = 4 - if(35 to 40) severity = 5 - if(40 to 45) severity = 6 - if(45 to INFINITY) severity = 7 - overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity) - else - clear_fullscreen("oxy") + switch(health) + if(-20 to -10) + severity = 1 + if(-30 to -20) + severity = 2 + if(-40 to -30) + severity = 3 + if(-50 to -40) + severity = 4 + if(-60 to -50) + severity = 5 + if(-70 to -60) + severity = 6 + if(-80 to -70) + severity = 7 + if(-90 to -80) + severity = 8 + if(-95 to -90) + severity = 9 + if(-INFINITY to -95) + severity = 10 + overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity) + else if(stat == CONSCIOUS) + if(check_death_method()) + clear_fullscreen("crit") + if(getOxyLoss()) + var/severity = 0 + switch(getOxyLoss()) + if(10 to 20) + severity = 1 + if(20 to 25) + severity = 2 + if(25 to 30) + severity = 3 + if(30 to 35) + severity = 4 + if(35 to 40) + severity = 5 + if(40 to 45) + severity = 6 + if(45 to INFINITY) + severity = 7 + overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity) + else + clear_fullscreen("oxy") //Fire and Brute damage overlay (BSSR) var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp @@ -450,4 +465,4 @@ if(85 to INFINITY) severity = 6 overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity) else - clear_fullscreen("brute") + clear_fullscreen("brute") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm index 649ec7b3f00..e3bfcb74431 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -174,11 +174,11 @@ else health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - if(health < config.health_threshold_dead && stat != 2) + if(health < HEALTH_THRESHOLD_DEAD && check_death_method() && stat != DEAD) death() return - else if(src.health <= config.health_threshold_crit) + else if(src.health <= HEALTH_THRESHOLD_CRIT && check_death_method()) if(!src.reagents.has_reagent("epinephrine")) src.adjustOxyLoss(10) diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm index 22030c78f4b..58c6e09764b 100644 --- a/code/modules/mob/living/carbon/update_status.dm +++ b/code/modules/mob/living/carbon/update_status.dm @@ -3,12 +3,12 @@ return if(stat != DEAD) // if(health <= min_health) - if(health <= config.health_threshold_dead) + if(health <= HEALTH_THRESHOLD_DEAD && check_death_method()) death() create_debug_log("died of damage, trigger reason: [reason]") return // if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health) - if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit) + if(paralysis || sleeping || (check_death_method() && getOxyLoss() > 50) || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT && check_death_method()) if(stat == CONSCIOUS) KnockOut() create_debug_log("fell unconscious, trigger reason: [reason]") @@ -21,7 +21,7 @@ ..() if(staminaloss) var/total_health = (health - staminaloss) - if(total_health <= config.health_threshold_softcrit && !stat) + if(total_health <= HEALTH_THRESHOLD_CRIT && !stat) to_chat(src, "You're too exhausted to keep going...") Weaken(5) setStaminaLoss(health - 2) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 734dd556b48..afca9ad8798 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -104,11 +104,11 @@ /mob/living/proc/getBruteLoss() return bruteloss -/mob/living/proc/adjustBruteLoss(var/amount, updating_health = TRUE) +/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) return FALSE //godmode var/old_bruteloss = bruteloss - bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2)) + bruteloss = max(bruteloss + amount, 0) if(old_bruteloss == bruteloss) updating_health = FALSE . = STATUS_UPDATE_NONE @@ -120,11 +120,15 @@ /mob/living/proc/getOxyLoss() return oxyloss -/mob/living/proc/adjustOxyLoss(var/amount, updating_health = TRUE) +/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) + oxyloss = 0 return FALSE //godmode + if(BREATHLESS in mutations) + oxyloss = 0 + return FALSE var/old_oxyloss = oxyloss - oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2)) + oxyloss = max(oxyloss + amount, 0) if(old_oxyloss == oxyloss) updating_health = FALSE . = STATUS_UPDATE_NONE @@ -135,7 +139,11 @@ /mob/living/proc/setOxyLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) + oxyloss = 0 return FALSE //godmode + if(BREATHLESS in mutations) + oxyloss = 0 + return FALSE var/old_oxyloss = oxyloss oxyloss = amount if(old_oxyloss == oxyloss) @@ -149,11 +157,11 @@ /mob/living/proc/getToxLoss() return toxloss -/mob/living/proc/adjustToxLoss(var/amount, updating_health = TRUE) +/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) return FALSE //godmode var/old_toxloss = toxloss - toxloss = min(max(toxloss + amount, 0),(maxHealth*2)) + toxloss = max(toxloss + amount, 0) if(old_toxloss == toxloss) updating_health = FALSE . = STATUS_UPDATE_NONE @@ -162,7 +170,7 @@ if(updating_health) updatehealth("adjustToxLoss") -/mob/living/proc/setToxLoss(var/amount, updating_health = TRUE) +/mob/living/proc/setToxLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) return FALSE //godmode var/old_toxloss = toxloss @@ -178,11 +186,11 @@ /mob/living/proc/getFireLoss() return fireloss -/mob/living/proc/adjustFireLoss(var/amount, updating_health = TRUE) +/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) return FALSE //godmode var/old_fireloss = fireloss - fireloss = min(max(fireloss + amount, 0),(maxHealth*2)) + fireloss = max(fireloss + amount, 0) if(old_fireloss == fireloss) updating_health = FALSE . = STATUS_UPDATE_NONE @@ -194,11 +202,11 @@ /mob/living/proc/getCloneLoss() return cloneloss -/mob/living/proc/adjustCloneLoss(var/amount, updating_health = TRUE) +/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE) if(status_flags & GODMODE) return FALSE //godmode var/old_cloneloss = cloneloss - cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2)) + cloneloss = max(cloneloss + amount, 0) if(old_cloneloss == cloneloss) updating_health = FALSE . = STATUS_UPDATE_NONE @@ -207,8 +215,9 @@ if(updating_health) updatehealth("adjustCloneLoss") -/mob/living/proc/setCloneLoss(var/amount, updating_health = TRUE) - if(status_flags & GODMODE) return 0 //godmode +/mob/living/proc/setCloneLoss(amount, updating_health = TRUE) + if(status_flags & GODMODE) + return FALSE //godmode var/old_cloneloss = cloneloss cloneloss = amount if(old_cloneloss == cloneloss) @@ -235,7 +244,7 @@ if(status_flags & GODMODE) return FALSE var/old_stamloss = staminaloss - staminaloss = min(max(staminaloss + amount, 0),(maxHealth*2)) + staminaloss = max(staminaloss + amount, 0) if(old_stamloss == staminaloss) updating = FALSE . = STATUS_UPDATE_NONE @@ -300,4 +309,4 @@ updatehealth("take overall damage") /mob/living/proc/has_organic_damage() - return (maxHealth - health) + return (maxHealth - health) \ No newline at end of file diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 43a811dc3a3..003b5c3d4fe 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -59,7 +59,7 @@ if(!gibbed && deathgasp_on_death) emote("deathgasp") - if(suiciding) + if(mind && suiciding) mind.suicided = TRUE clear_fullscreens() update_sight() @@ -96,3 +96,9 @@ // u no we dead return TRUE + +/mob/living/proc/delayed_gib() + visible_message("[src] starts convulsing violently!", "You feel as if your body is tearing itself apart!") + Weaken(15) + do_jitter_animation(1000, -1) + addtimer(CALLBACK(src, .proc/gib), rand(20, 100)) \ No newline at end of file diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 66f3eec1683..d28e728c82c 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -25,6 +25,10 @@ handle_diseases() + //Heart Attack, if applicable + if(stat != DEAD) + handle_heartattack() + //Handle temperature/pressure differences between body and environment if(environment) handle_environment(environment) @@ -48,14 +52,15 @@ if(client) //regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES - if(get_nations_mode()) - process_nations() ..() /mob/living/proc/handle_breathing(times_fired) return +/mob/living/proc/handle_heartattack() + return + /mob/living/proc/handle_mutations_and_radiation() radiation = 0 //so radiation don't accumulate in simple animals return @@ -220,10 +225,4 @@ return /mob/living/proc/handle_hud_icons_health() - return - -/mob/living/proc/process_nations() - if(client) - var/client/C = client - for(var/mob/living/carbon/human/H in view(src, world.view)) - C.images += H.hud_list[NATIONS_HUD] + return \ No newline at end of file diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bf933f568d4..52fde3d0d9e 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -246,17 +246,18 @@ set hidden = 1 if(InCritical()) create_attack_log("[src] has ["succumbed to death"] with [round(health, 0.1)] points of health!") - adjustOxyLoss(health - config.health_threshold_dead) + adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD) // super check for weird mobs, including ones that adjust hp // we don't want to go overboard and gib them, though for(var/i = 1 to 5) - if(health < config.health_threshold_dead) + if(health < HEALTH_THRESHOLD_DEAD) break - take_overall_damage(max(5, health - config.health_threshold_dead), 0) + take_overall_damage(max(5, health - HEALTH_THRESHOLD_DEAD), 0) + death() to_chat(src, "You have given up life and succumbed to death.") /mob/living/proc/InCritical() - return (health < 0 && health > -95.0 && stat == UNCONSCIOUS) + return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS) /mob/living/ex_act(severity) ..() @@ -462,7 +463,6 @@ human_mob = src human_mob.set_heartattack(FALSE) human_mob.restore_blood() - human_mob.shock_stage = 0 human_mob.decaylevel = 0 human_mob.remove_all_embedded_objects() @@ -759,7 +759,7 @@ if(!silent) visible_message("[src] tries to put [what] on [who].") if(do_mob(src, who, what.put_on_delay)) - if(what && Adjacent(who)) + if(what && Adjacent(who) && !(what.flags & NODROP)) unEquip(what) who.equip_to_slot_if_possible(what, where, 0, 1) add_attack_logs(src, who, "Equipped [what]") @@ -786,11 +786,11 @@ ..() floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. -/mob/living/proc/do_jitter_animation(jitteriness) +/mob/living/proc/do_jitter_animation(jitteriness, loop_amount = 6) var/amplitude = min(4, (jitteriness/100) + 1) var/pixel_x_diff = rand(-amplitude, amplitude) var/pixel_y_diff = rand(-amplitude/3, amplitude/3) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = loop_amount) animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y) , time = 2) floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 0641ce380f5..88b17124451 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -55,8 +55,22 @@ /mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone) return 0 -/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0) - return 0 //only carbon liveforms have this proc +/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage) + if(status_flags & GODMODE) //godmode + return FALSE + if(NO_SHOCK in mutations) //shockproof + return FALSE + if(tesla_shock && tesla_ignore) + return FALSE + if(shock_damage > 0) + if(!illusion) + adjustFireLoss(shock_damage) + visible_message( + "[src] was shocked by \the [source]!", + "You feel a powerful shock coursing through your body!", + "You hear a heavy electrical crack.") + return shock_damage /mob/living/emp_act(severity) var/list/L = src.get_contents() @@ -337,8 +351,4 @@ return TRUE if(INTENT_DISARM) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return TRUE - -//defined here, overridden for humans in human_defense. By default, living mobs don't get to block anything -/mob/living/proc/check_block() - return FALSE \ No newline at end of file + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index dcc046f7b00..d1157b662fa 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -17,6 +17,4 @@ //Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways. update_pipe_vision() - update_interface() - return . diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5f0397becfe..ccf319b0884 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -38,7 +38,7 @@ var/list/ai_verbs_default = list( name = "AI" icon = 'icons/mob/ai.dmi'// icon_state = "ai" - move_resist = MOVE_FORCE_VERY_STRONG + move_resist = MOVE_FORCE_NORMAL density = 1 status_flags = CANSTUN|CANPARALYSE|CANPUSH mob_size = MOB_SIZE_LARGE @@ -534,14 +534,12 @@ var/list/ai_verbs_default = list( if(!isturf(loc)) // if their location isn't a turf return // stop - var/is_anchored = FALSE - if(move_resist == MOVE_FORCE_VERY_STRONG) - move_resist = MOVE_FORCE_VERY_STRONG + if(anchored) + anchored = FALSE else - is_anchored = TRUE - move_resist = MOVE_FORCE_NORMAL + anchored = TRUE - to_chat(src, "[is_anchored ? "You are now anchored." : "You are now unanchored."]") + to_chat(src, "[anchored ? "You are now anchored." : "You are now unanchored."]") /mob/living/silicon/ai/update_canmove() return FALSE @@ -1113,7 +1111,7 @@ var/list/ai_verbs_default = list( user.visible_message("\The [user] decides not to unbolt \the [src].") return user.visible_message("\The [user] finishes unfastening \the [src]!") - anchored = 0 + anchored = FALSE return else user.visible_message("\The [user] starts to bolt \the [src] to the plating...") @@ -1121,7 +1119,7 @@ var/list/ai_verbs_default = list( user.visible_message("\The [user] decides not to bolt \the [src].") return user.visible_message("\The [user] finishes fastening down \the [src]!") - anchored = 1 + anchored = TRUE return else return ..() diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm index c364c8d21b9..69136e07a99 100644 --- a/code/modules/mob/living/silicon/ai/latejoin.dm +++ b/code/modules/mob/living/silicon/ai/latejoin.dm @@ -27,7 +27,7 @@ var/global/list/empty_playable_ai_cores = list() //Handle job slot/tater cleanup. var/job = mind.assigned_role - job_master.FreeRole(job) + SSjobs.FreeRole(job) if(mind.objectives.len) mind.objectives.Cut() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 3700f83f0a9..eec1ec5b8b8 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -133,9 +133,6 @@ process_queued_alarms() - if(get_nations_mode()) - process_nations_ai() - /mob/living/silicon/ai/updatehealth(reason = "none given") if(status_flags & GODMODE) health = 100 @@ -156,12 +153,6 @@ ..() add_ai_verbs(src) -/mob/living/silicon/ai/proc/process_nations_ai() - if(client) - var/client/C = client - for(var/mob/living/carbon/human/H in view(eyeobj, 14)) - C.images += H.hud_list[NATIONS_HUD] - /mob/living/silicon/ai/update_sight() see_invisible = initial(see_invisible) see_in_dark = initial(see_in_dark) diff --git a/code/modules/mob/living/silicon/ai/update_status.dm b/code/modules/mob/living/silicon/ai/update_status.dm index 18a35534db8..fd001956c67 100644 --- a/code/modules/mob/living/silicon/ai/update_status.dm +++ b/code/modules/mob/living/silicon/ai/update_status.dm @@ -2,7 +2,7 @@ if(status_flags & GODMODE) return if(stat != DEAD) - if(health <= config.health_threshold_dead) + if(health <= HEALTH_THRESHOLD_DEAD && check_death_method()) death() create_debug_log("died of damage, trigger reason: [reason]") return diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 2dd61d9a2ce..d0262df743c 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -1,6 +1,7 @@ /mob/living/silicon/robot/Login() ..() - if(client) - client.hotkeytype = "Cyborg" regenerate_icons() show_laws(0) + + var/datum/hotkey_mode/cyborg/C = new(src) + C.set_winset_values() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 05e3e0b16af..ae6a832f6ac 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -93,7 +93,7 @@ var/list/robot_verbs_default = list( var/updating = 0 //portable camera camerachunk update - hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, NATIONS_HUD) + hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD) var/magpulse = 0 var/ionpulse = 0 // Jetpack-like effect. @@ -288,10 +288,6 @@ var/list/robot_verbs_default = list( if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis) to_chat(src, "Crisis mode active. Combat module available.") modules += "Combat" - if(ticker && ticker.mode && ticker.mode.name == "nations") - var/datum/game_mode/nations/N = ticker.mode - if(N.kickoff) - modules = list("Nations") if(mmi != null && mmi.alien) modules = list("Hunter") modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules @@ -390,11 +386,6 @@ var/list/robot_verbs_default = list( module.channels = list("Security" = 1) icon_state = "droidcombat" - if("Nations") - module = new /obj/item/robot_module/nations(src) - module.channels = list() - icon_state = "droidpeace" - if("Hunter") module = new /obj/item/robot_module/alien/hunter(src) icon_state = "xenoborg-state-a" @@ -415,7 +406,7 @@ var/list/robot_verbs_default = list( feedback_inc("cyborg_[lowertext(modtype)]",1) rename_character(real_name, get_default_name()) - if(modtype == "Medical" || modtype == "Security" || modtype == "Combat" || modtype == "Nations") + if(modtype == "Medical" || modtype == "Security" || modtype == "Combat") status_flags &= ~CANPUSH choose_icon(6,module_sprites) @@ -891,7 +882,7 @@ var/list/robot_verbs_default = list( else overlays += "[panelprefix]-openpanel -c" - var/combat = list("Combat","Nations") + var/combat = list("Combat") if(modtype in combat) if(base_icon == "") base_icon = icon_state @@ -1356,24 +1347,6 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/ert/gamma crisis = 1 -/mob/living/silicon/robot/nations - base_icon = "droidpeace" - icon_state = "droidpeace" - modtype = "Nations" - designation = "Nations" - -/mob/living/silicon/robot/nations/init() - ..() - module = new /obj/item/robot_module/nations(src) - //languages - module.add_languages(src) - //subsystems - module.add_subsystems_and_actions(src) - - status_flags &= ~CANPUSH - - notify_ai(2) - /mob/living/silicon/robot/emp_act(severity) ..() switch(severity) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 5cbdf9f3fa8..699376c927f 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -144,6 +144,7 @@ modules += new /obj/item/robotanalyzer(src) modules += new /obj/item/reagent_scanner/adv(src) modules += new /obj/item/borg_defib(src) + modules += new /obj/item/handheld_defibrillator(src) modules += new /obj/item/roller_holder(src) modules += new /obj/item/reagent_containers/borghypo(src) modules += new /obj/item/reagent_containers/glass/beaker/large(src) @@ -412,6 +413,7 @@ modules += new /obj/item/reagent_scanner/adv(src) modules += new /obj/item/bodyanalyzer/borg/syndicate(src) modules += new /obj/item/borg_defib(src) + modules += new /obj/item/handheld_defibrillator(src) modules += new /obj/item/roller_holder(src) modules += new /obj/item/reagent_containers/borghypo/syndicate(src) modules += new /obj/item/extinguisher/mini(src) @@ -427,6 +429,7 @@ modules += new /obj/item/bonesetter(src) modules += new /obj/item/surgicaldrill(src) modules += new /obj/item/gripper/medical(src) + modules += new /obj/item/gun/medbeam(src) modules += new /obj/item/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon modules += new /obj/item/card/emag(src) modules += new /obj/item/crowbar/cyborg(src) @@ -494,22 +497,6 @@ fix_modules() -/obj/item/robot_module/nations - name = "nations robot module" - module_type = "Malf" - -/obj/item/robot_module/nations/New() - ..() - modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src) - modules += new /obj/item/gun/energy/gun/cyborg(src) - modules += new /obj/item/pickaxe/drill/jackhammer(src) - modules += new /obj/item/borg/combat/shield(src) - modules += new /obj/item/borg/combat/mobility(src) - modules += new /obj/item/wrench/cyborg(src) - emag = new /obj/item/gun/energy/lasercannon/cyborg(src) - - fix_modules() - /obj/item/robot_module/alien/hunter name = "alien hunter module" module_type = "Standard" diff --git a/code/modules/mob/living/silicon/robot/syndicate.dm b/code/modules/mob/living/silicon/robot/syndicate.dm index 48179e8d374..cc5fe804a36 100644 --- a/code/modules/mob/living/silicon/robot/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/syndicate.dm @@ -70,12 +70,17 @@ /mob/living/silicon/robot/syndicate/saboteur/init() ..() module = new /obj/item/robot_module/syndicate_saboteur(src) + var/obj/item/borg/upgrade/selfrepair/SR = new /obj/item/borg/upgrade/selfrepair(src) SR.cyborg = src SR.icon_state = "selfrepair_off" - var/datum/action/A = new /datum/action/item_action/toggle(SR) - A.Grant(src) + var/datum/action/self_repair = new /datum/action/item_action/toggle(SR) + self_repair.Grant(src) + + var/datum/action/thermals = new /datum/action/innate/robot_sight/thermal() + thermals.Grant(src) + /mob/living/silicon/robot/syndicate/saboteur/verb/modify_name() set name = "Modify Name" set desc = "Change your systems' registered name to fool Nanotrasen systems. No cost." diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 20b363051de..5c19dcb0d7a 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -25,7 +25,7 @@ var/next_alarm_notice var/list/datum/alarm/queued_alarms = new() - hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD,NATIONS_HUD) + hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD) var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use @@ -71,6 +71,9 @@ /mob/living/silicon/drop_item() return +/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + return FALSE //So borgs they don't die trying to fix wiring + /mob/living/silicon/emp_act(severity) switch(severity) if(1) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index a0b6652f883..4793b91dee6 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -156,8 +156,8 @@ bot_core = new bot_core_type(src) spawn(30) - if(radio_controller && bot_filter) - radio_controller.add_object(bot_core, control_freq, bot_filter) + if(SSradio && bot_filter) + SSradio.add_object(bot_core, control_freq, bot_filter) prepare_huds() for(var/datum/atom_hud/data/diagnostic/diag_hud in huds) @@ -197,8 +197,8 @@ if(reset_access_timer_id) deltimer(reset_access_timer_id) reset_access_timer_id = null - if(radio_controller && bot_filter) - radio_controller.remove_object(bot_core, control_freq) + if(SSradio && bot_filter) + SSradio.remove_object(bot_core, control_freq) QDEL_NULL(bot_core) return ..() @@ -747,7 +747,7 @@ Pass a positive integer as an argument to override a bot's default speed. /mob/living/simple_animal/bot/proc/post_signal_multiple(var/freq, var/list/keyval) if(z != 1) //Bot control will only work on station. return - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) + var/datum/radio_frequency/frequency = SSradio.return_frequency(freq) if(!frequency) return diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index a6fcf4b5a20..2b3d11357d1 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -85,6 +85,9 @@ /mob/living/simple_animal/hostile/construct/narsie_act() return +/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) + return FALSE + /////////////////Juggernaut/////////////// diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index 9e848f5e18c..07a5fcf0131 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -109,6 +109,8 @@ forceMove(M) else get_scooped(M) + else + ..() /mob/living/simple_animal/diona/proc/merge() if(stat != CONSCIOUS) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 03f353754fe..dd0c5b9f72a 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -31,14 +31,6 @@ /mob/living/simple_animal/hostile/retaliate/goat/handle_automated_movement() ..() - if(!pulledby) - for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) - var/step = get_step(src, direction) - if(step) - if(locate(/obj/structure/spacevine) in step) - Move(step, get_dir(src, step)) - -/mob/living/simple_animal/hostile/retaliate/goat/handle_automated_action() //chance to go crazy and start wacking stuff if(!enemies.len && prob(1)) Retaliate() @@ -46,11 +38,16 @@ if(enemies.len && prob(10)) enemies = list() LoseTarget() - src.visible_message("[src] calms down.") + visible_message("[src] calms down.") - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) + if(stat == CONSCIOUS) + eat_plants() + if(!pulledby) + for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) + var/step = get_step(src, direction) + if(step) + if(locate(/obj/structure/spacevine) in step || locate(/obj/structure/glowshroom) in step) + Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Life(seconds, times_fired) . = ..() @@ -60,30 +57,52 @@ /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() ..() - src.visible_message("[src] gets an evil-looking gleam in their eye.") + visible_message("[src] gets an evil-looking gleam in their eye.") /mob/living/simple_animal/hostile/retaliate/goat/Move() - ..() + . = ..() if(!stat) - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) + eat_plants() -/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass)) +/mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants() + var/eaten = FALSE + var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc + if(SV) + SV.eat(src) + eaten = TRUE + + var/obj/structure/glowshroom/GS = locate(/obj/structure/glowshroom) in loc + if(GS) + qdel(GS) + eaten = TRUE + + if(eaten && prob(10)) + say("Nom") + +/mob/living/simple_animal/hostile/retaliate/goat/attackby(obj/item/I, mob/user, params) + if(stat == CONSCIOUS && istype(I, /obj/item/reagent_containers/glass)) user.changeNext_move(CLICK_CD_MELEE) - var/obj/item/reagent_containers/glass/G = O + var/obj/item/reagent_containers/glass/G = I var/transfered = min(milk_content, rand(5,10), (G.volume - G.reagents.total_volume)) if(transfered > 0) - user.visible_message("[user] milks [src] using \the [O].") + user.visible_message("[user] milks [src] using [G].") G.reagents.add_reagent("milk", transfered) milk_content -= transfered else if(G.reagents.total_volume >= G.volume) - to_chat(user, "\The [O] is full.") + to_chat(user, "[G] is full.") else to_chat(user, "The udder is dry. Wait a bit longer...") + return TRUE else - ..() + return ..() + +/mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget() + ..() + if(isdiona(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/NB = pick(H.bodyparts) + H.visible_message("[src] takes a big chomp out of [H]!", "[src] takes a big chomp out of your [NB.name]!") + NB.droplimb() //cow /mob/living/simple_animal/cow diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 4516a44a935..5ebefeba405 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -11,7 +11,7 @@ /mob/living/simple_animal/hostile/poison/bees name = "bee" - desc = "buzzy buzzy bee, stingy sti- Ouch!" + desc = "Buzzy buzzy bee, stingy sti- Ouch!" icon_state = "" icon_living = "" icon = 'icons/mob/bees.dmi' @@ -33,25 +33,28 @@ environment_smash = 0 mouse_opacity = MOUSE_OPACITY_OPAQUE pass_flags = PASSTABLE | PASSGRILLE | PASSMOB - flying = 1 - search_objects = 1 //have to find those plant trays! - density = 0 + density = FALSE mob_size = MOB_SIZE_TINY + flying = TRUE + search_objects = TRUE //have to find those plant trays! //Spaceborn beings don't get hurt by space atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 - del_on_death = 1 + del_on_death = TRUE var/datum/reagent/beegent = null //hehe, beegent var/obj/structure/beebox/beehome = null - var/isqueen = FALSE var/idle = 0 + var/isqueen = FALSE + var/bee_syndicate = FALSE var/icon_base = "bee" var/static/list/bee_icons = list() + var/static/beehometypecache = typecacheof(/obj/structure/beebox) + var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics) /mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0) - return 1 + return TRUE /mob/living/simple_animal/hostile/poison/bees/New() ..() @@ -65,6 +68,20 @@ beehome = null return ..() +/mob/living/simple_animal/hostile/poison/bees/death(gibbed) + . = ..() + if(!.) + return + if(beehome) + if(beehome.bees) + beehome.bees.Remove(src) + beehome = null + +/mob/living/simple_animal/hostile/poison/bees/examine(mob/user) + ..() + if(!bee_syndicate && !beehome) + to_chat(user, "This bee is homeless!") + /mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals() overlays.Cut() @@ -94,21 +111,45 @@ //We don't attack beekeepers/people dressed as bees//Todo: bee costume /mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target) . = ..() - return . + if(!.) + return FALSE + if(!bee_syndicate && isliving(the_target)) + var/mob/living/H = the_target + return !H.bee_friendly() /mob/living/simple_animal/hostile/poison/bees/Found(atom/A) if(isliving(A)) - var/mob/living/L = A - return !L.bee_friendly() - return 0 + var/mob/living/H = A + return !H.bee_friendly() + if(istype(A, /obj/machinery/hydroponics)) + var/obj/machinery/hydroponics/Hydro = A + if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit) + wanted_objects |= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted + return TRUE + return FALSE /mob/living/simple_animal/hostile/poison/bees/AttackingTarget() - if(beegent && isliving(target)) - var/mob/living/L = target - if(!isnull(target.reagents)) - beegent.reaction_mob(L, INGEST) - L.reagents.add_reagent(beegent.id, rand(1,5)) - target.attack_animal(src) + //Pollinate + if(istype(target, /obj/machinery/hydroponics)) + var/obj/machinery/hydroponics/Hydro = target + pollinate(Hydro) + else if(istype(target, /obj/structure/beebox)) + if(target == beehome) + var/obj/structure/beebox/BB = target + forceMove(BB) + target = null + wanted_objects -= beehometypecache //so we don't attack beeboxes when not going home + return //no don't attack the goddamm box + else + ..() + if(isliving(target)) + var/mob/living/L = target + if(L.reagents) + if(beegent) + beegent.reaction_mob(L, INGEST) + L.reagents.add_reagent(beegent.id, rand(1, 5)) + else + L.reagents.add_reagent("spidertoxin", 5) /mob/living/simple_animal/hostile/poison/bees/proc/assign_reagent(datum/reagent/R) if(istype(R)) @@ -116,81 +157,13 @@ name = "[initial(name)] ([R.name])" generate_bee_visuals() -/mob/living/simple_animal/hostile/poison/bees/handle_automated_action() - . = ..() - if(!.) - return - -/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B) - if(!B) - return 0 - if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent) - return 1 - return 0 - -//Botany Worker Bees -/mob/living/simple_animal/hostile/poison/bees/worker - //Blank type define in case we need to give them special stuff later, plus organization (currently they are same as base type bee) - - -/mob/living/simple_animal/hostile/poison/bees/worker/Destroy() - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - return ..() - -/mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed) - . = ..() - if(!.) - return - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - -/mob/living/simple_animal/hostile/poison/bees/worker/examine(mob/user) - ..() - - if(!beehome) - to_chat(user, "This bee is homeless!") - -/mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A) - if(istype(A, /obj/machinery/hydroponics)) - var/obj/machinery/hydroponics/Hydro = A - if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.lid_state) - wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered - return 1 - ..() - -/mob/living/simple_animal/hostile/poison/bees/worker/CanAttack(atom/the_target) - . = ..() - if(!.) - return 0 - if(isliving(the_target)) //Should ignore ghosts and camera mobs already, but just in case - var/mob/living/L = the_target - return !L.bee_friendly() - -/mob/living/simple_animal/hostile/poison/bees/worker/AttackingTarget() - //Pollinate - if(istype(target, /obj/machinery/hydroponics)) - var/obj/machinery/hydroponics/Hydro = target - pollinate(Hydro) - else if(target == beehome) - var/obj/structure/beebox/BB = target - forceMove(BB) - target = null - wanted_objects -= /obj/structure/beebox //so we don't attack beeboxes when not going home - else - ..() - -/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro) +/mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/hydroponics/Hydro) if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state) target = null return target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity - wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered + wanted_objects -= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted Hydro.recent_bee_visit = TRUE spawn(BEE_TRAY_RECENT_VISIT) if(Hydro) @@ -210,68 +183,79 @@ if(beehome) beehome.bee_resources = min(beehome.bee_resources + growth, 100) -/mob/living/simple_animal/hostile/poison/bees/worker/handle_automated_action() +/mob/living/simple_animal/hostile/poison/bees/handle_automated_action() . = ..() if(!.) return - if(!isqueen) - if(loc == beehome) - idle = min(100, ++idle) - if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM)) - forceMove(get_turf(beehome)) - else - idle = max(0, --idle) - if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME)) - if(!FindTarget()) - wanted_objects += /obj/structure/beebox //so we don't attack beeboxes when not going home - target = beehome - if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home - for(var/obj/structure/beebox/BB in view(vision_range, src)) - if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees()) - continue - BB.bees |= src - beehome = BB - + if(!bee_syndicate) + if(!isqueen) + if(loc == beehome) + idle = min(100, ++idle) + if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM)) + forceMove(beehome.drop_location()) + else + idle = max(0, --idle) + if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME)) + if(!FindTarget()) + wanted_objects |= beehometypecache //so we don't attack beeboxes when not going home + target = beehome + if(!beehome) //add ourselves to a beebox (of the same reagent) if we have no home + for(var/obj/structure/beebox/BB in view(vision_range, src)) + if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees()) + continue + BB.bees |= src + beehome = BB + break // End loop after the first compatible find. //Botany Queen Bee /mob/living/simple_animal/hostile/poison/bees/queen name = "queen bee" - desc = "she's the queen of bees, BZZ BZZ" + desc = "She's the queen of bees, BZZ BZZ" icon_base = "queen" isqueen = TRUE - //the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself +//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself /mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A) - return 0 + return FALSE + +//leave pollination for the peasent bees +/mob/living/simple_animal/hostile/poison/bees/queen/AttackingTarget() + ..() + if(beegent && isliving(target)) + var/mob/living/L = target + beegent.reaction_mob(L, TOUCH) + L.reagents.add_reagent(beegent.id, rand(1, 5)) + +//PEASENT BEES +/mob/living/simple_animal/hostile/poison/bees/queen/pollinate() + return + +/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B) + if(!B) + return FALSE + if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent) + return TRUE + return FALSE -/mob/living/simple_animal/hostile/poison/bees/queen/CanAttack(atom/the_target) - . = ..() - if(!.) - return 0 - if(isliving(the_target)) //Should ignore ghosts and camera mobs already, but just in case - var/mob/living/L = the_target - return !L.bee_friendly() /obj/item/queen_bee name = "queen bee" - desc = "she's the queen of bees, BZZ BZZ" + desc = "She's the queen of bees, BZZ BZZ" icon_state = "queen_item" item_state = "" icon = 'icons/mob/bees.dmi' var/mob/living/simple_animal/hostile/poison/bees/queen/queen + /obj/item/queen_bee/attackby(obj/item/I, mob/user, params) - if(istype(I,/obj/item/reagent_containers/syringe)) + if(istype(I, /obj/item/reagent_containers/syringe)) var/obj/item/reagent_containers/syringe/S = I if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped - if(S.reagents.has_reagent("royal_bee_jelly",5)) + if(S.reagents.has_reagent("royal_bee_jelly", 5)) S.reagents.remove_reagent("royal_bee_jelly", 5) - if(!queen.beegent.can_synth) - to_chat(user, "You inject [src] with the royal bee jelly. It's ineffective! Maybe it's something to do with the [src] reagent.") - return - var/obj/item/queen_bee/qb = new(get_turf(user)) + var/obj/item/queen_bee/qb = new(user.drop_location()) qb.queen = new(qb) if(queen && queen.beegent) qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents. @@ -282,16 +266,17 @@ else var/datum/reagent/R = GLOB.chemical_reagents_list[S.reagents.get_master_reagent_id()] if(R && S.reagents.has_reagent(R.id, 5)) - S.reagents.remove_reagent(R.id,5) + S.reagents.remove_reagent(R.id, 5) queen.assign_reagent(R) - user.visible_message("[user] injects [src]'s genome with [R.name], mutating it's DNA!","You inject [src]'s genome with [R.name], mutating it's DNA!") + user.visible_message("[user] injects [src]'s genome with [R.name], mutating its DNA!", "You inject [src]'s genome with [R.name], mutating its DNA!") name = queen.name else to_chat(user, "You don't have enough units of that chemical to modify the bee's DNA!") - ..() + else + return ..() -/obj/item/queen_bee/bought/New() - ..() +/obj/item/queen_bee/bought/Initialize(mapload) + . = ..() queen = new(src) /obj/item/queen_bee/Destroy() @@ -299,7 +284,6 @@ return ..() - //Syndicate Bees /mob/living/simple_animal/hostile/poison/bees/syndi name = "syndi-bee" @@ -309,10 +293,14 @@ maxHealth = 25 health = 25 faction = list("hostile", "syndicate") - search_objects = 0 //these bees don't care about trivial things like plants, especially when there is havoc to sow - beegent = new /datum/reagent/facid() //prepare to die + search_objects = FALSE //these bees don't care about trivial things like plants, especially when there is havoc to sow + bee_syndicate = TRUE var/list/master_and_friends = list() +/mob/living/simple_animal/hostile/poison/bees/syndi/New() + beegent = GLOB.chemical_reagents_list["facid"] //Prepare to die + ..() + /mob/living/simple_animal/hostile/poison/bees/syndi/Destroy() master_and_friends.Cut() return ..() @@ -320,24 +308,27 @@ /mob/living/simple_animal/hostile/poison/bees/syndi/assign_reagent(datum/reagent/R) return -/mob/living/simple_animal/hostile/poison/bees/syndi/Found(atom/A) - return CanAttack(A) +/mob/living/simple_animal/hostile/poison/bees/syndi/pollinate() // No Pollination + return + +/mob/living/simple_animal/hostile/poison/bees/syndi/Found(atom/A) //Typical usual hostile mob targeting list + return /mob/living/simple_animal/hostile/poison/bees/syndi/CanAttack(atom/the_target) . = ..() if(!.) - return 0 + return FALSE if(isliving(the_target)) var/mob/living/L = the_target if(ishuman(L)) var/mob/living/carbon/human/H = L if(H in master_and_friends) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/hostile/poison/bees/syndi/AttackingTarget() ..() if(target && isliving(target)) var/mob/living/L = target if(L.stat) - LoseTarget() + LoseTarget() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm index 9ac2d899456..244edaeedec 100644 --- a/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm +++ b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm @@ -142,7 +142,7 @@ return -/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)//prevents runtimes with machine fuckery +/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) //prevents runtimes with machine fuckery return FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm index 450f6767892..f3e110d0099 100644 --- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm +++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm @@ -71,7 +71,7 @@ else if(health > (maxHealth*0.25)) msgs += "It is covered in wounds!" if(resting) - if(bruteloss > 0 || fireloss > 0) + if(getBruteLoss() || getFireLoss()) msgs += "It is currently licking its wounds, regenerating the damage to its body!" else msgs += "It is currently resting." @@ -79,7 +79,7 @@ /mob/living/simple_animal/hostile/hellhound/Life(seconds, times_fired) . = ..() - if(stat != DEAD && resting && (bruteloss > 0) || (fireloss > 0)) + if(stat != DEAD && resting && (getBruteLoss() || getFireLoss())) if(life_regen_cycles >= life_regen_cycle_trigger) life_regen_cycles = 0 to_chat(src, "You lick your wounds, helping them close.") @@ -91,7 +91,7 @@ /mob/living/simple_animal/hostile/hellhound/proc/wants_to_rest() if(target) return FALSE - if(bruteloss > 0 || fireloss > 0) + if(getBruteLoss() || getFireLoss()) return TRUE return FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index ccbd37f2f4c..50568fb37d0 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -53,6 +53,7 @@ if(!targets_from) targets_from = src environment_target_typecache = typecacheof(environment_target_typecache) + wanted_objects = typecacheof(wanted_objects) /mob/living/simple_animal/hostile/Destroy() targets_from = null @@ -205,7 +206,7 @@ return 0 return 1 if(isobj(the_target)) - if(is_type_in_list(the_target, wanted_objects)) + if(is_type_in_typecache(the_target, wanted_objects)) return 1 return 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm index 4041e95c6c7..74a28c58c3f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -98,7 +98,7 @@ /obj/item/organ/internal/hivelord_core/on_life() ..() - if(owner.health < config.health_threshold_crit) + if(owner.health < HEALTH_THRESHOLD_CRIT) ui_action_click() /obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 0f37482b3e2..81b384f56b7 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -238,8 +238,8 @@ if(istype(target, /obj/item/clothing/suit/space/hardsuit/mining) || istype(target, /obj/item/clothing/head/helmet/space/hardsuit/mining) || istype(target, /obj/item/clothing/suit/space/eva/plasmaman/miner) || istype(target, /obj/item/clothing/head/helmet/space/eva/plasmaman/miner)) var/obj/item/clothing/C = target var/current_armor = C.armor - if(current_armor.["melee"] < 60) - current_armor.["melee"] = min(current_armor.["melee"] + 10, 60) + if(current_armor["melee"] < 60) + current_armor["melee"] = min(current_armor["melee"] + 10, 60) to_chat(user, "You strengthen [target], improving its resistance against melee attacks.") qdel(src) else @@ -260,7 +260,7 @@ qdel(src) D.overlays += image("icon"="mecha.dmi", "icon_state"="ripley-g-open") D.desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates." - if(damage_absorption.["brute"] == 0.3) + if(damage_absorption["brute"] == 0.3) D.overlays += image("icon"="mecha.dmi", "icon_state"="ripley-g-full-open") D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - the pilot must be an experienced monster hunter." else diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm index 51028a69111..14353c4dfd0 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm @@ -24,6 +24,12 @@ canlay = 1000 spider_tier = TS_TIER_5 projectiletype = /obj/item/projectile/terrorqueenspit/empress + icon = 'icons/mob/terrorspider64.dmi' + pixel_x = -16 + mob_size = MOB_SIZE_LARGE + icon_state = "terror_empress" + icon_living = "terror_empress" + icon_dead = "terror_empress_dead" var/datum/action/innate/terrorspider/queen/empress/empresslings/empresslings_action var/datum/action/innate/terrorspider/queen/empress/empresserase/empresserase_action atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) @@ -42,7 +48,7 @@ queenfakelings_action.button.name = "Empress Lings" /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/LayQueenEggs() - var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE) + var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE, TS_DESC_BROWN) var/numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50) if(eggtype == null || numlings == null) to_chat(src, "Cancelled.") @@ -60,6 +66,8 @@ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings) if(TS_DESC_WHITE) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, numlings) + if(TS_DESC_BROWN) + DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, numlings) if(TS_DESC_PRINCE) DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, numlings) if(TS_DESC_PRINCESS) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm index 354f99db8af..d1e171d2f55 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm @@ -38,6 +38,8 @@ if(can_die()) if(spider_awaymission && !is_away_level(z)) canspawn = FALSE + if(degenerate) + canspawn = FALSE if(canspawn) canspawn = FALSE for(var/i in 0 to spawn_count) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm index ed2ea164634..2839dedb237 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm @@ -142,9 +142,8 @@ visible_message("\The [src] looks around warily - then seeks a better nesting ground.") path_to_vent = 1 else - visible_message("\The [src] looks around, searching for the vent that should be there, but isn't. A bluespace portal forms on her, and she is gone.") - qdel(src) - new /obj/effect/portal(get_turf(loc)) + neststep = -1 + message_admins("Warning: [key_name_admin(src)] was spawned in an area without a vent! This is likely a mapping/spawn mistake. This mob's AI has been permanently deactivated.") if(1) // No nest, and we should create one. Start NestMode(), then advance to step 2. if(world.time > (lastnestsetup + nestfrequency)) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index c797d51ce3b..39c03feb928 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -316,12 +316,12 @@ var/global/list/ts_spiderling_list = list() adjustToxLoss(rand(1,10)) if(regen_points < regen_points_max) regen_points += regen_points_per_tick - if((bruteloss > 0) || (fireloss > 0)) + if(getBruteLoss() || getFireLoss()) if(regen_points > regen_points_per_hp) - if(bruteloss > 0) + if(getBruteLoss()) adjustBruteLoss(-1) regen_points -= regen_points_per_hp - else if(fireloss > 0) + else if(getFireLoss()) adjustFireLoss(-1) regen_points -= regen_points_per_hp if(prob(5)) diff --git a/code/modules/mob/living/simple_animal/pony.dm b/code/modules/mob/living/simple_animal/pony.dm deleted file mode 100644 index 960f8fc0998..00000000000 --- a/code/modules/mob/living/simple_animal/pony.dm +++ /dev/null @@ -1,129 +0,0 @@ -/mob/living/simple_animal/pony - name = "\improper pony" - desc = "A bound spirit" - icon = 'icons/mob/pony.dmi' -// icon_dead = "shade_dead" - maxHealth = 50 - health = 50 - speak_emote = list("whinnys") - emote_hear = list("excitedly says") - response_help = "pets" - response_disarm = "pushes" - response_harm = "kicks" - melee_damage_lower = 5 - melee_damage_upper = 15 - attacktext = "sends rainbows of power to" - minbodytemp = 0 - maxbodytemp = 4000 - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - speed = 0 - stop_automated_movement = 0 - status_flags = 0 - faction = list("pony") - status_flags = CANPUSH - universal_speak = 1 - -/mob/living/simple_animal/pony/Life() - ..() - if(stat == 2) - new /obj/item/reagent_containers/food/snacks/ectoplasm(src.loc) - src.visible_message("[src] lets out a contented sigh as [p_their()] form unwinds.") - src.ghostize() - qdel(src) - return - -/mob/living/simple_animal/pony/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri - if(istype(O, /obj/item/soulstone)) - O.transfer_soul("SHADE", src, user) - else - ..() - -/mob/living/simple_animal/pony/twilight - name = "Twilight Sparkle" - real_name = "Twilight Sparkle" - icon_state = "twilight" - icon_living = "twilight" - -/mob/living/simple_animal/pony/pinkie - name = "Pinkie Pie" - real_name = "Pinkie Pie" - icon_state = "pinkie" - icon_living = "pinkie" - -/mob/living/simple_animal/pony/rainbow - name = "Rainbow Dash" - real_name = "Rainbow Dash" - icon_state = "rainbow" - icon_living = "rainbow" - -mob/living/simple_animal/pony/fluttershy - name = "Fluttershy" - real_name = "Fluttershy" - icon_state = "fluttershy" - icon_living = "fluttershy" - -mob/living/simple_animal/pony/applejack - name = "Applejack" - real_name = "Applejack" - icon_state = "applejack" - icon_living = "applejack" - -mob/living/simple_animal/pony/luna - name = "Luna" - real_name = "Luna" - icon_state = "luna" - icon_living = "luna" - -mob/living/simple_animal/pony/clownie - name = "Clownie" - real_name = "Clownie" - icon_state = "clownie" - icon_living = "clownie" - -mob/living/simple_animal/pony/tia - name = "Tia" - real_name = "Tia" - icon_state = "tia" - icon_living = "tia" - -mob/living/simple_animal/pony/trixie - name = "Trixie" - real_name = "Trixie" - icon_state = "trixie_a_full" - icon_living = "trixing_a_full" - -mob/living/simple_animal/pony/lyra - name = "Lyra" - real_name = "Lyra" - icon_state = "lyra" - icon_living = "lyra" - -mob/living/simple_animal/pony/vinyl - name = "Vinyl" - real_name = "Vinyl" - icon_state = "vinyl" - icon_living = "vinyl" - -mob/living/simple_animal/pony/rarity - name = "Rarity" - real_name = "Rarity" - icon_state = "rarity" - icon_living = "rarity" - -mob/living/simple_animal/pony/whooves - name = "Whooves" - real_name = "Whooves" - icon_state = "whooves" - icon_living = "whooves" - -mob/living/simple_animal/pony/fleur - name = "Fleur" - real_name = "Fleur" - icon_state = "fleur" - icon_living = "fleur" - -mob/living/simple_animal/pony/mac - name = "Mac" - real_name = "Mac" - icon_state = "mac" - icon_living = "mac" \ No newline at end of file diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm index fa5530091c9..70cced62aab 100644 --- a/code/modules/mob/living/stat_states.dm +++ b/code/modules/mob/living/stat_states.dm @@ -33,7 +33,7 @@ /mob/living/proc/can_be_revived() . = TRUE // if(health <= min_health) - if(health <= config.health_threshold_dead) + if(health <= HEALTH_THRESHOLD_DEAD) return FALSE // death() is used to make a mob die @@ -71,3 +71,6 @@ spell.updateButtonIcon() return 1 + +/mob/living/proc/check_death_method() + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 4e5c778b7fb..d47f21b8d46 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -297,6 +297,9 @@ SetLoseBreath(max(losebreath, amount)) /mob/living/SetLoseBreath(amount) + if(BREATHLESS in mutations) + losebreath = 0 + return FALSE losebreath = max(amount, 0) /mob/living/AdjustLoseBreath(amount, bound_lower = 0, bound_upper = INFINITY) diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index daf058bb41b..bec41f68698 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -110,7 +110,7 @@ if(status_flags & GODMODE) return if(stat != DEAD) - if(health <= config.health_threshold_dead) + if(health <= HEALTH_THRESHOLD_DEAD && check_death_method()) death() create_debug_log("died of damage, trigger reason: [reason]") else if(paralysis || status_flags & FAKEDEATH) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index eecd0650af0..fc265722f4a 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -72,29 +72,3 @@ update_client_colour(0) callHook("mob_login", list("client" = client, "mob" = src)) - -// Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget(). -// Calling it in the overriden Login, such as /mob/living/Login() doesn't cause this. -/mob/proc/update_interface() - spawn() // Spawn off so winget/winset don't delay callers. - if(client) - if(winget(src, "mainwindow.hotkey_toggle", "is-checked") == "true") - update_hotkey_mode() - else - update_normal_mode() - -/mob/proc/update_hotkey_mode() - var/hotkeyname = "hotkeymode" - if(client) - var/hotkeys = client.hotkeylist[client.hotkeytype] - hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"] - client.hotkeyon = 1 - winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0") - -/mob/proc/update_normal_mode() - var/hotkeyname = "macro" - if(client) - var/hotkeys = client.hotkeylist[client.hotkeytype]//get the list containing the hotkey names - hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"]//get the name of the hotkey, to not clutter winset() to much - client.hotkeyon = 0 - winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e0d20f01a48..ee04e624f02 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -580,6 +580,10 @@ var/list/slot_equipment_priority = list( \ to_chat(src, "Something is there but you can't see it.") return 1 + var/is_antag = (isAntag(src) || isobserver(src)) //ghosts don't have minds + if(client) + client.update_description_holders(A, is_antag) + face_atom(A) A.examine(src) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 77c74c4396e..3e9ff0b7ba6 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -173,6 +173,9 @@ //SSD var, changed it up some so people can have special things happen for different mobs when SSD. var/player_logged = 0 + //Ghosted var, set only if a player has manually ghosted out of this mob. + var/player_ghosted = 0 + var/turf/listed_turf = null //the current turf being examined in the stat panel var/list/shouldnt_see = list(/atom/movable/lighting_overlay) //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 80303c1dcd1..a46b9a94fc7 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -256,7 +256,7 @@ new_player_panel() /mob/new_player/proc/IsJobAvailable(rank) - var/datum/job/job = job_master.GetJob(rank) + var/datum/job/job = SSjobs.GetJob(rank) if(!job) return 0 if(!job.is_position_available()) return 0 if(jobban_isbanned(src,rank)) return 0 @@ -269,9 +269,9 @@ if(config.assistantlimit) if(job.title == "Civilian") var/count = 0 - var/datum/job/officer = job_master.GetJob("Security Officer") - var/datum/job/warden = job_master.GetJob("Warden") - var/datum/job/hos = job_master.GetJob("Head of Security") + var/datum/job/officer = SSjobs.GetJob("Security Officer") + var/datum/job/warden = SSjobs.GetJob("Warden") + var/datum/job/hos = SSjobs.GetJob("Head of Security") count += (officer.current_positions + warden.current_positions + hos.current_positions) if(job.current_positions > (config.assistantratio * count)) if(count >= 5) // if theres more than 5 security on the station just let assistants join regardless, they should be able to handle the tide @@ -280,21 +280,21 @@ return 1 /mob/new_player/proc/IsAdminJob(rank) - var/datum/job/job = job_master.GetJob(rank) + var/datum/job/job = SSjobs.GetJob(rank) if(job.admin_only) return 1 else return 0 /mob/new_player/proc/IsERTSpawnJob(rank) - var/datum/job/job = job_master.GetJob(rank) + var/datum/job/job = SSjobs.GetJob(rank) if(job.spawn_ert) return 1 else return 0 /mob/new_player/proc/IsSyndicateCommand(rank) - var/datum/job/job = job_master.GetJob(rank) + var/datum/job/job = SSjobs.GetJob(rank) if(job.syndicate_command) return 1 else @@ -312,15 +312,15 @@ if(!IsJobAvailable(rank)) to_chat(src, alert("[rank] is not available. Please try another.")) return 0 - var/datum/job/thisjob = job_master.GetJob(rank) + var/datum/job/thisjob = SSjobs.GetJob(rank) if(thisjob.barred_by_disability(client)) to_chat(src, alert("[rank] is not available due to your character's disability. Please try another.")) return 0 - job_master.AssignRole(src, rank, 1) + SSjobs.AssignRole(src, rank, 1) var/mob/living/character = create_character() //creates the human and transfers vars and mind - character = job_master.AssignRank(character, rank, 1) //equips the human + character = SSjobs.AssignRank(character, rank, 1) //equips the human // AIs don't need a spawnpoint, they must spawn at an empty core if(character.mind.assigned_role == "AI") @@ -367,7 +367,7 @@ character.buckled.loc = character.loc character.buckled.dir = character.dir - character = job_master.EquipRank(character, rank, 1) //equips the human + character = SSjobs.EquipRank(character, rank, 1) //equips the human EquipCustomItems(character) ticker.mode.latespawn(character) @@ -384,8 +384,8 @@ callHook("latespawn", list(character)) AddEmploymentContract(character) - if(!thisjob.is_position_available() && thisjob in job_master.prioritized_jobs) - job_master.prioritized_jobs -= thisjob + if(!thisjob.is_position_available() && thisjob in SSjobs.prioritized_jobs) + SSjobs.prioritized_jobs -= thisjob qdel(src) @@ -452,11 +452,11 @@ else if(SSshuttle.emergency.mode >= SHUTTLE_CALL) dat += "The station is currently undergoing evacuation procedures.
" - if(length(job_master.prioritized_jobs)) + if(length(SSjobs.prioritized_jobs)) dat += "The station has flagged these jobs as high priority: " - var/amt = length(job_master.prioritized_jobs) + var/amt = length(SSjobs.prioritized_jobs) var/amt_count - for(var/datum/job/a in job_master.prioritized_jobs) + for(var/datum/job/a in SSjobs.prioritized_jobs) amt_count++ if(amt_count != amt) dat += " [a.title], " @@ -478,7 +478,7 @@ "Science" = list(jobs = list(), titles = science_positions, color = "#e6b3e6"), "Supply" = list(jobs = list(), titles = supply_positions, color = "#ead4ae"), ) - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(job && IsJobAvailable(job.title) && !job.barred_by_disability(client)) activePlayers[job] = 0 var/categorized = 0 @@ -512,7 +512,7 @@ dat += "
" dat += "[jobcat]" for(var/datum/job/job in categorizedJobs[jobcat]["jobs"]) - if(job in job_master.prioritized_jobs) + if(job in SSjobs.prioritized_jobs) dat += "[job.title] ([job.current_positions]) (Active: [activePlayers[job]])
" else dat += "[job.title] ([job.current_positions]) (Active: [activePlayers[job]])
" diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 84ac1ed9eb0..64f9e139542 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -385,19 +385,22 @@ if(underwear && (current_species.clothing_flags & HAS_UNDERWEAR)) var/datum/sprite_accessory/underwear/U = GLOB.underwear_list[underwear] if(U) - underwear_s = new/icon(U.icon, "uw_[U.icon_state]_s", ICON_OVERLAY) + var/u_icon = U.sprite_sheets && (current_species.name in U.sprite_sheets) ? U.sprite_sheets[current_species.name] : U.icon //Species-fit the undergarment. + underwear_s = new/icon(u_icon, "uw_[U.icon_state]_s", ICON_OVERLAY) var/icon/undershirt_s = null if(undershirt && (current_species.clothing_flags & HAS_UNDERSHIRT)) var/datum/sprite_accessory/undershirt/U2 = GLOB.undershirt_list[undershirt] if(U2) - undershirt_s = new/icon(U2.icon, "us_[U2.icon_state]_s", ICON_OVERLAY) + var/u2_icon = U2.sprite_sheets && (current_species.name in U2.sprite_sheets) ? U2.sprite_sheets[current_species.name] : U2.icon + undershirt_s = new/icon(u2_icon, "us_[U2.icon_state]_s", ICON_OVERLAY) var/icon/socks_s = null if(socks && (current_species.clothing_flags & HAS_SOCKS)) var/datum/sprite_accessory/socks/U3 = GLOB.socks_list[socks] if(U3) - socks_s = new/icon(U3.icon, "sk_[U3.icon_state]_s", ICON_OVERLAY) + var/u3_icon = U3.sprite_sheets && (current_species.name in U3.sprite_sheets) ? U3.sprite_sheets[current_species.name] : U3.icon + socks_s = new/icon(u3_icon, "sk_[U3.icon_state]_s", ICON_OVERLAY) var/icon/clothes_s = null var/uniform_dmi='icons/mob/uniform.dmi' diff --git a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm index 41dd75a49e5..10f7b1acd46 100644 --- a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm @@ -49,6 +49,7 @@ // Restrict some styles to specific species var/list/species_allowed = list("Human", "Slime People") + var/list/sprite_sheets = list() //For accessories common across species but need to use 'fitted' sprites (like underwear). e.g. list("Vox" = 'icons/mob/species/vox/iconfile.dmi') var/list/models_allowed = list() //Specifies which, if any, hairstyles or markings can be accessed by which prosthetics. Should equal the manufacturing company name in robolimbs.dm. var/list/heads_allowed = null //Specifies which, if any, alt heads a head marking, hairstyle or facial hair style is compatible with. var/list/tails_allowed = null //Specifies which, if any, tails a tail marking is compatible with. @@ -132,7 +133,7 @@ /datum/sprite_accessory/skin/human name = "Default human skin" icon_state = "default" - species_allowed = list("Human",) + species_allowed = list("Human") /datum/sprite_accessory/skin/human/human_tatt01 name = "Tatt01 human skin" @@ -167,7 +168,8 @@ /////////////////////////// /datum/sprite_accessory/underwear icon = 'icons/mob/underwear.dmi' - species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask") + species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi') gender = NEUTER /datum/sprite_accessory/underwear/nude @@ -293,7 +295,8 @@ //////////////////////////// /datum/sprite_accessory/undershirt icon = 'icons/mob/underwear.dmi' - species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask") + species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi') gender = NEUTER /datum/sprite_accessory/undershirt/nude @@ -529,7 +532,8 @@ /////////////////////// /datum/sprite_accessory/socks icon = 'icons/mob/underwear.dmi' - species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask") + species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi') gender = NEUTER /datum/sprite_accessory/socks/nude @@ -566,6 +570,10 @@ icon_state = "thin_knee" gender = FEMALE +/datum/sprite_accessory/socks/striped_norm + name = "Normal Striped" + icon_state = "striped_norm" + /datum/sprite_accessory/socks/striped_knee name = "Knee-high Striped" icon_state = "striped_knee" @@ -603,50 +611,3 @@ /datum/sprite_accessory/socks/black_fishnet name = "Black Fishnet" icon_state = "black_fishnet" - -/datum/sprite_accessory/socks/vox - species_allowed = list("Vox") - -/datum/sprite_accessory/socks/vox/vox_white - name = "Vox White" - icon_state = "vox_white" - -/datum/sprite_accessory/socks/vox/vox_black - name = "Vox Black" - icon_state = "vox_black" - -/datum/sprite_accessory/socks/vox/vox_thin - name = "Vox Black Thin" - icon_state = "vox_blackthin" - -/datum/sprite_accessory/socks/vox/vox_rainbow - name = "Vox Rainbow" - icon_state = "vox_rainbow" - -/datum/sprite_accessory/socks/vox/vox_stripped - name = "Vox Striped" - icon_state = "vox_white" - -/datum/sprite_accessory/socks/vox/vox_white_thigh - name = "Vox Thigh-high White" - icon_state = "vox_whiteTH" - -/datum/sprite_accessory/socks/vox/vox_black_thigh - name = "Vox Thigh-high Black" - icon_state = "vox_blackTH" - -/datum/sprite_accessory/socks/vox/vox_thin_thigh - name = "Vox Thigh-high Thin" - icon_state = "vox_blackthinTH" - -/datum/sprite_accessory/socks/vox/vox_rainbow_thigh - name = "Vox Thigh-high Rainbow" - icon_state = "vox_rainbowTH" - -/datum/sprite_accessory/socks/vox/vox_striped_thigh - name = "Vox Thigh-high Striped" - icon_state = "vox_stripedTH" - -/datum/sprite_accessory/socks/vox/vox_fishnet - name = "Vox Fishnets" - icon_state = "vox_fishnet" \ No newline at end of file diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index a1ed4f0bde9..d3a8765cf86 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -289,8 +289,6 @@ return 1 if(ispath(MP, /mob/living/simple_animal/parrot)) return 1 - if(ispath(MP, /mob/living/simple_animal/pony)) - return 1 if(!GAMEMODE_IS_NUCLEAR) if(ispath(MP, /mob/living/simple_animal/pet/fox/Syndifox)) return 0 diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index 9c6c8f2fa73..9ad5449ee8b 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -39,7 +39,7 @@ var/global/image/typing_indicator set_typing_indicator(1) hud_typing = 1 - var/message = input("","say (text)") as null|text + var/message = typing_input(src, "", "say (text)") hud_typing = 0 set_typing_indicator(0) if(message) @@ -49,9 +49,10 @@ var/global/image/typing_indicator set name = ".Me" set hidden = 1 + set_typing_indicator(1) hud_typing = 1 - var/message = input("","me (text)") as null|text + var/message = typing_input(src, "", "me (text)") hud_typing = 0 set_typing_indicator(0) if(message) diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm index d67268716a5..38a42222c63 100644 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -72,7 +72,7 @@ /datum/computer_file/program/card_mod/proc/format_job_slots() var/list/formatted = list() - for(var/datum/job/job in job_master.occupations) + for(var/datum/job/job in SSjobs.occupations) if(job_blacklisted(job)) continue formatted.Add(list(list( @@ -127,10 +127,10 @@ /datum/computer_file/program/card_mod/proc/can_prioritize_job(datum/job/job) if(job) if(!job_blacklisted(job)) - if(job in job_master.prioritized_jobs) + if(job in SSjobs.prioritized_jobs) return 2 else - if(job_master.prioritized_jobs.len >= 3) + if(SSjobs.prioritized_jobs.len >= 3) return 0 if(job.total_positions <= job.current_positions) return 0 @@ -320,7 +320,7 @@ // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS if(is_authenticated(usr)) var/edit_job_target = href_list["job"] - var/datum/job/j = job_master.GetJob(edit_job_target) + var/datum/job/j = SSjobs.GetJob(edit_job_target) if(!j) return 1 if(can_open_job(j) != 1) @@ -335,7 +335,7 @@ // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS if(is_authenticated(usr)) var/edit_job_target = href_list["job"] - var/datum/job/j = job_master.GetJob(edit_job_target) + var/datum/job/j = SSjobs.GetJob(edit_job_target) if(!j) return 1 if(can_close_job(j) != 1) @@ -352,16 +352,16 @@ // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY if(is_authenticated(usr)) var/priority_target = href_list["job"] - var/datum/job/j = job_master.GetJob(priority_target) + var/datum/job/j = SSjobs.GetJob(priority_target) if(!j) return 0 // Unlike the proper ID computer, this does not check job_in_department var/priority = TRUE - if(j in job_master.prioritized_jobs) - job_master.prioritized_jobs -= j + if(j in SSjobs.prioritized_jobs) + SSjobs.prioritized_jobs -= j priority = FALSE - else if(job_master.prioritized_jobs.len < 3) - job_master.prioritized_jobs += j + else if(SSjobs.prioritized_jobs.len < 3) + SSjobs.prioritized_jobs += j else return 0 log_game("[key_name(usr)] [priority ? "prioritized" : "unprioritized"] the job \"[j.title]\".") diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index 6e2c8e6b521..c1124bee744 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -104,7 +104,7 @@ H.visible_message("[H] holds up a contract claiming his soul, then immediately catches fire. It looks like \he's trying to commit suicide!") H.adjust_fire_stacks(20) H.IgniteMob() - return(FIRELOSS) + return FIRELOSS else ..() diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index f4808f46d53..13d85941a79 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -283,34 +283,25 @@ var/global/list/fax_blacklist = list() use_power(200) - var/obj/item/rcvdcopy - if(istype(copyitem, /obj/item/paper)) - rcvdcopy = copy(copyitem) - else if(istype(copyitem, /obj/item/photo)) - rcvdcopy = photocopy(copyitem) - else if(istype(copyitem, /obj/item/paper_bundle)) - rcvdcopy = bundlecopy(copyitem) - else + if(!(istype(copyitem, /obj/item/paper) || istype(copyitem, /obj/item/paper_bundle) || istype(copyitem, /obj/item/photo))) visible_message("[src] beeps, \"Error transmitting message.\"") return - rcvdcopy.loc = null //hopefully this shouldn't cause trouble - var/datum/fax/admin/A = new /datum/fax/admin() - A.name = rcvdcopy.name + A.name = copyitem.name A.from_department = department A.to_department = destination A.origin = src - A.message = rcvdcopy + A.message = copyitem A.sent_by = sender A.sent_at = world.time //message badmins that a fax has arrived switch(destination) if("Central Command") - message_admins(sender, "CENTCOM FAX", destination, rcvdcopy, "#006100") + message_admins(sender, "CENTCOM FAX", destination, copyitem, "#006100") if("Syndicate") - message_admins(sender, "SYNDICATE FAX", destination, rcvdcopy, "#DC143C") + message_admins(sender, "SYNDICATE FAX", destination, copyitem, "#DC143C") for(var/obj/machinery/photocopier/faxmachine/F in allfaxes) if(F.department == destination) F.receivefax(copyitem) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index da241a9c007..01974ad3694 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -131,7 +131,7 @@ usr << browse(dat + "[P.name]" \ + "" \ + "

Written on the back:
[P.scribble]" : ]"\ + + "[P.scribble ? "

Written on the back:
[P.scribble]" : ""]"\ + "", "window=[name]") /obj/item/paper_bundle/attack_self(mob/user as mob) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 83897e5cbd3..302f2e02342 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -26,7 +26,7 @@ /obj/item/pen/suicide_act(mob/user) to_chat(viewers(user), "[user] starts scribbling numbers over [user.p_them()]self with the [name]! It looks like [user.p_theyre()] trying to commit sudoku.") - return (BRUTELOSS) + return BRUTELOSS /obj/item/pen/blue name = "blue-ink pen" diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 9bb3a09ebb0..8e78f0ce230 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -15,7 +15,7 @@ /obj/item/stamp/suicide_act(mob/user) user.visible_message("[user] stamps 'VOID' on [user.p_their()] forehead, then promptly falls over, dead.") - return (OXYLOSS) + return OXYLOSS /obj/item/stamp/qm name = "Quartermaster's rubber stamp" diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index 46e8e1d257c..de2414da743 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -28,7 +28,7 @@ post_status(href_list["statdisp"]) /datum/data/pda/app/status_display/proc/post_status(var/command, var/data1, var/data2) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) + var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/modules/pda/radio.dm b/code/modules/pda/radio.dm index e6d7f29f6ac..7db0ed332d5 100644 --- a/code/modules/pda/radio.dm +++ b/code/modules/pda/radio.dm @@ -26,15 +26,15 @@ add_to_radio(bot_filter) /obj/item/integrated_radio/Destroy() - if(radio_controller) - radio_controller.remove_object(src, control_freq) + if(SSradio) + SSradio.remove_object(src, control_freq) hostpda = null return ..() /obj/item/integrated_radio/proc/post_signal(var/freq, var/key, var/value, var/key2, var/value2, var/key3, var/value3,var/key4, var/value4, s_filter) // to_chat(world, "Post: [freq]: [key]=[value], [key2]=[value2]") - var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq) + var/datum/radio_frequency/frequency = SSradio.return_frequency(freq) if(!frequency) return @@ -93,8 +93,8 @@ post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter) /obj/item/integrated_radio/proc/add_to_radio(bot_filter) //Master filter control for bots. Must be placed in the bot's local New() to support map spawned bots. - if(radio_controller) - radio_controller.add_object(src, control_freq, filter = bot_filter) + if(SSradio) + SSradio.add_object(src, control_freq, filter = bot_filter) /obj/item/integrated_radio/honkbot bot_filter = RADIO_HONKBOT @@ -171,13 +171,13 @@ var/datum/radio_frequency/radio_connection /obj/item/integrated_radio/signal/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null return ..() /obj/item/integrated_radio/signal/Initialize() - if(!radio_controller) + if(!SSradio) return if(src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ) src.frequency = sanitize_frequency(src.frequency) @@ -185,9 +185,9 @@ set_frequency(frequency) /obj/item/integrated_radio/signal/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency) + radio_connection = SSradio.add_object(src, frequency) /obj/item/integrated_radio/signal/proc/send_signal(message="ACTIVATE") diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 1f7af8e4204..e8aab46dbbe 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -49,6 +49,7 @@ anchored = 1 use_power = NO_POWER_USE req_access = list(access_engine_equip) + siemens_strength = 1 var/spooky=0 var/area/area var/areastring = null @@ -535,7 +536,7 @@ if(C.amount >= 10 && !terminal && opened && has_electronics != 2) var/turf/T = get_turf(src) var/obj/structure/cable/N = T.get_cable_node() - if(prob(50) && electrocute_mob(usr, N, N)) + if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) do_sparks(5, 1, src) return C.use(10) @@ -1237,13 +1238,13 @@ if(prob(5)) var/list/shock_mobs = list() for(var/C in view(get_turf(src), 5)) //We only want to shock a single random mob in range, not every one. - if(iscarbon(C)) - shock_mobs +=C + if(isliving(C)) + shock_mobs += C if(shock_mobs.len) - var/mob/living/carbon/S = pick(shock_mobs) - S.electrocute_act(rand(5,25), "electrical arc") - playsound(get_turf(S), 'sound/effects/eleczap.ogg', 75, 1) - Beam(S,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) + var/mob/living/L = pick(shock_mobs) + L.electrocute_act(rand(5, 25), "electrical arc") + playsound(get_turf(L), 'sound/effects/eleczap.ogg', 75, 1) + Beam(L, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) else // no cell, switch everything off diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 410b91bdf48..c71bc3e7c8c 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -191,14 +191,14 @@ By design, d1 is the smallest direction and d2 is the highest src.add_fingerprint(user) // shock the user with probability prb -/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0) +/obj/structure/cable/proc/shock(mob/user, prb, siemens_coeff = 1) if(!prob(prb)) - return 0 + return FALSE if(electrocute_mob(user, powernet, src, siemens_coeff)) do_sparks(5, 1, src) - return 1 + return TRUE else - return 0 + return FALSE //explosion handling /obj/structure/cable/ex_act(severity) @@ -504,7 +504,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( user.visible_message("[user] is making a noose with the [name]! It looks like [user.p_theyre()] trying to commit suicide.") else user.visible_message("[user] is strangling [user.p_them()]self with the [name]! It looks like [user.p_theyre()] trying to commit suicide.") - return(OXYLOSS) + return OXYLOSS /obj/item/stack/cable_coil/New(loc, length = MAXCOIL, paramcolor = null) ..() diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 3bc2b5bc39b..dfe10113f12 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -90,7 +90,7 @@ /obj/item/stock_parts/cell/suicide_act(mob/user) to_chat(viewers(user), "[user] is licking the electrodes of the [src]! It looks like [user.p_theyre()] trying to commit suicide.") - return (FIRELOSS) + return FIRELOSS /obj/item/stock_parts/cell/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/reagent_containers/syringe)) @@ -162,23 +162,10 @@ ex_act(EXPLODE_DEVASTATE) /obj/item/stock_parts/cell/proc/get_electrocute_damage() - switch(charge) - if(5000000 to INFINITY) - return min(rand(200, 300),rand(200, 300)) - if(4000000 to 5000000 - 1) - return min(rand(80, 180),rand(80, 180)) - if(1000000 to 4000000 - 1) - return min(rand(50, 160),rand(50, 160)) - if(200000 to 1000000 - 1) - return min(rand(25, 80),rand(25, 80)) - if(100000 to 200000 - 1)//Ave powernet - return min(rand(20, 60),rand(20, 60)) - if(50000 to 100000 - 1) - return min(rand(15, 40),rand(15, 40)) - if(1000 to 50000 - 1) - return min(rand(10, 20),rand(10, 20)) - else - return 0 + if(charge >= 1000) + return Clamp(20 + round(charge / 25000), 20, 195) + rand(-5, 5) + else + return 0 // Cell variants /obj/item/stock_parts/cell/empty/New() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 8dda1ed8731..a0bee89e0be 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -353,7 +353,7 @@ M.show_message("[user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) if(on && (W.flags & CONDUCT)) if(prob(12)) - electrocute_mob(user, get_area(src), src, 0.3) + electrocute_mob(user, get_area(src), src, 0.3, TRUE) broken() else @@ -387,7 +387,7 @@ if(has_power() && (W.flags & CONDUCT)) do_sparks(3, 1, src) if(prob(75)) - electrocute_mob(user, get_area(src), src, rand(0.7,1.0)) + electrocute_mob(user, get_area(src), src, rand(0.7, 1), TRUE) // returns whether this light has power diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 69b27eff562..3e5d614896e 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -298,34 +298,37 @@ //power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null //source is an object caused electrocuting (airlock, grille, etc) //No animations will be performed by this proc. -/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0) +/proc/electrocute_mob(mob/living/M, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE) if(!istype(M)) - return 0 + return FALSE if(istype(M.loc,/obj/mecha)) - return 0 //feckin mechs are dumb + return FALSE //feckin mechs are dumb + if(dist_check) + if(!in_range(source, M)) + return FALSE if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M if(H.gloves) var/obj/item/clothing/gloves/G = H.gloves if(G.siemens_coefficient == 0) - return 0 //to avoid spamming with insulated glvoes on + return FALSE //to avoid spamming with insulated glvoes on var/area/source_area - if(istype(power_source,/area)) + if(istype(power_source, /area)) source_area = power_source power_source = source_area.get_apc() - if(istype(power_source,/obj/structure/cable)) + if(istype(power_source, /obj/structure/cable)) var/obj/structure/cable/Cable = power_source power_source = Cable.powernet var/datum/powernet/PN var/obj/item/stock_parts/cell/cell - if(istype(power_source,/datum/powernet)) + if(istype(power_source, /datum/powernet)) PN = power_source else if(istype(power_source,/obj/item/stock_parts/cell)) cell = power_source - else if(istype(power_source,/obj/machinery/power/apc)) + else if(istype(power_source, /obj/machinery/power/apc)) var/obj/machinery/power/apc/apc = power_source cell = apc.cell if(apc.terminal) @@ -344,7 +347,7 @@ if(cell) cell_damage = cell.get_electrocute_damage() var/shock_damage = 0 - if(PN_damage>=cell_damage) + if(PN_damage >= cell_damage) power_source = PN shock_damage = PN_damage else diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index a07d854380d..228b4232968 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -128,23 +128,10 @@ newavail = 0 /datum/powernet/proc/get_electrocute_damage() - switch(avail) - if(5000000 to INFINITY) - return min(rand(200,300),rand(200,300)) - if(4000000 to 5000000) - return min(rand(80,180),rand(80,180)) - if(1000000 to 4000000) - return min(rand(50,160),rand(50,160)) - if(200000 to 1000000) - return min(rand(25,80),rand(25,80)) - if(100000 to 200000)//Ave powernet - return min(rand(20,60),rand(20,60)) - if(50000 to 100000) - return min(rand(15,40),rand(15,40)) - if(1000 to 50000) - return min(rand(10,20),rand(10,20)) - else - return 0 + if(avail >= 1000) + return Clamp(20 + round(avail / 25000), 20, 195) + rand(-5, 5) + else + return 0 //////////////////////////////////////////////// // Misc. diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index a0e84f8455a..6c8eba8fb62 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -78,7 +78,7 @@ if(isliving(user)) var/shock_damage = min(rand(30,40),rand(30,40)) - if(iscarbon(user)) + if(isliving(user) && !issilicon(user)) var/stun = min(shock_damage, 15) user.Stun(stun) user.Weaken(10) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index b0ed7c14581..7e031755e22 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -54,10 +54,10 @@ //Radio remote control /obj/machinery/power/emitter/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) + SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/power/emitter/verb/rotate() @@ -121,8 +121,8 @@ update_icon() /obj/machinery/power/emitter/Destroy() - if(radio_controller) - radio_controller.remove_object(src, frequency) + if(SSradio) + SSradio.remove_object(src, frequency) radio_connection = null msg_admin_attack("Emitter deleted at ([x],[y],[z] - [ADMIN_JMP(src)])", ATKLOG_FEW) log_game("Emitter deleted at ([x],[y],[z])") diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 6d5d0226e69..2884fc18b4c 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -183,7 +183,7 @@ playsound(src.loc, I.usesound, 50, 1) if(do_after(user, 50 * I.toolspeed, target = src)) - if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) //animate the electrocution if uncautious and unlucky + if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal, 1, TRUE)) //animate the electrocution if uncautious and unlucky do_sparks(5, 1, src) return @@ -320,7 +320,7 @@ if(do_after(user, 50, target = src)) var/turf/T = get_turf(user) var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one - if(prob(50) && electrocute_mob(user, N, N)) //animate the electrocution if uncautious and unlucky + if(prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) //animate the electrocution if uncautious and unlucky do_sparks(5, 1, src) return diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index e5005708c67..19948c94a36 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -115,6 +115,16 @@ /obj/singularity/energy_ball/Bumped(atom/A) dust_mobs(A) +/obj/singularity/energy_ball/attack_tk(mob/user) + if(iscarbon(user)) + var/mob/living/carbon/C = user + to_chat(C, "That was a shockingly dumb idea.") + var/obj/item/organ/internal/brain/B = C.get_int_organ(/obj/item/organ/internal/brain) + C.ghostize(0) + if(B) + B.remove(C) + qdel(B) + /obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target) if(istype(target)) target.orbiting_balls += src @@ -130,6 +140,10 @@ qdel(src) /obj/singularity/energy_ball/proc/dust_mobs(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.incorporeal_move || L.status_flags & GODMODE) + return if(!iscarbon(A)) return for(var/obj/machinery/power/grounding_rod/GR in orange(src, 2)) @@ -155,7 +169,6 @@ var/static/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics, /obj/machinery/power/emitter, /obj/machinery/field/generator, - /mob/living/simple_animal, /obj/machinery/particle_accelerator/control_box, /obj/structure/particle_accelerator/fuel_chamber, /obj/structure/particle_accelerator/particle_emitter/center, @@ -165,6 +178,9 @@ /obj/structure/particle_accelerator/end_cap, /obj/machinery/field/containment, /obj/structure/disposalpipe, + /obj/structure/disposaloutlet, + /obj/machinery/disposal/deliveryChute, + /obj/machinery/camera, /obj/structure/sign, /obj/machinery/gateway, /obj/structure/grille, @@ -255,7 +271,7 @@ else if(closest_mob) var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) - closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1) + closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = TRUE) if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob if(stun_mobs) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 795b5942845..8c9b0cf66f8 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -154,14 +154,14 @@ var/obj/item/ammo_casing/energy/shot = ammo_type[select] power_supply.use(shot.e_cost) update_icon() - return(FIRELOSS) + return FIRELOSS else user.visible_message("[user] panics and starts choking to death!") - return(OXYLOSS) + return OXYLOSS else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!
") playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) - return (OXYLOSS) + return OXYLOSS /obj/item/gun/energy/vv_edit_var(var_name, var_value) switch(var_name) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 74ab90fcbc4..623986f5837 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -137,7 +137,7 @@ playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) user.visible_message("[user] cocks the [name] and pretends to blow [user.p_their()] brains out! It looks like [user.p_theyre()] trying to commit suicide!
") shoot_live_shot() - return (OXYLOSS) + return OXYLOSS // Plasma Cutters // /obj/item/gun/energy/plasmacutter diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index d77621051e2..face61e79c3 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -54,8 +54,8 @@ feedback_add_details("gun_fired","[type]") /obj/item/gun/medbeam/process() - var/mob/living/carbon/human/H = loc - if(!istype(H)) + var/source = loc + if(!ishuman(source) && !isrobot(source)) LoseTarget() return @@ -68,9 +68,9 @@ last_check = world.time - if(get_dist(H,current_target)>max_range || !los_check(H,current_target)) + if(get_dist(source,current_target)>max_range || !los_check(source,current_target)) LoseTarget() - to_chat(H, "You lose control of the beam!") + to_chat(source, "You lose control of the beam!") return if(current_target) diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 6e558dedbd1..9defe7637d4 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -55,7 +55,7 @@ /obj/item/gun/projectile/proc/can_reload() return !magazine -/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user as mob) +/obj/item/gun/projectile/proc/reload(obj/item/ammo_box/magazine/AM, mob/user as mob) user.remove_from_mob(AM) magazine = AM magazine.loc = src @@ -81,7 +81,7 @@ to_chat(user, "You perform a tactical reload on \the [src], replacing the magazine.") magazine.loc = get_turf(loc) magazine.update_icon() - magazine = null + magazine = null reload(AM, user) return TRUE else @@ -165,14 +165,14 @@ if(user.l_hand == src || user.r_hand == src) process_fire(user, user, 0, zone_override = "head") user.visible_message("[user] blows [user.p_their()] brains out with the [name]!") - return(BRUTELOSS) + return BRUTELOSS else user.visible_message("[user] panics and starts choking to death!") - return(OXYLOSS) + return OXYLOSS else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with the [name]! It looks like [user.p_theyre()] trying to commit suicide!") playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) - return (OXYLOSS) + return OXYLOSS /obj/item/gun/projectile/proc/sawoff(mob/user) if(sawn_state == SAWN_OFF) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index fd2dbaa335e..d313195a40e 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -259,19 +259,19 @@ /obj/item/projectile/plasma/on_hit(atom/target) . = ..() - if(istype(target, /turf/simulated/mineral)) + if(ismineralturf(target)) + forcedodge = 1 var/turf/simulated/mineral/M = target M.gets_drilled(firer) - Range() - if(range > 0) - return -1 + else + forcedodge = 0 /obj/item/projectile/plasma/adv - range = 5 + range = 6 /obj/item/projectile/plasma/adv/mech damage = 10 - range = 6 + range = 9 /obj/item/projectile/energy/teleport name = "teleportation burst" diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 6e4379d1fc9..8d7201d0645 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -218,7 +218,7 @@ var/const/INGEST = 2 /datum/reagents/proc/metabolize(mob/living/M) if(M) - set_reagent_temp(M.bodytemperature) + temperature_reagents(M.bodytemperature - 30) // a bitfield filled in by each reagent's `on_mob_life` to find out which states to update var/update_flags = STATUS_UPDATE_NONE @@ -465,8 +465,8 @@ var/const/INGEST = 2 add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier) var/list/seen = viewers(4, get_turf(my_atom)) - for(var/mob/M in seen) - if(!C.no_message) + for(var/mob/living/M in seen) + if(C.mix_message) to_chat(M, "[bicon(my_atom)] [C.mix_message]") if(istype(my_atom, /obj/item/slime_extract)) @@ -478,7 +478,8 @@ var/const/INGEST = 2 ME2.name = "used slime extract" ME2.desc = "This extract has been used up." - playsound(get_turf(my_atom), C.mix_sound, 80, 1) + if(C.mix_sound) + playsound(get_turf(my_atom), C.mix_sound, 80, 1) C.on_reaction(src, created_volume) reaction_occured = 1 diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index e827d282e21..258237f0ddd 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -1,38 +1,80 @@ /obj/machinery/chem_dispenser name = "chem dispenser" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE icon = 'icons/obj/chemical.dmi' icon_state = "dispenser" - use_power = NO_POWER_USE + use_power = IDLE_POWER_USE idle_power_usage = 40 var/ui_title = "Chem Dispenser 5000" - var/energy = 100 - var/max_energy = 100 - var/amount = 30 + var/cell_type = /obj/item/stock_parts/cell/high + var/obj/item/stock_parts/cell/cell + var/powerefficiency = 0.1 + var/amount = 10 + var/recharge_amount = 100 + var/recharge_counter = 0 + var/hackedcheck = FALSE var/obj/item/reagent_containers/beaker = null - var/recharged = 0 - var/hackedcheck = 0 + var/image/icon_beaker = null //cached overlay var/list/dispensable_reagents = list("hydrogen", "lithium", "carbon", "nitrogen", "oxygen", "fluorine", "sodium", "aluminum", "silicon", "phosphorus", "sulfur", "chlorine", "potassium", "iron", "copper", "mercury", "plasma", "radium", "water", "ethanol", "sugar", "iodine", "bromine", "silver") + var/list/upgrade_reagents = list("oil", "ash", "acetone", "saltpetre", "ammonia", "diethylamine", "fuel") var/list/hacked_reagents = list("toxin") var/hack_message = "You disable the safety safeguards, enabling the \"Mad Scientist\" mode." var/unhack_message = "You re-enable the safety safeguards, enabling the \"NT Standard\" mode." - var/list/broken_requirements = list() - var/broken_on_spawn = 0 - var/recharge_delay = 5 - var/image/icon_beaker = null //cached overlay + +/obj/machinery/chem_dispenser/New() + ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/chem_dispenser(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/capacitor(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + component_parts += new cell_type(null) + RefreshParts() + dispensable_reagents = sortList(dispensable_reagents) + +/obj/machinery/chem_dispenser/RefreshParts() + recharge_amount = initial(recharge_amount) + var/newpowereff = 0.0666666 + for(var/obj/item/stock_parts/cell/P in component_parts) + cell = P + for(var/obj/item/stock_parts/matter_bin/M in component_parts) + newpowereff += 0.0166666666 * M.rating + for(var/obj/item/stock_parts/capacitor/C in component_parts) + recharge_amount *= C.rating + for(var/obj/item/stock_parts/manipulator/M in component_parts) + if(M.rating > 3) + dispensable_reagents |= upgrade_reagents + powerefficiency = round(newpowereff, 0.01) + +/obj/machinery/chem_dispenser/Destroy() + QDEL_NULL(beaker) + QDEL_NULL(cell) + return ..() + +/obj/machinery/chem_dispenser/examine(mob/user) + ..() + if(panel_open) + to_chat(user, "[src]'s maintenance hatch is open!") + if(in_range(user, src) || isobserver(user)) + to_chat(user, "The status display reads:
Recharging [recharge_amount] power units per interval.
Power efficiency increased by [round((powerefficiency * 1000) - 100, 1)]%.") -/obj/machinery/chem_dispenser/proc/recharge() - if(stat & (BROKEN|NOPOWER)) return - var/addenergy = 1 - var/oldenergy = energy - energy = min(energy + addenergy, max_energy) - if(energy != oldenergy) - use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air) - SSnanoui.update_uis(src) // update all UIs attached to src +/obj/machinery/chem_dispenser/process() + if(recharge_counter >= 4) + if(!is_operational()) + return + var/usedpower = cell.give(recharge_amount) + if(usedpower) + use_power(15 * recharge_amount) + SSnanoui.update_uis(src) // update all UIs attached to src + recharge_counter = 0 + return + recharge_counter++ /obj/machinery/chem_dispenser/power_change() if(powered()) @@ -42,72 +84,19 @@ stat |= NOPOWER SSnanoui.update_uis(src) // update all UIs attached to src -/obj/machinery/chem_dispenser/process() - - if(recharged < 0) - recharge() - recharged = recharge_delay - else - recharged -= 1 - -/obj/machinery/chem_dispenser/New() - ..() - recharge() - dispensable_reagents = sortList(dispensable_reagents) - - if(broken_on_spawn) - overlays.Cut() - var/amount = pick(3,3,4) - var/list/options = list() - options[/obj/item/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it." - options[/obj/item/stock_parts/console_screen] = "Replace the console screen to fix it." - options[/obj/item/stock_parts/manipulator/pico] = "Upgrade to a pico manipulator to fix it." - options[/obj/item/stock_parts/matter_bin/super] = "Give it a super matter bin to fix it." - options[/obj/item/stock_parts/cell/super] = "Replace the reagent synthesizer with a super capacity cell to fix it." - options[/obj/item/reagent_scanner/adv] = "Replace the reagent scanner with an advanced reagent scanner to fix it" - options[/obj/item/stock_parts/micro_laser/high] = "Repair the reagent synthesizer with an high-power micro-laser to fix it" - options[/obj/item/reagent_scanner/adv] = "Replace the reagent scanner with an advanced reagent scanner to fix it" - options[/obj/item/stack/nanopaste] = "Apply some nanopaste to the broken nozzles to fix it." - options[/obj/item/stack/sheet/plasteel] = "Surround the outside with a plasteel cover to fix it." - options[/obj/item/stack/sheet/rglass] = "Insert a pane of reinforced glass to fix it." - - while(amount > 0) - amount -= 1 - - var/index = pick(options) - broken_requirements[index] = options[index] - options -= index - - /obj/machinery/chem_dispenser/ex_act(severity) switch(severity) - if(1.0) + if(1) qdel(src) - return - if(2.0) + if(2) if(prob(50)) qdel(src) - return /obj/machinery/chem_dispenser/blob_act() if(prob(50)) qdel(src) - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * - * @return nothing - */ /obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(broken_requirements.len) - to_chat(user, "[src] is broken. [broken_requirements[broken_requirements[1]]]") - return - // update the ui if it exists, returns null if no ui is passed/found ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) @@ -121,8 +110,8 @@ var/data[0] data["amount"] = amount - data["energy"] = round(energy) - data["maxEnergy"] = round(max_energy) + data["energy"] = cell.charge ? cell.charge * powerefficiency : "0" //To prevent NaN in the UI. + data["maxEnergy"] = cell.maxcharge * powerefficiency data["isBeakerLoaded"] = beaker ? 1 : 0 var/beakerContents[0] @@ -151,26 +140,32 @@ /obj/machinery/chem_dispenser/Topic(href, href_list) if(..()) - return 1 + return TRUE if(href_list["amount"]) - amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 + amount = round(text2num(href_list["amount"]), 1) // round to nearest 1 if(amount < 0) // Since the user can actually type the commands himself, some sanity checking amount = 0 if(amount > 100) amount = 100 if(href_list["dispense"]) - if(dispensable_reagents.Find(href_list["dispense"]) && beaker != null) - var/obj/item/reagent_containers/glass/B = beaker - var/datum/reagents/R = B.reagents - var/space = R.maximum_volume - R.total_volume + if(!is_operational() || QDELETED(cell)) + return + if(beaker && dispensable_reagents.Find(href_list["dispense"])) + var/datum/reagents/R = beaker.reagents + var/free = R.maximum_volume - R.total_volume + var/actual = min(amount, (cell.charge * powerefficiency) * 10, free) - R.add_reagent(href_list["dispense"], min(amount, energy * 10, space)) - energy = max(energy - min(amount, energy * 10, space) / 10, 0) + if(!cell.use(actual / powerefficiency)) + atom_say("Not enough energy to complete operation!") + return + + R.add_reagent(href_list["dispense"], actual) overlays.Cut() - icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10,5) + if(!icon_beaker) + icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. + icon_beaker.pixel_x = rand(-10, 5) overlays += icon_beaker if(href_list["remove"]) @@ -178,75 +173,96 @@ if(href_list["removeamount"]) var/amount = text2num(href_list["removeamount"]) if(isnum(amount) && (amount > 0)) - var/obj/item/reagent_containers/glass/B = beaker - var/datum/reagents/R = B.reagents + var/datum/reagents/R = beaker.reagents var/id = href_list["remove"] R.remove_reagent(id, amount) + else if(isnum(amount) && (amount == -1)) //Isolate instead + var/datum/reagents/R = beaker.reagents + var/id = href_list["remove"] + R.isolate_reagent(id) if(href_list["ejectBeaker"]) if(beaker) - var/obj/item/reagent_containers/glass/B = beaker - B.forceMove(loc) + beaker.forceMove(loc) beaker = null overlays.Cut() - add_fingerprint(usr) - return 1 // update UIs attached to this object -/obj/machinery/chem_dispenser/attackby(obj/item/reagent_containers/B, mob/user, params) - if(isrobot(user)) + add_fingerprint(usr) + return TRUE // update UIs attached to this object + +/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params) + if(ismultitool(I)) + if(!hackedcheck) + to_chat(user, hack_message) + dispensable_reagents += hacked_reagents + hackedcheck = TRUE + else + to_chat(user, unhack_message) + dispensable_reagents -= hacked_reagents + hackedcheck = FALSE + SSnanoui.update_uis(src) return - if(broken_requirements.len && B.type == broken_requirements[1]) - if(istype(B,/obj/item/stack)) - var/obj/item/stack/S = B - S.use(1) - else - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") - return - qdel(B) - broken_requirements -= broken_requirements[1] - to_chat(user, "You fix [src].") + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", "[initial(icon_state)]", I)) + return + + if(exchange_parts(user, I)) + SSnanoui.update_uis(src) + return + + if(iswrench(I)) + playsound(src, I.usesound, 50, 1) + if(anchored) + anchored = FALSE + to_chat(user, "[src] can now be moved.") + else if(!anchored) + anchored = TRUE + to_chat(user, "[src] is now secured.") + return + + if(panel_open) + if(iscrowbar(I)) + if(beaker) + beaker.forceMove(loc) + beaker = null + if(cell) + cell.forceMove(loc) + cell = null + default_deconstruction_crowbar(I) + return TRUE + + if(isrobot(user)) return if(beaker) to_chat(user, "Something is already loaded into the machine.") return - if(istype(B, /obj/item/reagent_containers/glass) || istype(B, /obj/item/reagent_containers/food/drinks)) - beaker = B - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") + if(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks)) + if(panel_open) + to_chat(user, "Close the maintenance panel first.") return - B.forceMove(src) - to_chat(user, "You set [B] on the machine.") + if(!user.drop_item()) + to_chat(user, "[I] is stuck to you!") + return + beaker = I + I.forceMove(src) + to_chat(user, "You set [I] on the machine.") SSnanoui.update_uis(src) // update all UIs attached to src if(!icon_beaker) icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10,5) + icon_beaker.pixel_x = rand(-10, 5) overlays += icon_beaker return + return ..() -/obj/machinery/chem_dispenser/attackby(obj/item/B, mob/user, params) - ..() - if(istype(B, /obj/item/multitool)) - if(hackedcheck == 0) - to_chat(user, hack_message) - dispensable_reagents += hacked_reagents - hackedcheck = 1 - return - - else - to_chat(user, unhack_message) - dispensable_reagents -= hacked_reagents - hackedcheck = 0 - return /obj/machinery/chem_dispenser/attack_ai(mob/user) return attack_hand(user) /obj/machinery/chem_dispenser/attack_ghost(mob/user) - return attack_hand(user) + if(user.can_admin_interact()) + return attack_hand(user) /obj/machinery/chem_dispenser/attack_hand(mob/user) if(stat & BROKEN) @@ -259,245 +275,45 @@ name = "soda fountain" desc = "A drink fabricating machine, capable of producing many sugary drinks with just one touch." ui_title = "Soda Dispens-o-matic" - energy = 100 - max_energy = 100 dispensable_reagents = list("water", "ice", "milk", "soymilk", "coffee", "tea", "hot_coco", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", "sodawater", "lemon_lime", "grapejuice", "sugar", "orangejuice", "lemonjuice", "limejuice", "tomatojuice", "banana", "watermelonjuice", "carrotjuice", "potato", "berryjuice") - var/list/special_reagents2 = list(list(""), - list("bananahonk", "milkshake", "cafe_latte", "cafe_mocha"), - list("triple_citrus", "icecoffe","icetea")) + upgrade_reagents = list("bananahonk", "milkshake", "cafe_latte", "cafe_mocha", "triple_citrus", "icecoffe","icetea") + hacked_reagents = list("thirteenloko") hack_message = "You change the mode from 'McNano' to 'Pizza King'." unhack_message = "You change the mode from 'Pizza King' to 'McNano'." - hacked_reagents = list("thirteenloko") /obj/machinery/chem_dispenser/soda/New() ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/soda(null) + QDEL_LIST(component_parts) + component_parts += new /obj/item/circuitboard/chem_dispenser/soda(null) component_parts += new /obj/item/stock_parts/matter_bin(null) component_parts += new /obj/item/stock_parts/matter_bin(null) component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/capacitor(null) component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/super(null) + component_parts += new cell_type(null) RefreshParts() -/obj/machinery/chem_dispenser/soda/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/soda(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/stock_parts/capacitor/super(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/hyper(null) - RefreshParts() - -/obj/machinery/chem_dispenser/soda/RefreshParts() - for(var/obj/item/stock_parts/manipulator/M in component_parts) - for(var/i in 1 to M.rating) - dispensable_reagents = sortList(dispensable_reagents | special_reagents2[i]) - -/obj/machinery/chem_dispenser/soda/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers/glass)) - if(panel_open) - to_chat(user, "Close the maintenance panel first.") - return - return ..() - else - ..() - - if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I)) - return - - if(exchange_parts(user, I)) - return - - if(iswrench(I)) - playsound(src, I.usesound, 50, 1) - if(anchored) - anchored = FALSE - to_chat(user, "[src] can now be moved.") - else if(!anchored) - anchored = TRUE - to_chat(user, "[src] is now secured.") - - if(panel_open) - if(iscrowbar(I)) - if(beaker) - var/obj/item/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - default_deconstruction_crowbar(I) - return TRUE - - /obj/machinery/chem_dispenser/beer icon_state = "booze_dispenser" name = "booze dispenser" ui_title = "Booze Portal 9001" - energy = 100 - max_energy = 100 desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." dispensable_reagents = list("ice", "cream", "cider", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequila", "vermouth", "cognac", "ale", "mead", "synthanol") - var/list/special_reagents3 = list(list("iced_beer"), - list("irishcream", "manhattan",), - list("antihol", "synthignon", "bravebull")) + upgrade_reagents = list("iced_beer", "irishcream", "manhattan", "antihol", "synthignon", "bravebull") + hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing", "sake") hack_message = "You disable the 'nanotrasen-are-cheap-bastards' lock, enabling hidden and very expensive boozes." unhack_message = "You re-enable the 'nanotrasen-are-cheap-bastards' lock, disabling hidden and very expensive boozes." - hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing", "sake") /obj/machinery/chem_dispenser/beer/New() ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/beer(null) + QDEL_LIST(component_parts) + component_parts += new /obj/item/circuitboard/chem_dispenser/beer(null) component_parts += new /obj/item/stock_parts/matter_bin(null) component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/capacitor(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/super(null) - RefreshParts() - -/obj/machinery/chem_dispenser/beer/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/beer(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/stock_parts/capacitor/super(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/hyper(null) - RefreshParts() - -/obj/machinery/chem_dispenser/beer/RefreshParts() - for(var/obj/item/stock_parts/manipulator/M in component_parts) - for(var/i in 1 to M.rating) - dispensable_reagents = sortList(dispensable_reagents | special_reagents3[i]) - -/obj/machinery/chem_dispenser/beer/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers/glass)) - if(panel_open) - to_chat(user, "Close the maintenance panel first.") - return - return ..() - else - ..() - - if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I)) - return - - if(exchange_parts(user, I)) - return - - if(iswrench(I)) - playsound(src, I.usesound, 50, 1) - if(anchored) - anchored = FALSE - to_chat(user, "[src] can now be moved.") - else if(!anchored) - anchored = TRUE - to_chat(user, "[src] is now secured.") - - if(panel_open) - if(iscrowbar(I)) - if(beaker) - var/obj/item/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - default_deconstruction_crowbar(I) - return TRUE - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/machinery/chem_dispenser/constructable - name = "portable chem dispenser" - icon = 'icons/obj/chemical.dmi' - icon_state = "minidispenser" - energy = 5 - max_energy = 5 - amount = 5 - recharge_delay = 10 - dispensable_reagents = list() - var/list/special_reagents = list(list("hydrogen", "oxygen", "silicon", "phosphorus", "sulfur", "carbon", "nitrogen", "water"), - list("lithium", "sugar", "copper", "mercury", "sodium","iodine","bromine"), - list("ethanol", "chlorine", "potassium", "aluminum","plasma", "radium", "fluorine", "iron", "silver"), - list("oil", "ash", "acetone", "saltpetre", "ammonia", "diethylamine", "fuel")) - -/obj/machinery/chem_dispenser/constructable/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/capacitor(null) component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/super(null) - RefreshParts() - -/obj/machinery/chem_dispenser/constructable/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/stock_parts/capacitor/super(null) - component_parts += new /obj/item/stock_parts/console_screen(null) - component_parts += new /obj/item/stock_parts/cell/hyper(null) - RefreshParts() - -/obj/machinery/chem_dispenser/constructable/RefreshParts() - var/time = 0 - var/temp_energy = 0 - var/i - for(var/obj/item/stock_parts/matter_bin/M in component_parts) - temp_energy += M.rating - temp_energy-- - max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest - for(var/obj/item/stock_parts/capacitor/C in component_parts) - time += C.rating - for(var/obj/item/stock_parts/cell/P in component_parts) - time += round(P.maxcharge, 10000) / 10000 - recharge_delay = 10 / (time/2) //delay between recharges, double the usual time on lowest 33% less than usual on highest - for(var/obj/item/stock_parts/manipulator/M in component_parts) - for(i=1, i<=M.rating, i++) - dispensable_reagents = sortList(dispensable_reagents | special_reagents[i]) - -/obj/machinery/chem_dispenser/constructable/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers/glass)) - if(panel_open) - to_chat(user, "Close the maintenance panel first.") - return - ..() - else - ..() - - if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I)) - return - - if(exchange_parts(user, I)) - return - - if(istype(I, /obj/item/wrench)) - playsound(src, I.usesound, 50, 1) - if(anchored) - anchored = 0 - to_chat(user, "[src] can now be moved.") - else if(!anchored) - anchored = 1 - to_chat(user, "[src] is now secured.") - - if(panel_open) - if(istype(I, /obj/item/crowbar)) - if(beaker) - var/obj/item/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - default_deconstruction_crowbar(I) - return 1 + component_parts += new cell_type(null) + RefreshParts() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index 2db474b39c4..848c1ca4ecd 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -88,6 +88,10 @@ /obj/machinery/chem_heater/attack_hand(mob/user) ui_interact(user) +/obj/machinery/chem_heater/attack_ghost(mob/user) + if(user.can_admin_interact()) + return attack_hand(user) + /obj/machinery/chem_heater/attack_ai(mob/user) add_hiddenprint(user) return attack_hand(user) diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 707ead485ff..ffd3ae57bd5 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -21,8 +21,25 @@ /obj/machinery/chem_master/New() ..() create_reagents(100) + component_parts = list() + component_parts += new /obj/item/circuitboard/chem_master(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/console_screen(null) + component_parts += new /obj/item/reagent_containers/glass/beaker(null) + component_parts += new /obj/item/reagent_containers/glass/beaker(null) + RefreshParts() update_icon() +/obj/machinery/chem_master/Destroy() + QDEL_NULL(beaker) + QDEL_NULL(loaded_pill_bottle) + return ..() + +/obj/machinery/chem_master/RefreshParts() + reagents.maximum_volume = 0 + for(var/obj/item/reagent_containers/glass/beaker/B in component_parts) + reagents.maximum_volume += B.reagents.maximum_volume + /obj/machinery/chem_master/ex_act(severity) switch(severity) if(1) @@ -50,6 +67,27 @@ update_icon() /obj/machinery/chem_master/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I)) + if(beaker) + beaker.forceMove(get_turf(src)) + beaker = null + reagents.clear_reagents() + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + loaded_pill_bottle = null + return + + if(exchange_parts(user, I)) + return + + if(panel_open) + if(iscrowbar(I)) + default_deconstruction_crowbar(I) + return TRUE + else + to_chat(user, "You can't use the [name] while it's panel is opened!") + return TRUE + if(default_unfasten_wrench(user, I)) power_change() return @@ -334,7 +372,8 @@ return attack_hand(user) /obj/machinery/chem_master/attack_ghost(mob/user) - return attack_hand(user) + if(user.can_admin_interact()) + return attack_hand(user) /obj/machinery/chem_master/attack_hand(mob/user) if(..()) @@ -399,40 +438,12 @@ name = "\improper CondiMaster 3000" condi = TRUE -/obj/machinery/chem_master/constructable - name = "ChemMaster 2999" - desc = "Used to seperate chemicals and distribute them in a variety of forms." - -/obj/machinery/chem_master/constructable/New() +/obj/machinery/chem_master/condimaster/New() ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/chem_master(null) + QDEL_LIST(component_parts) + component_parts += new /obj/item/circuitboard/chem_master/condi_master(null) component_parts += new /obj/item/stock_parts/manipulator(null) component_parts += new /obj/item/stock_parts/console_screen(null) component_parts += new /obj/item/reagent_containers/glass/beaker(null) component_parts += new /obj/item/reagent_containers/glass/beaker(null) - -/obj/machinery/chem_master/constructable/attackby(obj/item/I, mob/user, params) - - if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I)) - if(beaker) - beaker.forceMove(get_turf(src)) - beaker = null - reagents.clear_reagents() - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(get_turf(src)) - loaded_pill_bottle = null - return - - if(exchange_parts(user, I)) - return - - if(panel_open) - if(iscrowbar(I)) - default_deconstruction_crowbar(I) - return TRUE - else - to_chat(user, "You can't use the [name] while it's panel is opened!") - return TRUE - else - return ..() + RefreshParts() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index d2fb4eec567..6c22360face 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -765,7 +765,7 @@ /datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M) if(M.bodytemperature < 360) M.bodytemperature = min(360, M.bodytemperature + (50 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055 - ..() + return ..() /datum/reagent/consumable/ethanol/devilskiss name = "Devils Kiss" @@ -819,7 +819,7 @@ /datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M) if(M.bodytemperature > 270) M.bodytemperature = max(270, M.bodytemperature - (20 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055 - ..() + return ..() /datum/reagent/consumable/ethanol/grog name = "Grog" @@ -1178,7 +1178,7 @@ if(prob(25)) holder.remove_reagent(id, 15) M.fakevomit() - ..() + return ..() /datum/reagent/consumable/ethanol/synthanol/reaction_mob(mob/living/M, method=TOUCH, volume) if(M.isSynthetic()) diff --git a/code/modules/reagents/chemistry/reagents/blob.dm b/code/modules/reagents/chemistry/reagents/blob.dm index c7dd046664c..1dcd414b702 100644 --- a/code/modules/reagents/chemistry/reagents/blob.dm +++ b/code/modules/reagents/chemistry/reagents/blob.dm @@ -2,6 +2,7 @@ // The 4 damage /datum/reagent/blob description = "" + var/complementary_color = "#000000" var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt can_synth = FALSE @@ -11,8 +12,10 @@ /datum/reagent/blob/ripping_tendrils //does brute and a little stamina damage name = "Ripping Tendrils" + description = "Deals High Brute damage, as well as Stamina damage." id = "ripping_tendrils" color = "#7F0000" + complementary_color = "#a15656" message_living = ", and you feel your skin ripping and tearing off" /datum/reagent/blob/ripping_tendrils/reaction_mob(mob/living/M, method=TOUCH, volume) @@ -25,8 +28,10 @@ /datum/reagent/blob/boiling_oil //sets you on fire, does burn damage name = "Boiling Oil" + description = "Deals High Burn damage, and sets the victim aflame." id = "boiling_oil" color = "#B68D00" + complementary_color = "#c0a856" message = "The blob splashes you with burning oil" message_living = ", and you feel your skin char and melt" @@ -40,8 +45,10 @@ /datum/reagent/blob/envenomed_filaments //toxin, hallucination, and some bonus spore toxin name = "Envenomed Filaments" + description = "Deals High Toxin damage, causes Hallucinations, and injects Spores into the bloodstream." id = "envenomed_filaments" color = "#9ACD32" + complementary_color = "#b0cd73" message_living = ", and you feel sick and nauseated" /datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, volume) @@ -53,8 +60,10 @@ /datum/reagent/blob/lexorin_jelly //does tons of oxygen damage and a little brute name = "Lexorin Jelly" + description = "Deals Medium Brute damage, but massive amounts of Respiration Damage." id = "lexorin_jelly" color = "#00FFC5" + complementary_color = "#56ebc9" message_living = ", and your lungs feel heavy and weak" /datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, volume) @@ -67,8 +76,10 @@ /datum/reagent/blob/kinetic //does semi-random brute damage name = "Kinetic Gelatin" + description = "Deals Randomized damage, between 0.33 to 2.33 times the standard amount." id = "kinetic" color = "#FFA500" + complementary_color = "#ebb756" message = "The blob pummels you" /datum/reagent/blob/kinetic/reaction_mob(mob/living/M, method=TOUCH, volume) @@ -79,8 +90,10 @@ /datum/reagent/blob/cryogenic_liquid //does low burn damage and stamina damage and cools targets down name = "Cryogenic Liquid" + description = "Deals Medium Brute damage, Stamina Damage, and injects Frost Oil into its victims, freezing them to death." id = "cryogenic_liquid" color = "#8BA6E9" + complementary_color = "#a8b7df" message = "The blob splashes you with an icy liquid" message_living = ", and you feel cold and tired" @@ -91,23 +104,12 @@ M.adjustStaminaLoss(0.4*volume) M.reagents.add_reagent("frostoil", 0.4*volume) -/datum/reagent/blob/dark_matter - name = "Dark Matter" - id = "dark_matter" - color = "#61407E" - message = "You feel a thrum as the blob strikes you, and everything flies at you" - -/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - reagent_vortex(M, 0, volume) - volume = ..() - M.apply_damage(0.6*volume, BRUTE) - - /datum/reagent/blob/b_sorium name = "Sorium" + description = "Deals High Brute damage, and sends people flying away." id = "b_sorium" color = "#808000" + complementary_color = "#a2a256" message = "The blob slams into you, and sends you flying" /datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, volume) diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm index a9cbbe87691..9ce636b466a 100644 --- a/code/modules/reagents/chemistry/reagents/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -114,6 +114,19 @@ M.ForceContractDisease(new /datum/disease/vampire(0)) return ..() +/datum/reagent/bacon_grease + name = "pure bacon grease" + id = "bacon_grease" + description = "Hook me up to an IV of that sweet, sweet stuff!" + reagent_state = LIQUID + color = "#F7E6B1" + can_synth = FALSE + +/datum/reagent/bacon_grease/on_mob_life(mob/living/carbon/M) + if(volume > 4.5) + M.ForceContractDisease(new /datum/disease/critical/heart_failure(0)) + return ..() + /datum/reagent/heartworms name = "Space heartworms" id = "heartworms" diff --git a/code/modules/reagents/chemistry/reagents/drink_cold.dm b/code/modules/reagents/chemistry/reagents/drink_cold.dm index 8e902f014f3..707aab07b54 100644 --- a/code/modules/reagents/chemistry/reagents/drink_cold.dm +++ b/code/modules/reagents/chemistry/reagents/drink_cold.dm @@ -42,7 +42,7 @@ /datum/reagent/consumable/drink/cold/ice/on_mob_life(mob/living/M) M.bodytemperature = max(M.bodytemperature - 5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0) - ..() + return ..() /datum/reagent/consumable/drink/cold/space_cola name = "Cola" diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index c4434a92c5e..9b1aca91f8d 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -448,7 +448,7 @@ /datum/reagent/consumable/egg/on_mob_life(mob/living/M) if(prob(3)) M.reagents.add_reagent("cholesterol", rand(1,2)) - ..() + return ..() /datum/reagent/consumable/corn_starch name = "Corn Starch" @@ -643,9 +643,6 @@ color = "#684435" taste_message = "burritos" -/datum/reagent/consumable/beans/on_mob_life(mob/living/M) - return ..() - /datum/reagent/consumable/bread name = "Bread" id = "bread" @@ -845,10 +842,7 @@ to_chat(M, "Your chest is burning with pain!") update_flags |= M.Stun(1, FALSE) update_flags |= M.Weaken(1, FALSE) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.undergoing_cardiac_arrest()) - H.set_heartattack(TRUE) + M.ForceContractDisease(new /datum/disease/critical/heart_failure(0)) return ..() | update_flags /datum/reagent/fungus diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 804904723ea..59db92cf714 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -5,6 +5,7 @@ /datum/reagent/medicine/on_mob_life(mob/living/M) current_cycle++ holder.remove_reagent(id, (metabolization_rate / M.metabolism_efficiency) * M.digestion_ratio) //medicine reagents stay longer if you have a better metabolism + return STATUS_UPDATE_NONE /datum/reagent/medicine/hydrocodone name = "Hydrocodone" @@ -16,13 +17,6 @@ shock_reduction = 200 taste_message = "numbness" -/datum/reagent/medicine/hydrocodone/on_mob_life(mob/living/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.traumatic_shock < 100) - H.shock_stage = 0 - return ..() - /datum/reagent/medicine/sterilizine name = "Sterilizine" id = "sterilizine" @@ -120,7 +114,7 @@ /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE - if(M.bodytemperature < 265) + if(M.bodytemperature < TCRYO) update_flags |= M.adjustCloneLoss(-4, FALSE) update_flags |= M.adjustOxyLoss(-10, FALSE) update_flags |= M.adjustToxLoss(-3, FALSE) @@ -412,10 +406,6 @@ var/update_flags = STATUS_UPDATE_NONE if(prob(55)) update_flags |= M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER, FALSE) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.traumatic_shock < 100) - H.shock_stage = 0 return ..() | update_flags /datum/reagent/medicine/salbutamol @@ -472,7 +462,7 @@ update_flags |= M.AdjustWeakened(-1, FALSE) update_flags |= M.adjustStaminaLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) M.AdjustLoseBreath(-1, bound_lower = 5) - if(M.oxyloss > 75) + if(M.getOxyLoss() > 75) update_flags |= M.adjustOxyLoss(-1, FALSE) if(M.health < 0 || M.health > 0 && prob(33)) update_flags |= M.adjustToxLoss(-1, FALSE) @@ -537,6 +527,7 @@ taste_message = "a delightful numbing" /datum/reagent/medicine/morphine/on_mob_life(mob/living/M) + var/update_flags = STATUS_UPDATE_NONE M.AdjustJitter(-25) switch(current_cycle) if(1 to 15) @@ -545,13 +536,9 @@ if(16 to 35) M.Drowsy(20) if(36 to INFINITY) - M.Paralyse(15) + update_flags |= M.Paralyse(15, FALSE) M.Drowsy(20) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.traumatic_shock < 100) - H.shock_stage = 0 - ..() + return ..() | update_flags /datum/reagent/medicine/oculine name = "Oculine" @@ -600,7 +587,7 @@ if(prob(4)) M.emote("collapse") M.AdjustLoseBreath(-5, bound_lower = 5) - if(M.oxyloss > 65) + if(M.getOxyLoss() > 65) update_flags |= M.adjustOxyLoss(-10*REAGENTS_EFFECT_MULTIPLIER, FALSE) if(M.health < -25) update_flags |= M.adjustToxLoss(-1, FALSE) @@ -636,7 +623,7 @@ update_flags |= M.adjustBrainLoss(-1, FALSE) holder.remove_reagent("histamine", 15) M.AdjustLoseBreath(-1, bound_lower = 3) - if(M.oxyloss > 35) + if(M.getOxyLoss() > 35) update_flags |= M.adjustOxyLoss(-10*REAGENTS_EFFECT_MULTIPLIER, FALSE) if(M.health < -10 && M.health > -65) update_flags |= M.adjustToxLoss(-1*REAGENTS_EFFECT_MULTIPLIER, FALSE) @@ -684,7 +671,7 @@ update_flags |= M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE) return ..() | update_flags -/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method = TOUCH, volume) if(volume < 1) // gotta pay to play return ..() @@ -697,26 +684,19 @@ SM.visible_message("[M] seems to rise from the dead!") if(iscarbon(M)) - if(method == INGEST) + if(method == INGEST || (method == TOUCH && prob(25))) if(M.stat == DEAD) - if(M.getBruteLoss()+M.getFireLoss()+M.getCloneLoss() >= 150) - M.visible_message("[M]'s body starts convulsing!") - M.gib() + if(M.getBruteLoss() + M.getFireLoss() + M.getCloneLoss() >= 150) + M.delayed_gib() return - var/mob/dead/observer/ghost = M.get_ghost() - if(ghost) - to_chat(ghost, "A Strange Reagent is infusing your body with life. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") - window_flash(ghost.client) - ghost << sound('sound/effects/genetics.ogg') - M.visible_message("[M] doesn't appear to respond, perhaps try again later?") - if(!M.suiciding && !ghost && !(NOCLONE in M.mutations) && (M.mind && M.mind.is_revivable())) + if(!M.suiciding && !(NOCLONE in M.mutations) && (!M.mind || M.mind && M.mind.is_revivable())) var/time_dead = world.time - M.timeofdeath M.visible_message("[M] seems to rise from the dead!") M.adjustCloneLoss(50) M.setOxyLoss(0) - M.adjustBruteLoss(rand(0,15)) - M.adjustToxLoss(rand(0,15)) - M.adjustFireLoss(rand(0,15)) + M.adjustBruteLoss(rand(0, 15)) + M.adjustToxLoss(rand(0, 15)) + M.adjustFireLoss(rand(0, 15)) if(ishuman(M)) var/mob/living/carbon/human/H = M var/necrosis_prob = 40 * min((20 MINUTES), max((time_dead - (1 MINUTES)), 0)) / ((20 MINUTES) - (1 MINUTES)) @@ -731,8 +711,8 @@ O.germ_level = INFECTION_LEVEL_THREE H.update_body() + M.grab_ghost() M.update_revive() - M.stat = UNCONSCIOUS add_attack_logs(M, M, "Revived with strange reagent") //Yes, the logs say you revived yourself. ..() @@ -775,7 +755,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M H.update_mutations() - ..() + return ..() /datum/reagent/medicine/antihol name = "Antihol" @@ -789,7 +769,7 @@ M.SetSlur(0) M.AdjustDrunk(-4) M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 8, 0, 1) - if(M.toxloss <= 25) + if(M.getToxLoss() <= 25) update_flags |= M.adjustToxLoss(-2.0, FALSE) return ..() | update_flags @@ -873,6 +853,7 @@ /datum/reagent/medicine/insulin/on_mob_life(mob/living/M) M.reagents.remove_reagent("sugar", 5) + return ..() /datum/reagent/medicine/teporone name = "Teporone" @@ -889,7 +870,7 @@ M.bodytemperature = max(310, M.bodytemperature - (40 * TEMPERATURE_DAMAGE_COEFFICIENT)) else if(M.bodytemperature < 311) M.bodytemperature = min(310, M.bodytemperature + (40 * TEMPERATURE_DAMAGE_COEFFICIENT)) - ..() + return ..() /datum/reagent/medicine/haloperidol name = "Haloperidol" @@ -932,6 +913,7 @@ taste_message = "sleepiness" /datum/reagent/medicine/ether/on_mob_life(mob/living/M) + var/update_flags = STATUS_UPDATE_NONE M.AdjustJitter(-25) switch(current_cycle) if(1 to 30) @@ -940,9 +922,9 @@ if(31 to 40) M.Drowsy(20) if(41 to INFINITY) - M.Paralyse(15) + update_flags |= M.Paralyse(15, FALSE) M.Drowsy(20) - ..() + return ..() | update_flags /datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs name = "Restorative Nanites" diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index 9277ba33fd9..7d92080ae6b 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -162,7 +162,7 @@ if(!H.dna.species.exotic_blood && !(NO_BLOOD in H.dna.species.species_traits)) if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.8 - ..() + return ..() /datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, volume) if(M.has_bane(BANE_IRON) && holder && holder.chem_temp < 150) //If the target is weak to cold iron, then poison them. diff --git a/code/modules/reagents/chemistry/reagents/paradise_pop.dm b/code/modules/reagents/chemistry/reagents/paradise_pop.dm index 204848e1fe9..2294088e54a 100644 --- a/code/modules/reagents/chemistry/reagents/paradise_pop.dm +++ b/code/modules/reagents/chemistry/reagents/paradise_pop.dm @@ -31,7 +31,7 @@ var/turf/simulated/T = get_turf(M) goonchem_vortex(T, 1, 0) to_chat(M, "You briefly feel super-massive, like a black hole. Probably just your imagination...") - ..() + return ..() //Berry Banned: This one is tasty and safe to drink, might have a low chance of healing a random damage type? /datum/reagent/consumable/drink/berry_banned diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index fb58e351a03..d611c3c8d86 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -22,7 +22,7 @@ M.adjust_fire_stacks(mob_burning) M.IgniteMob() if(method == INGEST) - M.adjustFireLoss(min(max(15, volume * 3), 45)) + M.adjustFireLoss(min(max(10, volume * 2), 45)) to_chat(M, "It burns!") M.emote("scream") @@ -242,7 +242,7 @@ M.adjust_fire_stacks(10) M.IgniteMob() if(method == INGEST) - M.adjustFireLoss(min(max(30, volume * 6), 90)) + M.adjustFireLoss(min(max(15, volume * 2.5), 90)) to_chat(M, "It burns!") M.emote("scream") @@ -262,12 +262,6 @@ T.create_reagents(50) T.reagents.add_reagent("sorium", 5) -/datum/reagent/sorium_vortex - name = "sorium_vortex" - id = "sorium_vortex" - reagent_state = LIQUID - color = "#FFA500" - /datum/reagent/liquid_dark_matter name = "Liquid Dark Matter" id = "liquid_dark_matter" @@ -285,12 +279,6 @@ T.create_reagents(50) T.reagents.add_reagent("liquid_dark_matter", 5) -/datum/reagent/ldm_vortex - name = "LDM Vortex" - id = "ldm_vortex" - reagent_state = LIQUID - color = "#800080" - /datum/reagent/blackpowder name = "Black Powder" id = "blackpowder" @@ -354,7 +342,11 @@ if(method == TOUCH) M.ExtinguishMob() -/datum/reagent/cryostylane/reaction_turf(turf/T, volume) +/datum/reagent/cryostylane/reaction_turf(turf/simulated/T, volume) + if(!istype(T)) + return + if(volume >= 3) + T.MakeSlippery(TURF_WET_ICE) if(volume >= 5) for(var/mob/living/carbon/slime/M in T) M.adjustToxLoss(rand(15,30)) diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 510f3ca1368..4cf50c9f661 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -245,7 +245,7 @@ id = "sacid" description = "A strong mineral acid with the molecular formula H2SO4." reagent_state = LIQUID - color = "#00D72B" + color = "#00FF32" process_flags = ORGANIC | SYNTHETIC taste_message = "ACID" @@ -254,58 +254,34 @@ update_flags |= M.adjustFireLoss(1, FALSE) return ..() | update_flags -/datum/reagent/sacid/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(isgrey(H)) - return - +/datum/reagent/sacid/reaction_mob(mob/living/M, method = TOUCH, volume) + if(ishuman(M) && !isgrey(M)) + var/mob/living/carbon/human/H = M + if(method == TOUCH) if(volume > 25) - if(H.wear_mask) - to_chat(H, "Your mask protects you from the acid!") + to_chat(H, "Your [H.wear_mask] protects you from the acid!") return if(H.head) - to_chat(H, "Your helmet protects you from the acid!") + to_chat(H, "Your [H.wear_mask] protects you from the acid!") return - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.receive_damage(5, 10) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(5,10) + if(prob(75)) + H.take_organ_damage(5, 10) + H.emote("scream") + var/obj/item/organ/external/affecting = H.get_organ("head") + if(affecting) + affecting.disfigure() + else + H.take_organ_damage(5, 10) else - M.take_organ_damage(5,10) - - if(method == INGEST) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - if(isgrey(H)) - return - - if(volume >=10 && volume <=25) - if(!H.unacidable) - M.take_organ_damage(0,min(max(volume-10,2)*2,20)) - M.emote("scream") - - - if(volume > 25) - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.receive_damage(0, 20) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(0,20) + H.take_organ_damage(5, 10) + else + to_chat(H, "The greenish acidic substance stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!") + if(volume >= 10) + H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) + H.emote("scream") /datum/reagent/sacid/reaction_obj(obj/O, volume) if((istype(O,/obj/item) || istype(O,/obj/structure/glowshroom)) && prob(40)) @@ -506,19 +482,11 @@ M.fakevomit() update_flags |= M.adjustToxLoss(2, FALSE) update_flags |= M.adjustBruteLoss(2, FALSE) + if(volume > 40 && prob(4)) + M.delayed_gib() + return return ..() | update_flags -/datum/reagent/venom/overdose_process(mob/living/M) - var/update_flags = STATUS_UPDATE_NONE - if(volume >= 40) - if(prob(4)) - M.visible_message("[M] starts convulsing violently!", "You feel as if your body is tearing itself apart!") - update_flags |= M.Weaken(15, FALSE) - M.AdjustJitter(1000) - spawn(rand(20, 100)) - M.gib() - return list(0, update_flags) - /datum/reagent/neurotoxin2 name = "Neurotoxin" id = "neurotoxin2" @@ -622,7 +590,7 @@ id = "facid" description = "Fluorosulfuric acid is a an extremely corrosive super-acid." reagent_state = LIQUID - color = "#4141D2" + color = "#5050FF" process_flags = ORGANIC | SYNTHETIC taste_message = "ACID" @@ -632,47 +600,38 @@ update_flags |= M.adjustFireLoss(1, FALSE) return ..() | update_flags -/datum/reagent/facid/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH || method == INGEST) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - if(volume < 5) - to_chat(M, "The blueish acidic substance stings you, but isn't concentrated enough to harm you!") - - if(volume >=5 && volume <=10) - if(!H.unacidable) - M.take_organ_damage(0,max(volume-5,2)*4) - M.emote("scream") - - - if(volume > 10) - - if(method == TOUCH) - if(H.wear_mask) - if(!H.wear_mask.unacidable) - qdel(H.wear_mask) - H.update_inv_wear_mask() - to_chat(H, "Your mask melts away but protects you from the acid!") - else - to_chat(H, "Your mask protects you from the acid!") - return - - if(H.head) - if(!H.head.unacidable) - qdel(H.head) - H.update_inv_head() - to_chat(H, "Your helmet melts away but protects you from the acid") - else - to_chat(H, "Your helmet protects you from the acid!") - return - - if(!H.unacidable) - var/obj/item/organ/external/head/affecting = H.get_organ("head") +/datum/reagent/facid/reaction_mob(mob/living/M, method = TOUCH, volume) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(method == TOUCH) + if(volume > 9) + if(!H.wear_mask && !H.head) + var/obj/item/organ/external/affecting = H.get_organ("head") if(affecting) - affecting.receive_damage(0, 75) - H.UpdateDamageIcon() + affecting.disfigure() + H.adjustFireLoss(min(max(8, (volume - 5) * 3), 75)) H.emote("scream") + return + else + var/melted_something = FALSE + if(H.wear_mask && !H.wear_mask.unacidable) + qdel(H.wear_mask) + H.update_inv_wear_mask() + to_chat(H, "Your [H.wear_mask] melts away!") + melted_something = TRUE + + if(H.head && !H.head.unacidable) + qdel(H.head) + H.update_inv_head() + to_chat(H, "Your [H.head] melts away!") + melted_something = TRUE + if(melted_something) + return + + if(volume >= 5) + H.emote("scream") + H.adjustFireLoss(min(max(8, (volume - 5) * 3), 75)) + to_chat(H, "The blueish acidic substance stings[volume < 5 ? " you, but isn't concentrated enough to harm you" : null]!") /datum/reagent/facid/reaction_obj(obj/O, volume) if((istype(O, /obj/item) || istype(O, /obj/structure/glowshroom))) @@ -1057,6 +1016,11 @@ update_flags |= M.adjustToxLoss(1, FALSE) return ..() | update_flags +/datum/reagent/pestkiller/reaction_obj(obj/O, volume) + if(istype(O, /obj/effect/decal/ants)) + O.visible_message("The ants die.") + qdel(O) + /datum/reagent/pestkiller/reaction_mob(mob/living/M, method=TOUCH, volume) if(iscarbon(M)) var/mob/living/carbon/C = M @@ -1159,12 +1123,16 @@ M.apply_effect(2, IRRADIATE, 0, negate_armor = 1) if(!M.dna) return + var/did_mutation = FALSE if(prob(15)) randmutb(M) + did_mutation = TRUE if(prob(3)) randmutg(M) - domutcheck(M, null) - M.UpdateAppearance() + did_mutation = TRUE + if(did_mutation) + domutcheck(M, null) + M.UpdateAppearance() return ..() /datum/reagent/ants @@ -1203,6 +1171,6 @@ shock_timer++ if(shock_timer >= rand(5,30)) //Random shocks are wildly unpredictable shock_timer = 0 - M.electrocute_act(rand(5,20), "Teslium in their body", 1, 1) //Override because it's caused from INSIDE of you + M.electrocute_act(rand(5, 20), "Teslium in their body", 1, TRUE) //Override because it's caused from INSIDE of you playsound(M, "sparks", 50, 1) return ..() diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index 5623023659b..dcd21f639d1 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -24,61 +24,34 @@ if(method == TOUCH) // Put out fire M.adjust_fire_stacks(-(volume * 0.2)) - if(ishuman(M)) - - var/mob/living/carbon/human/H = M - - if(!isgrey(H)) //God this is so gross I hate it. - return + if(isgrey(M)) // You gosh darn snowflakes + var/mob/living/carbon/human/G = M + if(method == TOUCH) if(volume > 25) - - if(H.wear_mask) - to_chat(H, "Your mask protects you from the water!") + if(G.wear_mask) + to_chat(G, "Your [G.wear_mask] protects you from the acid!") return - if(H.head) - to_chat(H, "Your helmet protects you from the water!") + if(G.head) + to_chat(G, "Your [G.wear_mask] protects you from the acid!") return - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.receive_damage(5, 10) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(5,10) + if(prob(75)) + G.take_organ_damage(5, 10) + G.emote("scream") + var/obj/item/organ/external/affecting = G.get_organ("head") + if(affecting) + affecting.disfigure() + else + G.take_organ_damage(5, 10) else - M.take_organ_damage(5,10) - - if(method == INGEST) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - if(!isgrey(H)) - return - - if(volume < 10) - to_chat(M, "The watery solvent substance stings you, but isn't concentrated enough to harm you!") - - if(volume >=10 && volume <=25) - if(!H.unacidable) - M.take_organ_damage(0,min(max(volume-10,2)*2,20)) - M.emote("scream") - - - if(volume > 25) - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.receive_damage(0, 20) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(0,20) + G.take_organ_damage(5, 10) + else + to_chat(G, "The water stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!") + if(volume >= 10) + G.adjustFireLoss(min(max(4, (volume - 10) * 2), 20)) + G.emote("scream") /datum/reagent/water/reaction_turf(turf/simulated/T, volume) if(!istype(T)) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 288abeb5f4d..a881f191594 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -11,13 +11,11 @@ var/required_other = 0 // an integer required for the reaction to happen var/result_amount = 0 - var/secondary = 0 // set to nonzero if secondary reaction var/list/secondary_results = list() //additional reagents produced by the reaction var/min_temp = 0 //Minimum temperature required for the reaction to occur (heat to/above this). min_temp = 0 means no requirement var/max_temp = 9999 //Maximum temperature allowed for the reaction to occur (cool to/below this). var/mix_message = "The solution begins to bubble." var/mix_sound = 'sound/effects/bubbles.ogg' - var/no_message = 0 /datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume) return diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 0897de76566..b523bbafb45 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -264,11 +264,4 @@ required_reagents = list("ethanol" = 1, "copper" = 1, "silver" = 1) result_amount = 3 min_temp = T0C + 100 - mix_message = "The solution gently swirls with a metallic sheen." - -/datum/chemical_reaction/corazone - name = "Corazone" - id = "corazone" - result = "corazone" - result_amount = 3 - required_reagents = list("phenol" = 2, "lithium" = 1) + mix_message = "The solution gently swirls with a metallic sheen." \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 5aca554ae03..f2740676314 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -89,55 +89,59 @@ name = "Sorium" id = "sorium" result = "sorium" - required_reagents = list("mercury" = 1, "oxygen" = 1, "nitrogen" = 1, "carbon" = 1) + required_reagents = list("mercury" = 1, "carbon" = 1, "nitrogen" = 1, "oxygen" = 1, "stabilizing_agent" = 1) result_amount = 4 + mix_message = "The mixture pops and crackles before settling down." -/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) +/datum/chemical_reaction/sorium_explosion + name = "Sorium Explosion" + id = "sorium_explosion" + required_reagents = list("mercury" = 1, "carbon" = 1, "nitrogen" = 1, "oxygen" = 1) + result_amount = 1 + mix_message = "The mixture explodes with a big bang." + +/datum/chemical_reaction/sorium_explosion/on_reaction(datum/reagents/holder, created_volume) + var/turf/T = get_turf(holder.my_atom) + if(!T) return - var/turf/simulated/T = get_turf(holder.my_atom) goonchem_vortex(T, 0, created_volume) - holder.remove_reagent("sorium", created_volume) -/datum/chemical_reaction/sorium_vortex +/datum/chemical_reaction/sorium_explosion/sorium name = "sorium_vortex" id = "sorium_vortex" - result = "sorium_vortex" required_reagents = list("sorium" = 1) - result_amount = 1 min_temp = T0C + 200 - -/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume) - var/turf/simulated/T = get_turf(holder.my_atom) - goonchem_vortex(T, 0, created_volume) - holder.remove_reagent("sorium_vortex", created_volume) + mix_sound = null + mix_message = null /datum/chemical_reaction/liquid_dark_matter name = "Liquid Dark Matter" id = "liquid_dark_matter" result = "liquid_dark_matter" + required_reagents = list("plasma" = 1, "radium" = 1, "carbon" = 1, "stabilizing_agent" = 1) + result_amount = 4 + mix_message = "The mixture begins to glow in a dark purple." + +/datum/chemical_reaction/ldm_implosion + name = "Implosion" + id = "implosion" required_reagents = list("plasma" = 1, "radium" = 1, "carbon" = 1) - result_amount = 3 + result_amount = 1 + mix_message = "The mixture implodes suddenly." -/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) - return +/datum/chemical_reaction/ldm_implosion/on_reaction(datum/reagents/holder, created_volume) var/turf/simulated/T = get_turf(holder.my_atom) + if(!T) + return goonchem_vortex(T, 1, created_volume) - holder.remove_reagent("liquid_dark_matter", created_volume) -/datum/chemical_reaction/ldm_vortex +/datum/chemical_reaction/ldm_implosion/liquid_dark_matter name = "LDM Vortex" id = "ldm_vortex" - result = "ldm_vortex" required_reagents = list("liquid_dark_matter" = 1) - result_amount = 1 min_temp = T0C + 200 - -/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume) - var/turf/simulated/T = get_turf(holder.my_atom) - goonchem_vortex(T, 1, created_volume) - holder.remove_reagent("ldm_vortex", created_volume) + mix_sound = null + mix_message = null /datum/chemical_reaction/blackpowder name = "Black Powder" @@ -154,7 +158,7 @@ required_reagents = list("blackpowder" = 1) result_amount = 1 min_temp = T0C + 200 - no_message = 1 + mix_message = null mix_sound = null /datum/chemical_reaction/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume) @@ -175,42 +179,35 @@ spawn(0) qdel(holder.my_atom) -datum/chemical_reaction/flash_powder +/datum/chemical_reaction/flash_powder name = "Flash powder" id = "flash_powder" result = "flash_powder" - required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1) - result_amount = 3 + required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1, "stabilizing_agent" = 1) + result_amount = 5 + mix_message = "The chemicals hiss and fizz briefly before falling still." -/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) - return - var/location = get_turf(holder.my_atom) - do_sparks(2, 1, location) - for(var/mob/living/carbon/C in viewers(5, location)) - if(C.flash_eyes()) - if(get_dist(C, location) < 4) - C.Weaken(5) - continue - C.Stun(5) - holder.remove_reagent("flash_powder", created_volume) - -/datum/chemical_reaction/flash_powder_flash - name = "Flash powder activation" - id = "flash_powder_flash" +/datum/chemical_reaction/flash + name = "Flash" + id = "flash" result = null + required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1) + mix_message = "The chemicals catch fire, burning brightly and violently!" + mix_sound = 'sound/effects/bang.ogg' + +/datum/chemical_reaction/flash/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + if(!location) + return + do_sparks(2, 1, location) + bang(location, holder.my_atom, 5, flash = TRUE, bang = FALSE) + +/datum/chemical_reaction/flash/flash_powder + name = "flash_powder_flash" + id = "flash_powder_flash" required_reagents = list("flash_powder" = 1) min_temp = T0C + 100 - -/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - do_sparks(2, 1, location) - for(var/mob/living/carbon/C in viewers(5, location)) - if(C.flash_eyes()) - if(get_dist(C, location) < 4) - C.Weaken(5) - continue - C.Stun(5) + mix_message = null /datum/chemical_reaction/phlogiston name = "Phlogiston" @@ -250,7 +247,7 @@ datum/chemical_reaction/flash_powder name = "smoke_powder" id = "smoke_powder" result = "smoke_powder" - required_reagents = list("stabilizing_agent" = 1, "potassium" = 1, "sugar" = 1, "phosphorus" = 1) + required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1, "stabilizing_agent" = 1) result_amount = 3 mix_message = "The mixture sets into a greyish powder!" @@ -285,7 +282,6 @@ datum/chemical_reaction/flash_powder id = "smoke_powder_smoke" required_reagents = list("smoke_powder" = 1) min_temp = T0C + 100 - secondary = 1 result_amount = 1 forbidden_reagents = list("stimulants") mix_sound = null @@ -294,78 +290,30 @@ datum/chemical_reaction/flash_powder name = "sonic_powder" id = "sonic_powder" result = "sonic_powder" + required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1, "stabilizing_agent" = 1) + result_amount = 2 + mix_message = "The mixture begins to bubble slighly!" + +/datum/chemical_reaction/sonic_deafen + name = "sonic_deafen" + id = "sonic_deafen" + result = null required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1) - result_amount = 3 + mix_message = "The mixture begins to bubble furiously!" + mix_sound = 'sound/effects/bang.ogg' -/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) - return +/datum/chemical_reaction/sonic_deafen/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) - playsound(location, 'sound/effects/bang.ogg', 25, 1) - for(var/mob/living/M in hearers(5, location)) - var/ear_safety = 0 - var/distance = max(1,get_dist(src,T)) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) - ear_safety++ - to_chat(C, "BANG") - if(!ear_safety) - M.Stun(max(10/distance, 3)) - M.Weaken(max(10/distance, 3)) - M.AdjustEarDamage(rand(0, 5), 15) - if(iscarbon(M)) - var/mob/living/carbon/C = M - var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears) - if(istype(ears)) - if(ears.ear_damage >= 15) - to_chat(M, "Your ears start to ring badly!") - if(prob(ears.ear_damage - 5)) - to_chat(M, "You can't hear anything!") - M.BecomeDeaf() - else - if(ears.ear_damage >= 5) - to_chat(M, "Your ears start to ring!") - holder.remove_reagent("sonic_powder", created_volume) + if(!location) + return + bang(location, holder.my_atom, 5, flash = FALSE, bang = TRUE) -/datum/chemical_reaction/sonic_powder_deafen +/datum/chemical_reaction/sonic_deafen/sonic_powder name = "sonic_powder_deafen" id = "sonic_powder_deafen" - result = null required_reagents = list("sonic_powder" = 1) min_temp = T0C + 100 - -/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - playsound(location, 'sound/effects/bang.ogg', 25, 1) - for(var/mob/living/M in hearers(5, location)) - var/ear_safety = 0 - var/distance = max(1,get_dist(src,T)) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) - ear_safety++ - to_chat(M, "BANG") - if(!ear_safety) - M.Stun(max(10/distance, 3)) - M.Weaken(max(10/distance, 3)) - M.AdjustEarDamage(rand(0, 5), 15) - if(iscarbon(M)) - var/mob/living/carbon/C = M - var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears) - if(istype(ears)) - if(ears.ear_damage >= 15) - to_chat(M, "Your ears start to ring badly!") - if(prob(ears.ear_damage - 5)) - to_chat(M, "You can't hear anything!") - M.BecomeDeaf() - else - if(ears.ear_damage >= 5) - to_chat(M, "Your ears start to ring!") + mix_message = null /datum/chemical_reaction/cryostylane name = "cryostylane" @@ -428,9 +376,9 @@ datum/chemical_reaction/flash_powder /datum/chemical_reaction/shock_explosion/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) - for(var/mob/living/carbon/C in view(min(8, round(created_volume * 2)), T)) - C.Beam(T,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) //What? Why are we beaming from the mob to the turf? Turf to mob generates really odd results. - C.electrocute_act(3.5, "electrical blast") + for(var/mob/living/L in view(min(8, round(created_volume * 2)), T)) + L.Beam(T, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) //What? Why are we beaming from the mob to the turf? Turf to mob generates really odd results. + L.electrocute_act(3.5, "electrical blast") holder.del_reagent("teslium") //Clear all remaining Teslium and Uranium, but leave all other reagents untouched. holder.del_reagent("uranium") diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm index 54e3ce4fdb8..cdc10bcbcc5 100644 --- a/code/modules/reagents/chemistry/recipes/toxins.dm +++ b/code/modules/reagents/chemistry/recipes/toxins.dm @@ -15,7 +15,7 @@ result_amount = 1 min_temp = T0C + 400 mix_sound = null - no_message = 1 + mix_message = null /datum/chemical_reaction/cyanide name = "Cyanide" @@ -139,7 +139,7 @@ required_reagents = list("plasma" = 1, "silver" = 1, "blackpowder" = 1) result_amount = 3 mix_message = "A jet of sparks flies from the mixture as it merges into a flickering slurry." - min_temp = T0C + 130 + min_temp = T0C + 50 mix_sound = null /datum/chemical_reaction/teslium/on_reaction(datum/reagents/holder, created_volume) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 3a9ee271ab5..6aeafd92cf0 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -44,10 +44,28 @@ /obj/item/reagent_containers/glass/bottle/toxin name = "toxin bottle" - desc = "A small bottle of toxins. Do not drink, it is poisonous." + desc = "A small bottle containing toxic compounds." icon_state = "small_bottle" list_reagents = list("toxin" = 30) +/obj/item/reagent_containers/glass/bottle/atropine + name = "atropine bottle" + desc = "A small bottle containing atropine, used for cardiac emergencies." + icon_state = "small_bottle" + list_reagents = list("atropine" = 30) + +/obj/item/reagent_containers/glass/bottle/saline + name = "saline-glucose bottle" + desc = "A small bottle containing saline-glucose solution." + icon_state = "small_bottle" + list_reagents = list("salglu_solution" = 30) + +/obj/item/reagent_containers/glass/bottle/salicylic + name = "salicylic acid bottle" + desc = "A small bottle containing medicine for pain and fevers." + icon_state = "small_bottle" + list_reagents = list("sal_acid" = 30) + /obj/item/reagent_containers/glass/bottle/cyanide name = "cyanide bottle" desc = "A small bottle of cyanide. Bitter almonds?" @@ -99,25 +117,25 @@ /obj/item/reagent_containers/glass/bottle/morphine name = "Morphine Bottle" - desc = "A small bottle. Contains morphine." - icon_state = "round_bottle" + desc = "A small bottle of morphine, a powerful painkiller." + icon_state = "bottle" list_reagents = list("morphine" = 30) /obj/item/reagent_containers/glass/bottle/ether name = "Ether Bottle" - desc = "A small bottle. Contains ether." + desc = "A small bottle of an ether, a strong anesthetic and sedative." icon_state = "round_bottle" list_reagents = list("ether" = 30) /obj/item/reagent_containers/glass/bottle/charcoal name = "Charcoal Bottle" desc = "A small bottle. Contains charcoal." - icon_state = "round_bottle" + icon_state = "wide_bottle" list_reagents = list("charcoal" = 30) /obj/item/reagent_containers/glass/bottle/epinephrine name = "Epinephrine Bottle" - desc = "A small bottle. Contains epinephrine." + desc = "A small bottle. Contains epinephrine - used to stabilize patients." icon_state = "round_bottle" list_reagents = list("epinephrine" = 30) @@ -236,9 +254,21 @@ /obj/item/reagent_containers/glass/bottle/diphenhydramine name = "diphenhydramine bottle" desc = "A small bottle of diphenhydramine." - icon_state = "bottle" + icon_state = "round_bottle" list_reagents = list("diphenhydramine" = 30) +/obj/item/reagent_containers/glass/bottle/oculine + name = "oculine bottle" + desc = "A small bottle of combined eye and ear medication." + icon_state = "round_bottle" + list_reagents = list("oculine" = 30) + +/obj/item/reagent_containers/glass/bottle/potassium_iodide + name = "potassium iodide bottle" + desc = "A small bottle of potassium iodide." + icon_state = "wide_bottle" + list_reagents = list("potass_iodide" = 30) + /obj/item/reagent_containers/glass/bottle/flu_virion name = "Flu virion culture bottle" desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium." diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index cc866f7a2c7..4bd5d25ed3c 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -113,7 +113,7 @@ to_chat(user, "You cannot fill [target] while it is sealed.") return - else if(istype(target, /obj/effect/decal/cleanable)) //stops splashing while scooping up fluids + else if(istype(target, /obj/effect/decal)) //stops splashing while scooping up fluids return else if(reagents.total_volume) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 78e65c82591..4b66482cf1d 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -11,6 +11,7 @@ volume = 100 consume_sound = null taste = FALSE + antable = FALSE /obj/item/reagent_containers/food/pill/New() ..() @@ -103,7 +104,7 @@ name = "Charcoal pill" desc = "Neutralizes many common toxins." icon_state = "pill17" - list_reagents = list("charcoal" = 25) + list_reagents = list("charcoal" = 50) /obj/item/reagent_containers/food/pill/salicylic name = "Salicylic Acid pill" @@ -121,4 +122,22 @@ name = "Hydrocodone pill" desc = "Used to treat extreme pain." icon_state = "pill6" - list_reagents = list("hydrocodone" = 15) \ No newline at end of file + list_reagents = list("hydrocodone" = 15) + +/obj/item/reagent_containers/food/pill/calomel + name = "calomel pill" + desc = "Can be used to purge impurities, but is highly toxic itself." + icon_state = "pill3" + list_reagents = list("calomel" = 15) + +/obj/item/reagent_containers/food/pill/mutadone + name = "mutadone pill" + desc = "Used to cure genetic abnormalities." + icon_state = "pill18" + list_reagents = list("mutadone" = 20) + +/obj/item/reagent_containers/food/pill/mannitol + name = "mannitol pill" + desc = "Used to treat cranial swelling." + icon_state = "pill19" + list_reagents = list("mannitol" = 20) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index e75d5292be2..e28ec4c0cff 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -318,6 +318,11 @@ desc = "Contains insulin - used to treat diabetes." list_reagents = list("insulin" = 15) +/obj/item/reagent_containers/syringe/calomel + name = "Syringe (calomel)" + desc = "Contains calomel, which be used to purge impurities, but is highly toxic itself." + list_reagents = list("calomel" = 15) + /obj/item/reagent_containers/syringe/bioterror name = "bioterror syringe" desc = "Contains several paralyzing reagents." diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 8cf0f52d847..239cb71328e 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -177,7 +177,9 @@ var/obj/structure/closet/crate/O = target if(O.opened) return - if(use(3)) + if(amount >= 3 && do_after_once(user, 15, target = target)) + if(O.opened || !use(3)) + return var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) P.icon_state = "deliverycrate" P.wrapped = O @@ -189,7 +191,9 @@ var/obj/structure/closet/O = target if(O.opened) return - if(use(3)) + if(amount >= 3 && do_after_once(user, 15, target = target)) + if(O.opened || !use(3)) + return var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc)) P.wrapped = O P.init_welded = O.welded diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index cc6305319c7..a23378f5513 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -163,8 +163,8 @@ category = list("Medical Machinery") /datum/design/chem_dispenser - name = "Machine Board (Portable Chem Dispenser)" - desc = "The circuit board for a Portable Chem Dispenser." + name = "Machine Board (Chem Dispenser)" + desc = "The circuit board for a Chem Dispenser." id = "chem_dispenser" req_tech = list("programming" = 5, "biotech" = 3, "materials" = 4, "plasmatech" = 4) build_type = IMPRINTER @@ -173,8 +173,8 @@ category = list("Medical Machinery") /datum/design/chem_master - name = "Machine Design (Chem Master Board)" - desc = "The circuit board for a Chem Master 2999." + name = "Machine Design (ChemMaster Board)" + desc = "The circuit board for a ChemMaster 3000." id = "chem_master" req_tech = list("biotech" = 3, "materials" = 3, "programming" = 2) build_type = IMPRINTER diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 076074a7bb4..5b5dba286fd 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -974,9 +974,9 @@ desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles." id = "mech_plasma_cutter" build_type = MECHFAB - req_tech = list("engineering" = 3, "materials" = 3, "plasmatech" = 4) + req_tech = list("engineering" = 4, "materials" = 5, "plasmatech" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma - materials = list(MAT_METAL = 8000, MAT_GLASS = 1000, MAT_PLASMA = 2000) + materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_PLASMA = 6000) construction_time = 100 category = list("Exosuit Equipment") diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index d5434765e30..d945722770e 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -52,6 +52,16 @@ build_path = /obj/item/healthupgrade category = list("Medical") +/datum/design/handheld_defib + name = "Handheld Defibrillator" + desc = "A smaller defibrillator only capable of treating cardiac arrest." + id = "handheld_defib" + req_tech = list("biotech" = 2, "magnets" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 20, MAT_GLASS = 20) + build_path = /obj/item/handheld_defibrillator + category = list("Medical") + /datum/design/defib name = "Defibrillator" desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients." diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm index 2ebb962ce22..14cd12c6837 100644 --- a/code/modules/research/designs/mining_designs.dm +++ b/code/modules/research/designs/mining_designs.dm @@ -1,122 +1,122 @@ -///////////////////////////////////////// -/////////////////Mining////////////////// -///////////////////////////////////////// -/datum/design/drill_diamond - name = "Diamond Mining Drill" - desc = "Yours is the drill that will pierce the heavens!" - id = "drill_diamond" - req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. - build_path = /obj/item/pickaxe/drill/diamonddrill - category = list("Mining") - -/datum/design/drill - name = "Mining Drill" - desc = "Yours is the drill that will pierce through the rock walls." - id = "drill" - req_tech = list("materials" = 2, "powerstorage" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) - build_path = /obj/item/pickaxe/drill - category = list("Mining") - -/datum/design/plasmacutter - name = "Plasma Cutter" - desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." - id = "plasmacutter" - req_tech = list("materials" = 3, "plasmatech" = 3, "magnets" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) - build_path = /obj/item/gun/energy/plasmacutter - category = list("Mining") - -/datum/design/plasmacutter_adv - name = "Advanced Plasma Cutter" - desc = "It's an advanced plasma cutter, oh my god." - id = "plasmacutter_adv" - req_tech = list("materials" = 4, "plasmatech" = 4, "engineering" = 2, "combat" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) - build_path = /obj/item/gun/energy/plasmacutter/adv - category = list("Mining") - -/datum/design/jackhammer - name = "Sonic Jackhammer" - desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." - id = "jackhammer" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 6, "magnets" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) - build_path = /obj/item/pickaxe/drill/jackhammer - category = list("Mining") - -/datum/design/superresonator - name = "Upgraded Resonator" - desc = "An upgraded version of the resonator that allows more fields to be active at once." - id = "superresonator" - req_tech = list("materials" = 4, "powerstorage" = 3, "engineering" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) - build_path = /obj/item/resonator/upgraded - category = list("Mining") - -/datum/design/trigger_guard_mod - name = "Kinetic Accelerator Trigger Guard Mod" - desc = "A device which allows kinetic accelerators to be wielded by any organism." - id = "triggermod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/trigger_guard - category = list("Mining") - -/datum/design/damage_mod - name = "Kinetic Accelerator Damage Mod" - desc = "A device which allows kinetic accelerators to deal more damage." - id = "damagemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/damage - category = list("Mining", "Cyborg Upgrade Modules") - -/datum/design/cooldown_mod - name = "Kinetic Accelerator Cooldown Mod" - desc = "A device which decreases the cooldown of a Kinetic Accelerator." - id = "cooldownmod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/cooldown - category = list("Mining", "Cyborg Upgrade Modules") - -/datum/design/range_mod - name = "Kinetic Accelerator Range Mod" - desc = "A device which allows kinetic accelerators to fire at a further range." - id = "rangemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/range - category = list("Mining", "Cyborg Upgrade Modules") - -/datum/design/superaccelerator - name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do more damage while indoors." - id = "indoormod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) - build_path = /obj/item/borg/upgrade/modkit/indoors - category = list("Mining", "Cyborg Upgrade Modules") - -/datum/design/hyperaccelerator - name = "Kinetic Accelerator Mining AoE Mod" - desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." - id = "hypermod" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) - build_path = /obj/item/borg/upgrade/modkit/aoe/turfs - category = list("Mining", "Cyborg Upgrade Modules") +///////////////////////////////////////// +/////////////////Mining////////////////// +///////////////////////////////////////// +/datum/design/drill_diamond + name = "Diamond Mining Drill" + desc = "Yours is the drill that will pierce the heavens!" + id = "drill_diamond" + req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. + build_path = /obj/item/pickaxe/drill/diamonddrill + category = list("Mining") + +/datum/design/drill + name = "Mining Drill" + desc = "Yours is the drill that will pierce through the rock walls." + id = "drill" + req_tech = list("materials" = 2, "powerstorage" = 2, "engineering" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) + build_path = /obj/item/pickaxe/drill + category = list("Mining") + +/datum/design/plasmacutter + name = "Plasma Cutter" + desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." + id = "plasmacutter" + req_tech = list("materials" = 3, "plasmatech" = 3, "magnets" = 2) + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1000, MAT_PLASMA = 1500) + build_path = /obj/item/gun/energy/plasmacutter + category = list("Mining") + +/datum/design/plasmacutter_adv + name = "Advanced Plasma Cutter" + desc = "It's an advanced plasma cutter, oh my god." + id = "plasmacutter_adv" + req_tech = list("materials" = 4, "plasmatech" = 4, "engineering" = 2, "combat" = 3, "magnets" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1000, MAT_PLASMA = 4000, MAT_GOLD = 500) + build_path = /obj/item/gun/energy/plasmacutter/adv + category = list("Mining") + +/datum/design/jackhammer + name = "Sonic Jackhammer" + desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." + id = "jackhammer" + req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 6, "magnets" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) + build_path = /obj/item/pickaxe/drill/jackhammer + category = list("Mining") + +/datum/design/superresonator + name = "Upgraded Resonator" + desc = "An upgraded version of the resonator that allows more fields to be active at once." + id = "superresonator" + req_tech = list("materials" = 4, "powerstorage" = 3, "engineering" = 3, "magnets" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) + build_path = /obj/item/resonator/upgraded + category = list("Mining") + +/datum/design/trigger_guard_mod + name = "Kinetic Accelerator Trigger Guard Mod" + desc = "A device which allows kinetic accelerators to be wielded by any organism." + id = "triggermod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/trigger_guard + category = list("Mining") + +/datum/design/damage_mod + name = "Kinetic Accelerator Damage Mod" + desc = "A device which allows kinetic accelerators to deal more damage." + id = "damagemod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/damage + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/cooldown_mod + name = "Kinetic Accelerator Cooldown Mod" + desc = "A device which decreases the cooldown of a Kinetic Accelerator." + id = "cooldownmod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/cooldown + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/range_mod + name = "Kinetic Accelerator Range Mod" + desc = "A device which allows kinetic accelerators to fire at a further range." + id = "rangemod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/range + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/superaccelerator + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do more damage while indoors." + id = "indoormod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) + build_path = /obj/item/borg/upgrade/modkit/indoors + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/hyperaccelerator + name = "Kinetic Accelerator Mining AoE Mod" + desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." + id = "hypermod" + req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) + build_path = /obj/item/borg/upgrade/modkit/aoe/turfs + category = list("Mining", "Cyborg Upgrade Modules") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index f60954a83a6..0587f6e4f73 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -384,13 +384,13 @@ if(!istype(C)) to_chat(user, "The potion can only be used on clothing!") return - if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + if(C.max_heat_protection_temperature == FIRE_IMMUNITY_MAX_TEMP_PROTECT) to_chat(user, "[C] is already fireproof!") return ..() to_chat(user, "You slather the blue gunk over [C], fireproofing it.") C.name = "fireproofed [C.name]" C.color = "#000080" - C.max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT + C.max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT C.heat_protection = C.body_parts_covered C.burn_state = FIRE_PROOF uses -- diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index d9510d28114..8cb29ecf3b4 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -178,7 +178,7 @@ var/ert_request_answered = FALSE ticker.mode.ert += M.mind M.forceMove(spawn_location) - job_master.CreateMoneyAccount(M, class, null) + SSjobs.CreateMoneyAccount(M, class, null) active_team.equip_officer(class, M) diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index 368868770c7..b287643901d 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -306,7 +306,8 @@ /obj/item/roller = 1, /obj/item/storage/pill_bottle/ert = 1, /obj/item/flashlight = 1, - /obj/item/healthupgrade = 1 + /obj/item/healthupgrade = 1, + /obj/item/handheld_defibrillator = 1 ) /datum/outfit/job/centcom/response_team/medic/red @@ -335,7 +336,8 @@ /obj/item/roller = 1, /obj/item/clothing/shoes/magboots = 1, /obj/item/bodyanalyzer = 1, - /obj/item/healthupgrade = 1 + /obj/item/healthupgrade = 1, + /obj/item/handheld_defibrillator = 1 ) /datum/outfit/job/centcom/response_team/medic/gamma @@ -357,7 +359,8 @@ /obj/item/bodyanalyzer/advanced = 1, /obj/item/extinguisher/mini = 1, /obj/item/roller = 1, - /obj/item/healthanalyzer/advanced = 1 + /obj/item/healthanalyzer/advanced = 1, + /obj/item/handheld_defibrillator = 1 ) diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm index f5d3fe7e1bf..050326891fb 100644 --- a/code/modules/security_levels/security levels.dm +++ b/code/modules/security_levels/security levels.dm @@ -77,7 +77,7 @@ FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) - security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!") + security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!", new_sound = sound('sound/effects/new_siren.ogg')) security_level = SEC_LEVEL_GAMMA move_gamma_ship() @@ -102,7 +102,7 @@ FA.update_icon() if(SEC_LEVEL_EPSILON) - security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!") + security_announcement_up.Announce("Central Command has ordered the Epsilon security level on the station. Consider all contracts terminated.","Attention! Epsilon security level activated!", new_sound = sound('sound/effects/purge_siren.ogg')) security_level = SEC_LEVEL_EPSILON post_status("alert", "epsilonalert") diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index dfa54f086d1..06e0c2336f0 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -714,6 +714,8 @@ possible_destinations = C.possible_destinations shuttleId = C.shuttleId +/obj/machinery/computer/shuttle/Initialize(mapload) + . = ..() connect() /obj/machinery/computer/shuttle/proc/connect() diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index a6baec94d26..f48906fd1f3 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -739,7 +739,7 @@ return 1 /obj/machinery/computer/supplycomp/proc/post_signal(var/command) - var/datum/radio_frequency/frequency = radio_controller.return_frequency(DISPLAY_FREQ) + var/datum/radio_frequency/frequency = SSradio.return_frequency(DISPLAY_FREQ) if(!frequency) return diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 0ff4273daa1..78264ca0329 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -18,23 +18,11 @@ // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() - var/list/blood_data = get_blood_data(get_blood_id())//PROCCEPTION - if(NO_BLOOD in dna.species.species_traits) bleed_rate = 0 return - if(bodytemperature >= 225 && !(NOCLONE in mutations)) //cryosleep or husked people do not pump the blood. - - //Blood regeneration if there is some space - if(blood_volume < max_blood && blood_volume) - if(mind) //Handles vampires "eating" blood that isn't their own. - if(mind in ticker.mode.vampires) - if(nutrition >= NUTRITION_LEVEL_WELL_FED) - return //We don't want blood tranfusions making vampires fat. - if(blood_data["donor"] != src) - nutrition += (15 * REAGENTS_METABOLISM) - return //Only process one blood per tick, to maintain the same metabolism as nutriment for non-vampires. + if(bodytemperature >= TCRYO && !(NOCLONE in mutations)) //cryosleep or husked people do not pump the blood. if(blood_volume < BLOOD_VOLUME_NORMAL) blood_volume += 0.1 // regenerate blood VERY slowly @@ -56,7 +44,7 @@ if(prob(15)) Paralyse(rand(1,3)) to_chat(src, "You feel extremely [word].") - if(0 to BLOOD_VOLUME_SURVIVE) + if(-INFINITY to BLOOD_VOLUME_SURVIVE) death() var/temp_bleed = 0 diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 04626864b94..512de9de9e9 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -160,6 +160,7 @@ /obj/item/organ/internal/heart/cybernetic/upgraded/on_life() if(!ishuman(owner)) return + if(!(status & ORGAN_DEAD) && !attempted_restart && !beating) to_chat(owner, "Your [name] detects a cardiac event and attempts to return to its normal rhythm!") if(prob(20) && emagged) @@ -180,6 +181,28 @@ addtimer(CALLBACK(src, .proc/recharge), 300) addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] fails to return to its normal rhythm!"), 30) + if(!(status & ORGAN_DEAD) && !attempted_restart && owner.HasDisease(new /datum/disease/critical/heart_failure(0))) + to_chat(owner, "Your [name] detects a cardiac event and attempts to return to its normal rhythm!") + if(prob(40) && emagged) + attempted_restart = TRUE + for(var/datum/disease/critical/heart_failure/HF in owner.viruses) + HF.cure() + addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] returns to its normal rhythm!"), 30) + addtimer(CALLBACK(src, .proc/recharge), 200) + else if(prob(25)) + attempted_restart = TRUE + for(var/datum/disease/critical/heart_failure/HF in owner.viruses) + HF.cure() + addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] returns to its normal rhythm!"), 30) + addtimer(CALLBACK(src, .proc/recharge), 200) + else + attempted_restart = TRUE + if(emagged) + addtimer(CALLBACK(src, .proc/recharge), 200) + else + addtimer(CALLBACK(src, .proc/recharge), 300) + addtimer(CALLBACK(src, .proc/message_to_owner, owner, "Your [name] fails to return to its normal rhythm!"), 30) + if(!(status & ORGAN_DEAD)) var/boost = emagged ? 2 : 1 owner.AdjustDrowsy(-4 * boost) @@ -230,7 +253,7 @@ owner.adjustFireLoss(numHigh) if(prob(numMid)) to_chat(owner, "Your [name] lurches awkwardly!") - Stop() + owner.ForceContractDisease(new /datum/disease/critical/heart_failure(0)) if(prob(numMid)) to_chat(owner, "Your [name] stops beating!") Stop() @@ -246,4 +269,4 @@ owner.adjustFireLoss(numMid) if(prob(numLow)) to_chat(owner, "Your [name] lurches awkwardly!") - Stop() \ No newline at end of file + owner.ForceContractDisease(new /datum/disease/critical/heart_failure(0)) \ No newline at end of file diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 3026da6f66a..47fa74969d0 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -19,20 +19,16 @@ var/safe_toxins_max = 0.05 var/SA_para_min = 1 //Sleeping agent var/SA_sleep_min = 5 //Sleeping agent - var/gas_toxicity_multiplier = 100 - var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE - var/oxy_breath_dam_max = MAX_TOXIC_GAS_DAMAGE + var/oxy_damage_type = OXY - var/nitro_breath_dam_min = MIN_TOXIC_GAS_DAMAGE - var/nitro_breath_dam_max = MAX_TOXIC_GAS_DAMAGE + var/oxy_breath_dam_multiplier = 1 var/nitro_damage_type = OXY - var/co2_breath_dam_min = MIN_TOXIC_GAS_DAMAGE - var/co2_breath_dam_max = MAX_TOXIC_GAS_DAMAGE + var/nitro_breath_dam_multiplier = 1 var/co2_damage_type = OXY - var/tox_breath_dam_min = MIN_TOXIC_GAS_DAMAGE - var/tox_breath_dam_max = MAX_TOXIC_GAS_DAMAGE + var/co2_breath_dam_multiplier = 1 var/tox_damage_type = TOX + var/tox_breath_dam_multiplier = 1 var/cold_message = "your face freezing and an icicle forming" var/cold_level_1_threshold = 260 @@ -88,12 +84,11 @@ return if(!breath || (breath.total_moles() == 0)) - if(H.health >= config.health_threshold_crit) - H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) - else if(!(NOCRITDAMAGE in H.dna.species.species_traits)) - H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) + if(isspaceturf(loc)) + H.adjustOxyLoss(10) + else + H.adjustOxyLoss(5) - H.failed_last_breath = TRUE if(safe_oxygen_min) H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) else if(safe_toxins_min) @@ -104,6 +99,10 @@ H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro) return FALSE + + if(H.health < HEALTH_THRESHOLD_CRIT) + return FALSE + var/gas_breathed = 0 //Partial pressures in our breath @@ -118,8 +117,8 @@ //Too much oxygen! //Yes, some species may not like it. if(safe_oxygen_max) if(O2_pp > safe_oxygen_max) - var/ratio = (breath.oxygen/safe_oxygen_max) * gas_toxicity_multiplier - H.apply_damage_type(Clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type) + var/ratio = breath.oxygen/safe_oxygen_max + H.apply_damage_type(ratio * 325 * oxy_breath_dam_multiplier, oxy_damage_type) H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) else H.clear_alert("too_much_oxy") @@ -130,8 +129,7 @@ gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.oxygen) H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) else - H.failed_last_breath = FALSE - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS) gas_breathed = breath.oxygen H.clear_alert("not_enough_oxy") @@ -145,8 +143,8 @@ //Too much nitrogen! if(safe_nitro_max) if(N2_pp > safe_nitro_max) - var/ratio = (breath.nitrogen/safe_nitro_max) * gas_toxicity_multiplier - H.apply_damage_type(Clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type) + var/ratio = breath.nitrogen/safe_nitro_max + H.apply_damage_type(ratio * 325 * nitro_breath_dam_multiplier, nitro_damage_type) H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro) else H.clear_alert("too_much_nitro") @@ -157,8 +155,7 @@ gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.nitrogen) H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro) else - H.failed_last_breath = FALSE - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS) gas_breathed = breath.nitrogen H.clear_alert("not_enough_nitro") @@ -176,9 +173,9 @@ H.co2overloadtime = world.time else if(world.time - H.co2overloadtime > 120) H.Paralyse(3) - H.apply_damage_type(3, co2_damage_type) // Lets hurt em a little, let them know we mean business + H.apply_damage_type(HUMAN_MAX_OXYLOSS * co2_breath_dam_multiplier, co2_damage_type) // Lets hurt em a little, let them know we mean business if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good! - H.apply_damage_type(8, co2_damage_type) + H.apply_damage_type(15 * co2_breath_dam_multiplier, co2_damage_type) H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2) if(prob(20)) // Lets give them some chance to know somethings not right though I guess. H.emote("cough") @@ -193,8 +190,7 @@ gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.carbon_dioxide) H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) else - H.failed_last_breath = FALSE - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS) gas_breathed = breath.carbon_dioxide H.clear_alert("not_enough_co2") @@ -209,8 +205,8 @@ //Too much toxins! if(safe_toxins_max) if(Toxins_pp > safe_toxins_max) - var/ratio = (breath.toxins/safe_toxins_max) * gas_toxicity_multiplier - H.apply_damage_type(Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type) + var/ratio = breath.toxins/safe_toxins_max + H.apply_damage_type(ratio * 325 * tox_breath_dam_multiplier, tox_damage_type) H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) else H.clear_alert("too_much_tox") @@ -222,8 +218,7 @@ gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.toxins) H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) else - H.failed_last_breath = FALSE - H.adjustOxyLoss(-5) + H.adjustOxyLoss(-HUMAN_MAX_OXYLOSS) gas_breathed = breath.toxins H.clear_alert("not_enough_tox") @@ -261,11 +256,9 @@ if(breath_pp > 0) var/ratio = safe_breath_min/breath_pp H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all! - H.failed_last_breath = TRUE . = true_pp*ratio/6 else H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) - H.failed_last_breath = TRUE /obj/item/organ/internal/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures @@ -332,6 +325,7 @@ safe_oxygen_max = 0.05 //This is toxic to us safe_nitro_min = 16 //We breathe THIS! oxy_damage_type = TOX //And it poisons us + oxy_breath_dam_multiplier = 0.16 /obj/item/organ/internal/lungs/drask icon = 'icons/obj/species_organs/drask.dmi' @@ -341,7 +335,7 @@ cold_level_1_damage = -COLD_GAS_DAMAGE_LEVEL_1 //They heal when the air is cold cold_level_2_damage = -COLD_GAS_DAMAGE_LEVEL_2 cold_level_3_damage = -COLD_GAS_DAMAGE_LEVEL_3 - cold_damage_types = list(BRUTE = 1, BURN = 0.5) + cold_damage_types = list(BRUTE = 0.5, BURN = 0.25) /obj/item/organ/internal/lungs/cybernetic name = "cybernetic lungs" diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm index 536ca7a4f37..f330df260eb 100644 --- a/code/modules/surgery/organs/parasites.dm +++ b/code/modules/surgery/organs/parasites.dm @@ -52,10 +52,11 @@ var/egg_progress = 0 // # of on_life() cycles completed, unlike cycle_num this is reset on each hatch event var/egg_progress_per_hatch = 90 // if egg_progress > this, chance to hatch and reset egg_progress var/eggs_hatched = 0 // num of hatch events completed - var/eggs_max = 3 // max possible spiderlings you can get from a single infection if its left to run for a very long time var/awaymission_checked = FALSE var/awaymission_infection = FALSE // TRUE if infection occurred inside gateway - var/list/types_basic = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green) + var/list/types_basic = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray) + var/list/types_adv = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green) + /obj/item/organ/internal/body_egg/terror_eggs/on_life() // Safety first. @@ -78,19 +79,11 @@ qdel(src) return - // Detect dying hosts, and try to keep them alive (so spiderlings can hatch) at the cost of some growth progress. - if(owner.health < -25) - to_chat(owner,"You feel a strange, blissful senstation.") - owner.adjustBruteLoss(-5) - owner.adjustFireLoss(-5) - owner.adjustToxLoss(-5) - egg_progress += 10 - // Once at least one egg has hatched from you, you'll need help to reach medbay. if(eggs_hatched >= 1) owner.Confused(2) - if(egg_progress > egg_progress_per_hatch && eggs_hatched < eggs_max) + if(egg_progress > egg_progress_per_hatch) egg_progress -= egg_progress_per_hatch hatch_egg() @@ -107,15 +100,22 @@ return extra_progress /obj/item/organ/internal/body_egg/terror_eggs/proc/hatch_egg() + var/infection_completed = FALSE var/obj/structure/spider/spiderling/terror_spiderling/S = new(get_turf(owner)) - if(eggs_hatched >= 2) // on the third egg... - S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/princess - else - S.grow_as = pick(types_basic) + switch(eggs_hatched) + if(0) // First spiderling + S.grow_as = pick(types_basic) + if(1) // Second + S.grow_as = pick(types_adv) + if(2) // Last + S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/princess + infection_completed = TRUE S.immediate_ventcrawl = TRUE eggs_hatched++ to_chat(owner, "A strange prickling sensation moves across your skin... then suddenly the whole world seems to spin around you!") owner.Paralyse(10) + if(infection_completed && !QDELETED(src)) + qdel(src) /obj/item/organ/internal/body_egg/terror_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 53691dd0264..46e4ee0c18b 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -57,10 +57,10 @@ origin_tech = "materials=1;biotech=1" attack_verb = list("drilled") - suicide_act(mob/user) - to_chat(viewers(user), pick("[user] is pressing [src] to [user.p_their()] temple and activating it! It looks like [user.p_theyre()] trying to commit suicide.", - "[user] is pressing [src] to [user.p_their()] chest and activating it! It looks like [user.p_theyre()] trying to commit suicide.")) - return (BRUTELOSS) +/obj/item/surgicaldrill/suicide_act(mob/user) + to_chat(viewers(user), pick("[user] is pressing [src] to [user.p_their()] temple and activating it! It looks like [user.p_theyre()] trying to commit suicide.", + "[user] is pressing [src] to [user.p_their()] chest and activating it! It looks like [user.p_theyre()] trying to commit suicide.")) + return BRUTELOSS /obj/item/surgicaldrill/augment desc = "Effectively a small power drill contained within your arm, edges dulled to prevent tissue damage. May or may not pierce the heavens." @@ -87,11 +87,11 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' - suicide_act(mob/user) - to_chat(viewers(user), pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide.", - "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide.", - "[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku.")) - return (BRUTELOSS) +/obj/item/scalpel/suicide_act(mob/user) + to_chat(viewers(user), pick("[user] is slitting [user.p_their()] wrists with [src]! It looks like [user.p_theyre()] trying to commit suicide.", + "[user] is slitting [user.p_their()] throat with [src]! It looks like [user.p_theyre()] trying to commit suicide.", + "[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku.")) + return BRUTELOSS /obj/item/scalpel/augment diff --git a/config/example/config.txt b/config/example/config.txt index 40d9d870cf4..d93809c32cd 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -324,10 +324,10 @@ PLAYER_REROUTE_CAP 0 #DISABLE_SPACE_RUINS ## Minimum number of space ruins levels to generate -EXTRA_SPACE_RUINS_LEVELS_MIN 2 +EXTRA_SPACE_RUIN_LEVELS_MIN 2 ## Maximum number of space ruins levels to generate -EXTRA_SPACE_RUINS_LEVELS_MAX 4 +EXTRA_SPACE_RUIN_LEVELS_MAX 4 ## Uncomment to disable the OOC/LOOC channel by default. #DISABLE_OOC @@ -399,4 +399,7 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60 ##DEVELOPER_EXPRESS_START ## Uncomment to disable automatic admin for localhost -#DISABLE_LOCALHOST_ADMIN \ No newline at end of file +#DISABLE_LOCALHOST_ADMIN + +## Uncomment to give a confirmation before hitting start now +#START_NOW_CONFIRMATION \ No newline at end of file diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 8a477dd6610..f934ba87b2b 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -1,10 +1,4 @@ ### HEALTH ### -## level of health at which a mob becomes unconscious (crit) -HEALTH_THRESHOLD_CRIT -50 - -## level of health at which a mob becomes dead -HEALTH_THRESHOLD_DEAD -100 - ## Determines whether bones can be broken through excessive damage to the organ ## 0 means bones can't break, 1 means they can BONES_CAN_BREAK 1 diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css index fe68df7afcb..fed5a252ba3 100644 --- a/goon/browserassets/css/browserOutput-dark.css +++ b/goon/browserassets/css/browserOutput-dark.css @@ -364,6 +364,7 @@ h1.alert, h2.alert {color: #FFF;} .bold {font-weight: bold;} .center {text-align: center;} .red {color: #FF0000;} +.purple {color: #5e2d79;} .skeleton {color: #C8C8C8; font-weight: bold; font-style: italic;} .gutter {color: #7092BE; font-family: "Trebuchet MS", cursive, sans-serif;} .orange {color: #ffa500;} diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index 69c946460b0..1af8b03bd58 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -361,6 +361,7 @@ h1.alert, h2.alert {color: #000000;} .bold {font-weight: bold;} .center {text-align: center;} .red {color: #FF0000;} +.purple {color: #5e2d79;} .skeleton {color: #585858; font-weight: bold; font-style: italic;} .gutter {color: #7092BE; font-family: "Trebuchet MS", cursive, sans-serif;} .orange {color: #ffa500;} diff --git a/html/changelog.html b/html/changelog.html index 5401db048ea..7c4262f54ce 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,279 @@ -->
+

08 April 2019

+

TDSSS updated:

+
    +
  • Added missing vent in toxins mixing
  • +
+ +

07 April 2019

+

Arkatos updated:

+
    +
  • Guardians can no longer change action intents on their own
  • +
  • Fixes #10900 - Guardians can no longer attack their host while inside them
  • +
  • Explosive and Support Guardians now get precise cooldown shown (instead of just static estimate) before their bomb and beacon abitilites are ready to be used again, respectively
  • +
  • HARM action intent icon for Guardians updated
  • +
  • Dehydrated Space Carp TC cost changed from 3 to 2
  • +
  • Shadowling Glare ability reworked - The further Shadowling is from their glared target, the shorter stun their target gets. Stuns also have a delay before they kick in, based on the distance, however targets will be slowed and muted before stun takes effect. Targets on the tile just next to them are still stunned and muted for 10 seconds without any delay.
  • +
  • Added victory message to the End Round messages in the Shadowlings Rounds
  • +
  • Shadowling Destroy Engines ability reworked. You now need to sacrifice non-ally target to delay the emergency shuttle arrival by 10 minutes, and shuttle will be unable to be recalled. This ability can be used only once across ALL Shadowlings.
  • +
  • Descriptions now show with a mouse hover over action buttons
  • +
+

Fox McCloud updated:

+
    +
  • Fixes Russian revolvers triggering no matter where you clicked
  • +
  • Power gloves electric shocks can target anything now (still only damages mobs)
  • +
  • Power gloves electric arcs will bounce around (if it happens to target a mob though, it'll ground out and not bounce any more)
  • +
  • Power gloves cooldown lowered from 12 to 4
  • +
  • Power gloves heat up the turf they target
  • +
  • Using power gloves on disarm intent will weaken your target instead of dealing damage
  • +
  • CLF3, Phlogiston, and Fluorosulfuric acid all require greater volumes to achieve their upper damage limits
  • +
  • CLF3 and Phlogiston have lower minimum damage
  • +
  • Grey's treat water more closely to sulfuric acid (including passive damage while it's in them)
  • +
  • Grey's don't instantly purge all sulfuric acid from their system; it depletes at the normal rate, but doens't cause damage
  • +
  • Foam altered to be a bit more viable compared to smoke
  • +
  • Fixes being unable to view pill bottle inventory in some circumstances
  • +
  • Vending items from vending machines will try to put the item in your hands after vending
  • +
  • Vending machines with refill-canisters can be beaten apart and broken
  • +
+

Kyep updated:

+
    +
  • Ghosting while alive, conscious, and a member of the crew will now result in your body being moved to cryo after 5 minutes, assuming your body isn't killed or restrained in any way in the meantime.
  • +
  • An AI that ghosts while alive gets a dismissable hint that they might consider using OOC -> Wipe Core instead.
  • +
  • Ghosting out of your body while you are alive, and an antag, will result in admins being informed, so that they may replace you as an antag if needed.
  • +
  • Empress of terror (admin-only mob) is no longer incorrectly prevented from laying brown spider eggs.
  • +
  • Admins are now able to spawn a queen of terror in a room without a vent. Previously, queens would not allow this. Now, this just results in an alert to admins (since its probably a mistake) and deactivates the mob AI (but leaves it available for player control).
  • +
  • If there are player controlled terror spiders, admins using check antags panel will now be able to see eggs/spiderlings currently growing on the station. These counters only count eggs/spiderlings on station, and ignore fake spiderlings.
  • +
  • Empress of terror's 'erase brood' ability no longer incorrectly causes mothers of terror to spawn spiderlings on death. sprite: Empress of terror now has its own sprite.
  • +
  • White spider infections have been nerfed a bit. They no longer provide passive healing or increase infection progress while their host/victim is in crit. Also, the first spiderling to emerge from an infection can no longer be a green. Finally, the eggs now self-delete after the third spiderling emerges, so even in the event they aren't treated with surgery, the host isn't left with confused movement forever.
  • +
+

Markolie updated:

+
    +
  • Changing your hotkey mode now happens instantaneously and no longer lags.
  • +
  • An issue where the Hotkey Toggle button wasn't working has been fixed.
  • +
+

TDSSS updated:

+
    +
  • upload consoles now tell you if you forgot to select an ai/borg before using an upload module.
  • +
  • trick revolver comes in a box, so you can tell what it is when getting it in a surplus crate.
  • +
+

farie82 updated:

+
    +
  • Gives you the option to disable text popup spam. Aka if enabled you won't get popups after you pressed T and had a lagspike and you typed a sentence containing a lot of T's. Default is off
  • +
  • Now checks if OOC and LOOC are enabled before showing the popup
  • +
  • Adds a Mhelp ticket system
  • +
  • Take in the m/a-helps now actually takes the question
  • +
  • a/m-help followup responses using a-mhelp verb now get added to the last ticket like it should
  • +
  • Normal players can now see their open tickets using the My Admin/Mentor tickets verb
  • +
+ +

06 April 2019

+

Fox McCloud updated:

+
    +
  • Fixes people popping out of cloning taking tons of damage
  • +
  • Fixes Teslium recipe
  • +
  • Fixes some reagents not causing status updates
  • +
+

Twinmold updated:

+
    +
  • No longer costs toner to send a fax to Central Command
  • +
+

dovydas12345 updated:

+
    +
  • Fixed diamond statue names and description.
  • +
+

farie82 updated:

+
    +
  • Sec huds work again. No longer does the perp need glasses to be set to arrest. Cool does not equal arrest now
  • +
+ +

04 April 2019

+

Kyep updated:

+
    +
  • Improved the interface for Syndicate Uplinks. They now clearly mark which items are hijack-only and which are not. If you attempt to purchase a hijack-only item without hijack, they will explain why you can't.
  • +
  • Atmos Gas Grenades (the uplink grenade kit) are now split into Knockout grenades (2 N2O grenades, 8 TC, available to all agents), and Plasma Fire grenades (2 plasma fire grenades, 12 TC, only available if you have hijack). This both makes knockout grenades more useful for normal traitors, and also prevents non-hijackers using a plasma fire grenade to cause massive casualties/damage.
  • +
  • Plasma Grenades and the Syndicate Bomb can no longer show up in surplus crates, or be discounted. This means while you can buy one if you intend to, you're not randomly encouraged to bomb your target.
  • +
+ +

03 April 2019

+

Fox McCloud updated:

+
    +
  • Dramatically improves human life performance (sorry, doesn't fix your actual crappy real life)
  • +
  • Blobspores will additionally zomify all players who have 200 damage or more
  • +
  • Holoparasites will additionally die once their host has 200 damage or more
  • +
  • Fixes blob zombies who infect players who have no head being invisible
  • +
+

farie82 updated:

+
    +
  • Death nettle can be picked up again
  • +
  • Auto cloning now doesn't clone a person more than once.
  • +
  • A person in the cloning scanner won't be scanned if he's already being cloned
  • +
+ +

02 April 2019

+

Alonefromhell & AffectedArc07 updated:

+
    +
  • Fixed an edgecase compile error for spacehotel.dmm
  • +
+

Arkatos updated:

+
    +
  • Added Medical Beamgun to a Syndicate Medical Cyborg
  • +
  • Appropriate antagonist sound theme now plays when an antagonist is selected via Traitor Panel
  • +
  • Cult sound theme now plays for a new cult converts
  • +
  • Traitor/Malfunction sound theme now plays for newly autotraitored crew/AI
  • +
+

AzuleUtama updated:

+
    +
  • Cleaned up some outdated code left in uplinks.dm
  • +
+

Fox McCloud updated:

+
    +
  • Fixes some mobs not being able to hear sounds
  • +
  • Fixes the Master Controller not actually shutting down on round end
  • +
  • Adds space ants to the game; leave your food on tables or inside a container to avoid infestation!
  • +
  • Fixes bees not properly generating if they have a reagent in them
  • +
  • Can break bee boxes
  • +
  • Fixes bees breaking things they shouldn't
  • +
  • Fixes bees not properly injecting toxin if they lacked a reagent
  • +
  • purchased bee boxes are no longer wrenched down by default
  • +
  • Adds trick revolver to the syndicate uplink for the clown. Teach those pesky validhunters a lesson!
  • +
  • Adds the ability for admins to start a revolver only summon gun version; there's also a suicidal version that makes half the guns summoned real and the other half trick revolvers
  • +
  • stabilizing agent gets used up in reactions that utilize it
  • +
  • flashbangs spark when they initially go off
  • +
  • Fixes mech users being stunned by their own flashbangs
  • +
  • Fixes necromantic stone not working properly and other edge cases where you had O2 damage and could become O2 damage immune
  • +
+

KasparoVy updated:

+
    +
  • Adds Vox-fitted Tajaran veil sprites.
  • +
  • Removed stray pixel from Vox-fitted gasmask sprites.
  • +
  • Adjusts the Vox-fitted blindfold sprite.
  • +
+

Kyep updated:

+
    +
  • Blob mobs can definitely no longer be spawned in xenobio.
  • +
  • Changed playtime requirements for command jobs. HoS/RD/CE/CMO/AI now require 5h played in their department to be playable. HoP/Captain now require 5h played as a member of the command staff.
  • +
+

Markolie updated:

+
    +
  • Fixed some issues the compiler doesn't spot and some start up issues.
  • +
+

Ty-Omaha updated:

+
    +
  • Start now confirmation is now a config option
  • +
  • Grid check event sound effect
  • +
+

farie82 updated:

+
    +
  • Antidrop give edge case fixed
  • +
  • Can't give items to resting people now
  • +
  • put_in_hands now checks if you actually have hands
  • +
  • Wrapping lockers and crates now takes 1.5 seconds to do
  • +
  • Welding lockers now takes 1.5 seconds to do
  • +
+ +

01 April 2019

+

Arkatos updated:

+
    +
  • New Blob UI buttons for Storage Blob and Split consciousness abilities
  • +
  • New custom icons for Storage Blob and Split consciousness abilities
  • +
  • Added Node Requirement verb to the Blob. This verb, which is activated by default, enforces that resource and factory blob structures are built in a close proximity of the core/node in order to properly function. Players can disable it anytime in the Blob tab.
  • +
  • Remove Blob verb now has a new feature - partial refund for special Blob structures. When Blob Overmind removes special blob structure (such as a factory or node), it will receive 30% of the structure cost back as a refund.
  • +
  • Blob Overminds now show in Check Antagonists admin verb
  • +
  • Blob Mobs now use complementary colors of the Blob Overmind reagent as their own color
  • +
  • Removed Dark Matter from a list of possible Blob reagents
  • +
+

Fox McCloud updated:

+
    +
  • Fixes syndicate medborgs and regular medborgs not having handheld defibs
  • +
  • Fixes multi-tile airlocks breaking and not leaving behind an assembly
  • +
  • Updates the Timer SS
  • +
  • Roundstart ChemMasters are now constructable/deconstructable
  • +
  • Can upgrade ChemMasters. Larger beakers mean a larger reservoir
  • +
  • Mobs that are gibbed with strange reagent and GBS have a bit more of a dramatic flare to them with violent convulsions before exploding into tiny bits
  • +
+

Ty-Omaha updated:

+
    +
  • Modified alert sounds for Code Gamma and Code Epsilon.
  • +
+

dovydas12345 updated:

+
    +
  • Fixes AI's toggle floor bolts ability
  • +
+

farie82 updated:

+
    +
  • Bluespace golems no longer can crash the server
  • +
  • Spontaneous combustion now has a minimum stacksize of 1. No more getting wet from the fire virus
  • +
+ +

30 March 2019

+

Fox McCloud updated:

+
    +
  • Fixes a runtime involving decapitation
  • +
  • playing sounds performs better
  • +
+

Ty-Omaha updated:

+
    +
  • Removes SSD sleep bubbles from ghosts
  • +
+ +

29 March 2019

+

Arkatos updated:

+
    +
  • Fixes #11087 - Swarmers are now locked to their default action intent
  • +
  • Swarmers are now able to open airlocks and windoors (access restrictions still apply)
  • +
  • Added new Wizard item - Bottle of Ooze! This powerful item awakens all-consuming Morph, ready to eat everyone and everything on the station! Be careful though, as Morph diet also includes Wizards.. Costs 1 point in the spellbook.
  • +
  • Added custom icon for Bottle of Ooze
  • +
  • Morph introduction is now properly formatted
  • +
  • Added new Blob UI and icons, ported from /tg/station13
  • +
  • Added new *Blob Help* verb, designated to help out new players playing as Blob
  • +
  • Added descriptions for each Blob reagent
  • +
  • Added complementary colors for each Blob reagent
  • +
  • Blob marker now uses complementary color of Blob reagent as it's own color
  • +
  • Blob shortcuts updated. Blob shortcuts are now: Click = Expand Blob | CTRL Click = Create Shield Blob | Middle Mouse Click = Rally Spores | Alt Click = Remove Blob
  • +
+

Fox McCloud updated:

+
    +
  • Crit has been dramatically overhauled. Treating patients now requires a broader range of medicine. Recommend checking out a guide for how to treat using the new system!
  • +
  • Medical vendors now have styptic and silver sulfadiazine, saline, atropine, mannitol, mutadone, calomel, diphenhydramine, oculine, insulin, morphine, and potassium iodide for helping treat new patients. Amount of Gauze, Advanced Trauma, and Burn packs has also been increased.
  • +
  • Adds new handheld defibs. Utilize these for treating patients with cardiac arrest. Note: these do not revive people from the dead!
  • +
  • Doctors lockers now have a handheld defib in addition to a regular defib.
  • +
  • Medical borgs now have a handheld defib
  • +
  • CPR dramatically buffed. Heavily lowers O2 damage and resets losebreath to 0
  • +
  • Cryoxadone tuned down a little
  • +
  • Health analyzer UI altered ever so slightly for cardiac arerest, so it's easier to find
  • +
  • Added bacon grease reagent to traitor poison bottles; induces immediate cardiac failure
  • +
  • Upgraded Robotic Hearts now attempt to correct both cardiac failure and cardiac arrest tweak; Upgraded Robotic Hearts now do not punish you quite as severely for receiving a shock while having one (EMPs will still destroy you though)
  • +
  • Corazone recipe removed
  • +
  • hotspot sprites updated; fire will also now appear over top of things, rather than underneath it
  • +
  • Roundstart chem dispensers are now construcable/deconstrucable and can be moved
  • +
  • Energy ratio for chem dispensers increased by x10 (how many reagents you can dispense before running out and how quickly it recharges is all the same, however)
  • +
  • Adds the ability to add a single unit of reagent in the chem dispenser
  • +
  • Adds the ability to isolate reagents in the chem dispenser
  • +
  • Portable chem dispenser removed (the circuit board for them now makes full dispensers)
  • +
  • Fixes some suicides dealing damage and gibbing you at the same time
  • +
  • Allows you to suicide with more object types. Currently the only new object type you can suicide with is the gibber
  • +
+

Kyep updated:

+
    +
  • Blob mobs can no longer be spawned in xenobio.
  • +
  • Blob mobs spawned by blob cores can no longer have sentience potions used on them, which would allow whoever controls them to kill the blob with no countermeasure.
  • +
+

Mitchs98 updated:

+
    +
  • Adds in Shrimp & Fish Skewers as well as Cheeseburgers. Shrimp Skewer(Grill): 4 Shrimp(uncooked) + 1 Metal Rod, Fish Skewer(Grill): 2 Salmon Meat + Metal Rod + 10u Flour, Cheese Burger(Microwave): Burger + Cheese Wedge.
  • +
+

farie82 updated:

+
    +
  • Borgs can now only cuff people with two hands. Just like humanoids
  • +
  • You can cuff people with at least one hand now
  • +
+

ingles98 updated:

+
    +
  • Plasma Golems will now report their suicide acts to the Admins.
  • +
+

25 March 2019

Fox McCloud updated:

    @@ -63,6 +336,16 @@
  • Fixes chem smoke lagging under some circumstances
  • Fixes smoke not wanting to garbage collect
  • Fixes flares not returning a qdel hint
  • +
  • Fixes hotspots being slow to ignite turfs around them
  • +
  • Fixes LINDA not conducting temperature through things.
  • +
+

Mitchs98 updated:

+
    +
  • Chitinous Mass is no longer weaponized lag if examined.
  • +
+

farie82 updated:

+
    +
  • Diona nymphs are grabbable and punchable again

24 March 2019

diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 958cb315944..d145f082f7c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -9497,3 +9497,296 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Fixes chem smoke lagging under some circumstances - bugfix: Fixes smoke not wanting to garbage collect - bugfix: Fixes flares not returning a qdel hint + - bugfix: Fixes hotspots being slow to ignite turfs around them + - bugfix: Fixes LINDA not conducting temperature through things. + Mitchs98: + - bugfix: Chitinous Mass is no longer weaponized lag if examined. + farie82: + - bugfix: Diona nymphs are grabbable and punchable again +2019-03-29: + Arkatos: + - bugfix: 'Fixes #11087 - Swarmers are now locked to their default action intent' + - tweak: Swarmers are now able to open airlocks and windoors (access restrictions + still apply) + - rscadd: Added new Wizard item - Bottle of Ooze! This powerful item awakens all-consuming + Morph, ready to eat everyone and everything on the station! Be careful though, + as Morph diet also includes Wizards.. Costs 1 point in the spellbook. + - imageadd: Added custom icon for Bottle of Ooze + - tweak: Morph introduction is now properly formatted + - rscadd: Added new Blob UI and icons, ported from /tg/station13 + - rscadd: Added new *Blob Help* verb, designated to help out new players playing + as Blob + - rscadd: Added descriptions for each Blob reagent + - rscadd: Added complementary colors for each Blob reagent + - tweak: Blob marker now uses complementary color of Blob reagent as it's own color + - tweak: 'Blob shortcuts updated. Blob shortcuts are now: Click = Expand Blob | + CTRL Click = Create Shield Blob | Middle Mouse Click = Rally Spores | Alt Click + = Remove Blob' + Fox McCloud: + - rscadd: Crit has been dramatically overhauled. Treating patients now requires + a broader range of medicine. Recommend checking out a guide for how to treat + using the new system! + - rscadd: Medical vendors now have styptic and silver sulfadiazine, saline, atropine, + mannitol, mutadone, calomel, diphenhydramine, oculine, insulin, morphine, and + potassium iodide for helping treat new patients. Amount of Gauze, Advanced Trauma, + and Burn packs has also been increased. + - rscadd: 'Adds new handheld defibs. Utilize these for treating patients with cardiac + arrest. Note: these do not revive people from the dead!' + - rscadd: Doctors lockers now have a handheld defib in addition to a regular defib. + - rscadd: Medical borgs now have a handheld defib + - tweak: CPR dramatically buffed. Heavily lowers O2 damage and resets losebreath + to 0 + - tweak: Cryoxadone tuned down a little + - tweak: Health analyzer UI altered ever so slightly for cardiac arerest, so it's + easier to find + - rscadd: Added bacon grease reagent to traitor poison bottles; induces immediate + cardiac failure + - tweak: Upgraded Robotic Hearts now attempt to correct both cardiac failure and + cardiac arrest tweak; Upgraded Robotic Hearts now do not punish you quite as + severely for receiving a shock while having one (EMPs will still destroy you + though) + - rscdel: Corazone recipe removed + - tweak: hotspot sprites updated; fire will also now appear over top of things, + rather than underneath it + - rscadd: Roundstart chem dispensers are now construcable/deconstrucable and can + be moved + - tweak: Energy ratio for chem dispensers increased by x10 (how many reagents you + can dispense before running out and how quickly it recharges is all the same, + however) + - rscadd: Adds the ability to add a single unit of reagent in the chem dispenser + - rscadd: Adds the ability to isolate reagents in the chem dispenser + - rscdel: Portable chem dispenser removed (the circuit board for them now makes + full dispensers) + - bugfix: Fixes some suicides dealing damage and gibbing you at the same time + - rscadd: Allows you to suicide with more object types. Currently the only new object + type you can suicide with is the gibber + Kyep: + - tweak: Blob mobs can no longer be spawned in xenobio. + - tweak: Blob mobs spawned by blob cores can no longer have sentience potions used + on them, which would allow whoever controls them to kill the blob with no countermeasure. + Mitchs98: + - rscadd: 'Adds in Shrimp & Fish Skewers as well as Cheeseburgers. Shrimp Skewer(Grill): + 4 Shrimp(uncooked) + 1 Metal Rod, Fish Skewer(Grill): 2 Salmon Meat + Metal + Rod + 10u Flour, Cheese Burger(Microwave): Burger + Cheese Wedge.' + farie82: + - bugfix: Borgs can now only cuff people with two hands. Just like humanoids + - tweak: You can cuff people with at least one hand now + ingles98: + - bugfix: Plasma Golems will now report their suicide acts to the Admins. +2019-03-30: + Fox McCloud: + - bugfix: Fixes a runtime involving decapitation + - tweak: playing sounds performs better + Ty-Omaha: + - tweak: Removes SSD sleep bubbles from ghosts +2019-04-01: + Arkatos: + - rscadd: New Blob UI buttons for Storage Blob and Split consciousness abilities + - imageadd: New custom icons for Storage Blob and Split consciousness abilities + - rscadd: Added Node Requirement verb to the Blob. This verb, which is activated + by default, enforces that resource and factory blob structures are built in + a close proximity of the core/node in order to properly function. Players can + disable it anytime in the Blob tab. + - rscadd: Remove Blob verb now has a new feature - partial refund for special Blob + structures. When Blob Overmind removes special blob structure (such as a factory + or node), it will receive 30% of the structure cost back as a refund. + - tweak: Blob Overminds now show in Check Antagonists admin verb + - tweak: Blob Mobs now use complementary colors of the Blob Overmind reagent as + their own color + - rscdel: Removed Dark Matter from a list of possible Blob reagents + Fox McCloud: + - bugfix: Fixes syndicate medborgs and regular medborgs not having handheld defibs + - bugfix: Fixes multi-tile airlocks breaking and not leaving behind an assembly + - tweak: Updates the Timer SS + - rscadd: Roundstart ChemMasters are now constructable/deconstructable + - tweak: Can upgrade ChemMasters. Larger beakers mean a larger reservoir + - rscadd: Mobs that are gibbed with strange reagent and GBS have a bit more of a + dramatic flare to them with violent convulsions before exploding into tiny bits + Ty-Omaha: + - tweak: Modified alert sounds for Code Gamma and Code Epsilon. + dovydas12345: + - bugfix: Fixes AI's toggle floor bolts ability + farie82: + - bugfix: Bluespace golems no longer can crash the server + - tweak: Spontaneous combustion now has a minimum stacksize of 1. No more getting + wet from the fire virus +2019-04-02: + Alonefromhell & AffectedArc07: + - bugfix: Fixed an edgecase compile error for spacehotel.dmm + Arkatos: + - rscadd: Added Medical Beamgun to a Syndicate Medical Cyborg + - tweak: Appropriate antagonist sound theme now plays when an antagonist is selected + via Traitor Panel + - tweak: Cult sound theme now plays for a new cult converts + - tweak: Traitor/Malfunction sound theme now plays for newly autotraitored crew/AI + AzuleUtama: + - tweak: Cleaned up some outdated code left in uplinks.dm + Fox McCloud: + - bugfix: Fixes some mobs not being able to hear sounds + - bugfix: Fixes the Master Controller not actually shutting down on round end + - rscadd: Adds space ants to the game; leave your food on tables or inside a container + to avoid infestation! + - bugfix: Fixes bees not properly generating if they have a reagent in them + - rscadd: Can break bee boxes + - bugfix: Fixes bees breaking things they shouldn't + - bugfix: Fixes bees not properly injecting toxin if they lacked a reagent + - tweak: purchased bee boxes are no longer wrenched down by default + - rscadd: Adds trick revolver to the syndicate uplink for the clown. Teach those + pesky validhunters a lesson! + - rscadd: Adds the ability for admins to start a revolver only summon gun version; + there's also a suicidal version that makes half the guns summoned real and the + other half trick revolvers + - tweak: stabilizing agent gets used up in reactions that utilize it + - tweak: flashbangs spark when they initially go off + - bugfix: Fixes mech users being stunned by their own flashbangs + - bugfix: Fixes necromantic stone not working properly and other edge cases where + you had O2 damage and could become O2 damage immune + KasparoVy: + - rscadd: Adds Vox-fitted Tajaran veil sprites. + - rscdel: Removed stray pixel from Vox-fitted gasmask sprites. + - tweak: Adjusts the Vox-fitted blindfold sprite. + Kyep: + - bugfix: Blob mobs can definitely no longer be spawned in xenobio. + - tweak: Changed playtime requirements for command jobs. HoS/RD/CE/CMO/AI now require + 5h played in their department to be playable. HoP/Captain now require 5h played + as a member of the command staff. + Markolie: + - bugfix: Fixed some issues the compiler doesn't spot and some start up issues. + Ty-Omaha: + - tweak: Start now confirmation is now a config option + - rscadd: Grid check event sound effect + farie82: + - bugfix: Antidrop give edge case fixed + - bugfix: Can't give items to resting people now + - bugfix: put_in_hands now checks if you actually have hands + - tweak: Wrapping lockers and crates now takes 1.5 seconds to do + - tweak: Welding lockers now takes 1.5 seconds to do +2019-04-03: + Fox McCloud: + - bugfix: Dramatically improves human life performance (sorry, doesn't fix your + actual crappy real life) + - tweak: Blobspores will additionally zomify all players who have 200 damage or + more + - tweak: Holoparasites will additionally die once their host has 200 damage or more + - bugfix: Fixes blob zombies who infect players who have no head being invisible + farie82: + - bugfix: Death nettle can be picked up again + - bugfix: Auto cloning now doesn't clone a person more than once. + - tweak: A person in the cloning scanner won't be scanned if he's already being + cloned +2019-04-04: + Kyep: + - tweak: Improved the interface for Syndicate Uplinks. They now clearly mark which + items are hijack-only and which are not. If you attempt to purchase a hijack-only + item without hijack, they will explain why you can't. + - tweak: Atmos Gas Grenades (the uplink grenade kit) are now split into Knockout + grenades (2 N2O grenades, 8 TC, available to all agents), and Plasma Fire grenades + (2 plasma fire grenades, 12 TC, only available if you have hijack). This both + makes knockout grenades more useful for normal traitors, and also prevents non-hijackers + using a plasma fire grenade to cause massive casualties/damage. + - tweak: Plasma Grenades and the Syndicate Bomb can no longer show up in surplus + crates, or be discounted. This means while you can buy one if you intend to, + you're not randomly encouraged to bomb your target. +2019-04-06: + Fox McCloud: + - bugfix: Fixes people popping out of cloning taking tons of damage + - bugfix: Fixes Teslium recipe + - bugfix: Fixes some reagents not causing status updates + Twinmold: + - bugfix: No longer costs toner to send a fax to Central Command + dovydas12345: + - spellcheck: Fixed diamond statue names and description. + farie82: + - bugfix: Sec huds work again. No longer does the perp need glasses to be set to + arrest. Cool does not equal arrest now +2019-04-07: + Arkatos: + - tweak: Guardians can no longer change action intents on their own + - bugfix: 'Fixes #10900 - Guardians can no longer attack their host while inside + them' + - rscadd: Explosive and Support Guardians now get precise cooldown shown (instead + of just static estimate) before their bomb and beacon abitilites are ready to + be used again, respectively + - tweak: HARM action intent icon for Guardians updated + - tweak: Dehydrated Space Carp TC cost changed from 3 to 2 + - tweak: Shadowling Glare ability reworked - The further Shadowling is from their + glared target, the shorter stun their target gets. Stuns also have a delay before + they kick in, based on the distance, however targets will be slowed and muted + before stun takes effect. Targets on the tile just next to them are still stunned + and muted for 10 seconds without any delay. + - rscadd: Added victory message to the End Round messages in the Shadowlings Rounds + - tweak: Shadowling Destroy Engines ability reworked. You now need to sacrifice + non-ally target to delay the emergency shuttle arrival by 10 minutes, and shuttle + will be unable to be recalled. This ability can be used only once across ALL + Shadowlings. + - tweak: Descriptions now show with a mouse hover over action buttons + Fox McCloud: + - bugfix: Fixes Russian revolvers triggering no matter where you clicked + - rscadd: Power gloves electric shocks can target anything now (still only damages + mobs) + - rscadd: Power gloves electric arcs will bounce around (if it happens to target + a mob though, it'll ground out and not bounce any more) + - tweak: Power gloves cooldown lowered from 12 to 4 + - tweak: Power gloves heat up the turf they target + - tweak: Using power gloves on disarm intent will weaken your target instead of + dealing damage + - tweak: CLF3, Phlogiston, and Fluorosulfuric acid all require greater volumes to + achieve their upper damage limits + - tweak: CLF3 and Phlogiston have lower minimum damage + - bugfix: Grey's treat water more closely to sulfuric acid (including passive damage + while it's in them) + - tweak: Grey's don't instantly purge all sulfuric acid from their system; it depletes + at the normal rate, but doens't cause damage + - tweak: Foam altered to be a bit more viable compared to smoke + - bugfix: Fixes being unable to view pill bottle inventory in some circumstances + - tweak: Vending items from vending machines will try to put the item in your hands + after vending + - tweak: Vending machines with refill-canisters can be beaten apart and broken + Kyep: + - rscadd: Ghosting while alive, conscious, and a member of the crew will now result + in your body being moved to cryo after 5 minutes, assuming your body isn't killed + or restrained in any way in the meantime. + - rscadd: An AI that ghosts while alive gets a dismissable hint that they might + consider using OOC -> Wipe Core instead. + - rscadd: Ghosting out of your body while you are alive, and an antag, will result + in admins being informed, so that they may replace you as an antag if needed. + - bugfix: Empress of terror (admin-only mob) is no longer incorrectly prevented + from laying brown spider eggs. + - tweak: Admins are now able to spawn a queen of terror in a room without a vent. + Previously, queens would not allow this. Now, this just results in an alert + to admins (since its probably a mistake) and deactivates the mob AI (but leaves + it available for player control). + - rscadd: If there are player controlled terror spiders, admins using check antags + panel will now be able to see eggs/spiderlings currently growing on the station. + These counters only count eggs/spiderlings on station, and ignore fake spiderlings. + - bugfix: 'Empress of terror''s ''erase brood'' ability no longer incorrectly causes + mothers of terror to spawn spiderlings on death. sprite: Empress of terror now + has its own sprite.' + - tweak: White spider infections have been nerfed a bit. They no longer provide + passive healing or increase infection progress while their host/victim is in + crit. Also, the first spiderling to emerge from an infection can no longer be + a green. Finally, the eggs now self-delete after the third spiderling emerges, + so even in the event they aren't treated with surgery, the host isn't left with + confused movement forever. + Markolie: + - bugfix: Changing your hotkey mode now happens instantaneously and no longer lags. + - bugfix: An issue where the Hotkey Toggle button wasn't working has been fixed. + TDSSS: + - tweak: upload consoles now tell you if you forgot to select an ai/borg before + using an upload module. + - tweak: trick revolver comes in a box, so you can tell what it is when getting + it in a surplus crate. + farie82: + - rscadd: Gives you the option to disable text popup spam. Aka if enabled you won't + get popups after you pressed T and had a lagspike and you typed a sentence containing + a lot of T's. Default is off + - tweak: Now checks if OOC and LOOC are enabled before showing the popup + - rscadd: Adds a Mhelp ticket system + - tweak: Take in the m/a-helps now actually takes the question + - bugfix: a/m-help followup responses using a-mhelp verb now get added to the last + ticket like it should + - bugfix: Normal players can now see their open tickets using the My Admin/Mentor + tickets verb +2019-04-08: + TDSSS: + - bugfix: Added missing vent in toxins mixing diff --git a/html/changelogs/AutoChangeLog-pr-10327.yml b/html/changelogs/AutoChangeLog-pr-10327.yml new file mode 100644 index 00000000000..7b73cbcbd97 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10327.yml @@ -0,0 +1,9 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "CQC has been updated; a few combos are more powerful" + - tweak: "cost increased to 13 TC" + - tweak: "CQC is now nuke ops only" + - tweak: "gloves of the north star restriction on CQC removed" + - tweak: "CQC disarms will now take the item from your opponent" + - tweak: "CQC blocks melee weapons and a couple of stun weapons and not everything now" diff --git a/html/changelogs/AutoChangeLog-pr-11102.yml b/html/changelogs/AutoChangeLog-pr-11102.yml new file mode 100644 index 00000000000..7e54f5268ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11102.yml @@ -0,0 +1,5 @@ +author: "AffectedArc07" +delete-after: True +changes: + - rscadd: "ssMapping" + - tweak: "Gateway and space ruins are now loaded with ssMapping" diff --git a/html/changelogs/AutoChangeLog-pr-11214.yml b/html/changelogs/AutoChangeLog-pr-11214.yml new file mode 100644 index 00000000000..fcad43b3086 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11214.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - tweak: "Shadowlings now have a slightly bigger colored text when speaking in the Shadowling Hivemind" diff --git a/html/changelogs/AutoChangeLog-pr-11217.yml b/html/changelogs/AutoChangeLog-pr-11217.yml new file mode 100644 index 00000000000..9c6b9803c94 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11217.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Reagents will now adjust to the body temperature over time as opposed to all at once" diff --git a/html/changelogs/AutoChangeLog-pr-11224.yml b/html/changelogs/AutoChangeLog-pr-11224.yml new file mode 100644 index 00000000000..0357a4aa727 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11224.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - soundadd: "Replaced title2.ogg music with a higher quality version" diff --git a/html/changelogs/AutoChangeLog-pr-11227.yml b/html/changelogs/AutoChangeLog-pr-11227.yml new file mode 100644 index 00000000000..cc4293ba715 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11227.yml @@ -0,0 +1,7 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Strange Reagent will work 25% of the time with TOUCH based reactions" + - tweak: "Strange reagent will revive whether there's a ghost or not (can use SR on clientless mobs now, like monkies)" + - tweak: "SR puts the occupant back in their body automatically" + - tweak: "Cloners that eject their messes will now eject the unattached organs" diff --git a/html/changelogs/AutoChangeLog-pr-11230.yml b/html/changelogs/AutoChangeLog-pr-11230.yml new file mode 100644 index 00000000000..36c1f051aca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11230.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "the message for brain death will now properly and only occur when they have truly died from brain damage" + - bugfix: "Fixes being able to attain brain damage over 120" diff --git a/html/changelogs/AutoChangeLog-pr-11231.yml b/html/changelogs/AutoChangeLog-pr-11231.yml new file mode 100644 index 00000000000..82560671a26 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11231.yml @@ -0,0 +1,6 @@ +author: "Arkatos and Paradise community:" +delete-after: True +changes: + - rscadd: "Added Tip of the round to a pre-game lobby" + - rscadd: "Added Show Custom Tip admin verb" + - rscadd: "Added Give Random Tip OOC verb" diff --git a/html/changelogs/AutoChangeLog-pr-11243.yml b/html/changelogs/AutoChangeLog-pr-11243.yml new file mode 100644 index 00000000000..c0843a66d43 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11243.yml @@ -0,0 +1,4 @@ +author: "CornMyCob" +delete-after: True +changes: + - tweak: "The plasma cutter now cuts through multiple rock tiles." diff --git a/html/changelogs/AutoChangeLog-pr-11253.yml b/html/changelogs/AutoChangeLog-pr-11253.yml new file mode 100644 index 00000000000..0cfbb99257a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11253.yml @@ -0,0 +1,5 @@ +author: "Citinited" +delete-after: True +changes: + - bugfix: "You can no longer turn transit turfs into foamed metal flooring." + - bugfix: "Foamed metal floors have a sprite now." diff --git a/html/changelogs/AutoChangeLog-pr-11255.yml b/html/changelogs/AutoChangeLog-pr-11255.yml new file mode 100644 index 00000000000..7320fee3d2a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11255.yml @@ -0,0 +1,6 @@ +author: "Markolie" +delete-after: True +changes: + - rscadd: "Safes can now consist of more than two tumblers." + - tweak: "All safes now have three tumblers by default, instead of two." + - tweak: "The safe opening mechanism has changed slightly. This is described on the safe cracking UI." diff --git a/html/changelogs/AutoChangeLog-pr-11257.yml b/html/changelogs/AutoChangeLog-pr-11257.yml new file mode 100644 index 00000000000..a675de535f9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11257.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscdel: "Updates nations. Updates nations so hard right into the void" diff --git a/html/changelogs/AutoChangeLog-pr-11259.yml b/html/changelogs/AutoChangeLog-pr-11259.yml new file mode 100644 index 00000000000..2b6bdf7e540 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11259.yml @@ -0,0 +1,13 @@ +author: "Markolie" +delete-after: True +changes: + - rscadd: "The hardsuit equipment lockers on the Syndicate Nuclear Operative shuttle have been replaced with suit storage units. Suit storage units now have a separate slot for magboots." + - rscadd: "Nuclear Operatives can now purchase reinforcements. These reinforcements cost 25 telecrystals each." + - rscadd: "A number of new ammunition and weapon bundles have been added for Nuclear Operatives." + - tweak: "For every ten players on the server, the Nuclear Operatives now receive 2 extra telecrystals." + - tweak: "The Syndicate borg spawners have been separated into three separate spawners, one for each type of Syndicate cyborg. Their prices have been modified." + - tweak: "Saboteur borgs now spawn with thermals." + - tweak: "The Syndicate borg and exosuits have been moved to a new category, \"Support and Mechanized Exosuits\"." + - tweak: "Existing bundles and telecrystal purchases have been moved to a new category, \"Bundles and Telecrystals\"." + - tweak: "There are now more spawn points for nuclear operatives on their base. The number of operatives spawning has not been changed." + - bugfix: "Spawning nuclear operatives through the traitor panel now causes their ID to be properly updated." diff --git a/html/changelogs/AutoChangeLog-pr-11270.yml b/html/changelogs/AutoChangeLog-pr-11270.yml new file mode 100644 index 00000000000..6ecdf8039c0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11270.yml @@ -0,0 +1,4 @@ +author: "TDSSS" +delete-after: True +changes: + - tweak: "nukies can buy plasma grenades again" diff --git a/html/changelogs/AutoChangeLog-pr-11277.yml b/html/changelogs/AutoChangeLog-pr-11277.yml new file mode 100644 index 00000000000..c966a9c74cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11277.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - tweak: "Shield Blobs automatically spawned around Blob Cores now give no refund upon removing. No freebies." diff --git a/html/changelogs/AutoChangeLog-pr-11279.yml b/html/changelogs/AutoChangeLog-pr-11279.yml new file mode 100644 index 00000000000..11bdfb80538 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11279.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - tweak: "Ghosts now orbit around their followed targets" diff --git a/html/changelogs/AutoChangeLog-pr-11280.yml b/html/changelogs/AutoChangeLog-pr-11280.yml new file mode 100644 index 00000000000..5228e09b3c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11280.yml @@ -0,0 +1,4 @@ +author: "Ionward" +delete-after: True +changes: + - rscadd: "Added new mantles! Check the ClothesMate, or in department head's lockers." diff --git a/html/changelogs/AutoChangeLog-pr-11282.yml b/html/changelogs/AutoChangeLog-pr-11282.yml new file mode 100644 index 00000000000..5b8e5704c06 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11282.yml @@ -0,0 +1,5 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Plasma fires should burn a bit faster now" + - tweak: "Bleeding will now stop at the temperature at which cryoxadone heals" diff --git a/html/changelogs/AutoChangeLog-pr-11285.yml b/html/changelogs/AutoChangeLog-pr-11285.yml new file mode 100644 index 00000000000..3c725a05b90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11285.yml @@ -0,0 +1,8 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "Tesla can't zap cameras and other disposal structures anymore" + - rscadd: "Simple mobs can now be shocked" + - tweak: "Electrocution damage scales a bit more linearly up to its maximum potential instead of being heavily random" + - bugfix: "Fixes being able to shock yourself with TK, at range, on electrical equipment" + - rscadd: "simple mobs can now be shocked by the tesla and other sources" diff --git a/html/changelogs/AutoChangeLog-pr-11287.yml b/html/changelogs/AutoChangeLog-pr-11287.yml new file mode 100644 index 00000000000..111f8aac824 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11287.yml @@ -0,0 +1,6 @@ +author: "Fox McCloud" +delete-after: True +changes: + - bugfix: "Fixes goats not attacking people" + - tweak: "Goats will eat glowshrooms" + - rscadd: "Goats will eat full grown diona" diff --git a/html/changelogs/AutoChangeLog-pr-11288.yml b/html/changelogs/AutoChangeLog-pr-11288.yml new file mode 100644 index 00000000000..2a309dde374 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11288.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscadd: "Remapped toxins to be more compatible with the modern age" diff --git a/html/changelogs/AutoChangeLog-pr-11294.yml b/html/changelogs/AutoChangeLog-pr-11294.yml new file mode 100644 index 00000000000..0088263303b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11294.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "Ticket messages now have their corresponding span classes. Making them easier to notice" diff --git a/html/changelogs/AutoChangeLog-pr-11296.yml b/html/changelogs/AutoChangeLog-pr-11296.yml new file mode 100644 index 00000000000..42a9ce1a063 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11296.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "PM's now shouldn't go to the wrong client anymore when the target left." diff --git a/html/changelogs/AutoChangeLog-pr-11297.yml b/html/changelogs/AutoChangeLog-pr-11297.yml new file mode 100644 index 00000000000..9973022ecea --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11297.yml @@ -0,0 +1,9 @@ +author: "Fox McCloud" +delete-after: True +changes: + - tweak: "updates plasma and N2O sprites" + - bugfix: "Fixes not being able to look at a turf if it had plasma/N2O on it" + - rscdel: "cold turfs no longer become icy" + - rscadd: "Cryostylane makes turfs icy" + - rscadd: "Icy turfs are slippery; wear magboots to counteract the effect. Watch your head!" + - bugfix: "Fixes grammar of slipping on turfs; no more \"you slipped on floor\" or \"you slipped on wet floor\"" diff --git a/html/changelogs/AutoChangeLog-pr-11298.yml b/html/changelogs/AutoChangeLog-pr-11298.yml new file mode 100644 index 00000000000..0523ab305e7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11298.yml @@ -0,0 +1,5 @@ +author: "Kyep" +delete-after: True +changes: + - bugfix: "bans issued by admins via the Player Panel no longer incorrectly omit IP/etc information" + - tweak: "admins issuing permanent bans are no longer presented with an \"ip ban?\" prompt, as all bans include IP/CID information now. This prompt was a legacy thing from back when the filesystem was used to store bans, and hasn't ever affected how DB-based bans were stored." diff --git a/html/changelogs/AutoChangeLog-pr-11301.yml b/html/changelogs/AutoChangeLog-pr-11301.yml new file mode 100644 index 00000000000..2b1bc1f82cd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11301.yml @@ -0,0 +1,7 @@ +author: "KasparoVy" +delete-after: True +changes: + - rscadd: "Adds striped normal-height socks." + - rscadd: "Vox can now wear whatever undergarment they want." + - tweak: "Removes flesh from shredded Vox uniform sprites." + - rscdel: "Armalis can no longer wear undergarments. They didn't fit, anyhow." diff --git a/html/changelogs/AutoChangeLog-pr-11305.yml b/html/changelogs/AutoChangeLog-pr-11305.yml new file mode 100644 index 00000000000..6ca9bfb33bd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11305.yml @@ -0,0 +1,4 @@ +author: "Fox McCloud" +delete-after: True +changes: + - rscdel: "removes ponies" diff --git a/html/changelogs/AutoChangeLog-pr-11310.yml b/html/changelogs/AutoChangeLog-pr-11310.yml new file mode 100644 index 00000000000..3ec3c388190 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11310.yml @@ -0,0 +1,4 @@ +author: "KasparoVy" +delete-after: True +changes: + - bugfix: "Underwear no can no longer lock up the character creator." diff --git a/html/changelogs/AutoChangeLog-pr-11313.yml b/html/changelogs/AutoChangeLog-pr-11313.yml new file mode 100644 index 00000000000..d86b5ff7d0a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11313.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "Ducttape gags can now be removed properly without spawning an invisible one in your hands" diff --git a/html/changelogs/AutoChangeLog-pr-11314.yml b/html/changelogs/AutoChangeLog-pr-11314.yml new file mode 100644 index 00000000000..0d38b022e23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11314.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "Windoors now give the airlock assembly electronics once deconstructed" diff --git a/html/changelogs/AutoChangeLog-pr-11317.yml b/html/changelogs/AutoChangeLog-pr-11317.yml new file mode 100644 index 00000000000..96503bf1d88 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11317.yml @@ -0,0 +1,4 @@ +author: "farie82" +delete-after: True +changes: + - bugfix: "Can't place runes in space anymore" diff --git a/html/changelogs/AutoChangeLog-pr-11318.yml b/html/changelogs/AutoChangeLog-pr-11318.yml new file mode 100644 index 00000000000..a9e5c225096 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11318.yml @@ -0,0 +1,4 @@ +author: "AffectedArc07" +delete-after: True +changes: + - rscdel: "Master Controller" diff --git a/html/changelogs/AutoChangeLog-pr-11320.yml b/html/changelogs/AutoChangeLog-pr-11320.yml new file mode 100644 index 00000000000..6bafcda7d63 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11320.yml @@ -0,0 +1,4 @@ +author: "Markolie" +delete-after: True +changes: + - bugfix: "Shuttles no longer leave behind their propulsion." diff --git a/html/changelogs/AutoChangeLog-pr-11331.yml b/html/changelogs/AutoChangeLog-pr-11331.yml new file mode 100644 index 00000000000..bd501e2f162 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11331.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - rscadd: "Added cancel button to Wizard teleportation scrolls" diff --git a/html/changelogs/AutoChangeLog-pr-11333.yml b/html/changelogs/AutoChangeLog-pr-11333.yml new file mode 100644 index 00000000000..71935d55d86 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11333.yml @@ -0,0 +1,4 @@ +author: "Arkatos" +delete-after: True +changes: + - bugfix: "Toggling hardhat light on/off now correctly updates wearer's sprite" diff --git a/html/changelogs/AutoChangeLog-pr-11336.yml b/html/changelogs/AutoChangeLog-pr-11336.yml new file mode 100644 index 00000000000..bf2626580e3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11336.yml @@ -0,0 +1,4 @@ +author: "CthulhuOnIce" +delete-after: True +changes: + - bugfix: "you can smell dead bodies, even if someone else shouldn't" diff --git a/html/changelogs/AutoChangeLog-pr-11339.yml b/html/changelogs/AutoChangeLog-pr-11339.yml new file mode 100644 index 00000000000..a5b0f74908e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11339.yml @@ -0,0 +1,4 @@ +author: "Markolie" +delete-after: True +changes: + - bugfix: "AZERTY hotkey mode users can now switch between regular mode and hotkey mode properly using TAB again." diff --git a/html/changelogs/AutoChangeLog-pr-11350.yml b/html/changelogs/AutoChangeLog-pr-11350.yml new file mode 100644 index 00000000000..54d750a6e7e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11350.yml @@ -0,0 +1,5 @@ +author: "AffectedArc07" +delete-after: True +changes: + - rscadd: "SSvotes" + - rscadd: "SSradio" diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 97256ff448a..9a8d69a66bd 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/tile_effects.dmi b/icons/effects/tile_effects.dmi index 0475e83515c..251e539cc84 100644 Binary files a/icons/effects/tile_effects.dmi and b/icons/effects/tile_effects.dmi differ diff --git a/icons/goonstation/effects/effects.dmi b/icons/goonstation/effects/effects.dmi new file mode 100644 index 00000000000..8f38e42718e Binary files /dev/null and b/icons/goonstation/effects/effects.dmi differ diff --git a/icons/goonstation/effects/fire.dmi b/icons/goonstation/effects/fire.dmi index 48a1f9b90e6..03d0de0e38d 100644 Binary files a/icons/goonstation/effects/fire.dmi and b/icons/goonstation/effects/fire.dmi differ diff --git a/icons/goonstation/mob/inhands/items_lefthand.dmi b/icons/goonstation/mob/inhands/items_lefthand.dmi index 042c15f279b..cb8d5d66284 100644 Binary files a/icons/goonstation/mob/inhands/items_lefthand.dmi and b/icons/goonstation/mob/inhands/items_lefthand.dmi differ diff --git a/icons/goonstation/mob/inhands/items_righthand.dmi b/icons/goonstation/mob/inhands/items_righthand.dmi index 051f205bac7..1698af9855e 100644 Binary files a/icons/goonstation/mob/inhands/items_righthand.dmi and b/icons/goonstation/mob/inhands/items_righthand.dmi differ diff --git a/icons/goonstation/objects/objects.dmi b/icons/goonstation/objects/objects.dmi index 8dadb400668..99ddeac3d10 100644 Binary files a/icons/goonstation/objects/objects.dmi and b/icons/goonstation/objects/objects.dmi differ diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi index 56c39b9a75d..4797c79496e 100644 Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ diff --git a/icons/mob/guardian.dmi b/icons/mob/guardian.dmi index 2fa0a172bb9..a10e1e0b0ec 100644 Binary files a/icons/mob/guardian.dmi and b/icons/mob/guardian.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index f8f6ea63db1..b7f6b5c8f6a 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/clothing_lefthand.dmi b/icons/mob/inhands/clothing_lefthand.dmi index d04a64e1acc..6f2cf056cec 100644 Binary files a/icons/mob/inhands/clothing_lefthand.dmi and b/icons/mob/inhands/clothing_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing_righthand.dmi b/icons/mob/inhands/clothing_righthand.dmi index 7dac254e78d..169e9e6cbf3 100644 Binary files a/icons/mob/inhands/clothing_righthand.dmi and b/icons/mob/inhands/clothing_righthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 3efddb08c4b..fe096499427 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/pony.dmi b/icons/mob/pony.dmi deleted file mode 100644 index e269333f892..00000000000 Binary files a/icons/mob/pony.dmi and /dev/null differ diff --git a/icons/mob/species/vox/eyes.dmi b/icons/mob/species/vox/eyes.dmi index 99ee47ac1fa..3d9a6c77bf8 100644 Binary files a/icons/mob/species/vox/eyes.dmi and b/icons/mob/species/vox/eyes.dmi differ diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi index 7022c296574..971978ccff4 100644 Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ diff --git a/icons/mob/species/vox/underwear.dmi b/icons/mob/species/vox/underwear.dmi new file mode 100644 index 00000000000..5b29d437cef Binary files /dev/null and b/icons/mob/species/vox/underwear.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index fdbea753a29..44626a67680 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/terrorspider64.dmi b/icons/mob/terrorspider64.dmi new file mode 100644 index 00000000000..392ad43b3a7 Binary files /dev/null and b/icons/mob/terrorspider64.dmi differ diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index c212261f9ec..ab1879132de 100644 Binary files a/icons/mob/underwear.dmi and b/icons/mob/underwear.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 61390f38057..9c9f6d38e94 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 3004a130246..418f221c78f 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 7a728d811c3..4308626cdca 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/flag.dmi b/icons/obj/flag.dmi index 309b1d38d87..10faf8b850d 100644 Binary files a/icons/obj/flag.dmi and b/icons/obj/flag.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 108e5603b25..07c8be38ed9 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/icons/turf/floors/plating.dmi b/icons/turf/floors/plating.dmi index fee52346e3c..c765195aff6 100644 Binary files a/icons/turf/floors/plating.dmi and b/icons/turf/floors/plating.dmi differ diff --git a/interface/interface.dm b/interface/interface.dm index 88bdb34e6b8..0bec55ef51c 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -52,7 +52,6 @@ src << link(config.forumurl) else to_chat(src, "The forum URL is not set in the server configuration.") - return /client/verb/rules() set name = "Rules" @@ -64,7 +63,6 @@ src << link(config.rulesurl) else to_chat(src, "The rules URL is not set in the server configuration.") - return /client/verb/github() set name = "GitHub" @@ -76,7 +74,6 @@ src << link(config.githuburl) else to_chat(src, "The GitHub URL is not set in the server configuration.") - return /client/verb/discord() set name = "Discord" @@ -88,7 +85,6 @@ src << link(config.discordurl) else to_chat(src, "The Discord URL is not set in the server configuration.") - return /client/verb/donate() set name = "Donate" @@ -100,8 +96,28 @@ src << link(config.donationsurl) else to_chat(src, "The rules URL is not set in the server configuration.") - return +/client/verb/hotkey_mode() + set name = "Set Hotkey Mode" + set category = "Preferences" + + var/list/hotkey_modes = list() + for(var/hotkey_mode in subtypesof(/datum/hotkey_mode)) + var/datum/hotkey_mode/H = hotkey_mode + hotkey_modes[initial(H.name)] = H + + var/chosen_mode_name = input("Choose your preferred hotkey mode.", "Hotkey mode selection") as null|anything in hotkey_modes + if(!chosen_mode_name) + return + + var/datum/hotkey_mode/chosen_mode = hotkey_modes[chosen_mode_name] + var/datum/hotkey_mode/hotkey_mode = new chosen_mode(src) + + hotkey_mode.set_winset_values() + to_chat(usr, "Your hotkey mode has been changed to [hotkey_mode.name].") + + qdel(hotkey_mode) + /client/verb/hotkeys_help() set name = "Hotkey Help" set category = "OOC" @@ -234,32 +250,3 @@ Any-Mode: (hotkey doesn't need to be on) to_chat(src, hotkey_mode) to_chat(src, other) - -//adv. hotkey mode verbs, vars located in /code/modules/client/client defines.dm -/client/verb/hotkey_toggle()//toggles hotkey mode between on and off, respects selected type - set name = ".Toggle Hotkey Mode" - - hotkeyon = !hotkeyon//toggle the var - to_chat(usr, (hotkeyon ? "Hotkey mode enabled." : "Hotkey mode disabled."))//feedback to the user - - if(hotkeyon)//using an if statement because I don't want to clutter winset() with ? operators - winset(usr, "mainwindow.hotkey_toggle", "is-checked=true")//checks the button - else - winset(usr, "mainwindow.hotkey_toggle", "is-checked=false")//unchecks the button - if(mob) - mob.update_interface() - -/client/verb/hotkey_mode()//asks user for the hotkey type and changes the macro accordingly - set name = "Set Hotkey Mode" - set category = "Preferences" - - var/hkt = input("Choose hotkey mode", "Hotkey mode") as null|anything in hotkeylist//ask the user for the hotkey type - if(!hkt) - return - hotkeytype = hkt - - var/hotkeys = hotkeylist[hotkeytype]//get the list containing the hotkey names - var/hotkeyname = hotkeys[hotkeyon ? "on" : "off"]//get the name of the hotkey, to not clutter winset() to much - - winset(usr, "mainwindow", "macro=[hotkeyname]")//change the hotkey - to_chat(usr, "Hotkey mode changed to [hotkeytype].") diff --git a/interface/skin.dmf b/interface/skin.dmf index 996edf78905..e77ab2f9e33 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1,713 +1,7 @@ -macro "AZERTYoff" - elem "AZRFF-TAB" - name = "TAB" - command = ".Toggle-hotkey-mode" - is-disabled = false - elem "AZRFF-CENTER+REP" - name = "CENTER+REP" - command = ".center" - is-disabled = false - elem "AZRFF-NORTHEAST" - name = "NORTHEAST" - command = ".northeast" - is-disabled = false - elem "AZRFF-SOUTHEAST" - name = "SOUTHEAST" - command = ".southeast" - is-disabled = false - elem "AZRFF-SOUTHWEST" - name = "SOUTHWEST" - command = ".southwest" - is-disabled = false - elem "AZRFF-NORTHWEST" - name = "NORTHWEST" - command = ".northwest" - is-disabled = false - elem "AZRFF-CTRL+WEST" - name = "CTRL+WEST" - command = "westface" - is-disabled = false - elem "AZRFF-WEST+REP" - name = "WEST+REP" - command = ".moveleft" - is-disabled = false - elem "AZRFF-CTRL+NORTH" - name = "CTRL+NORTH" - command = "northface" - is-disabled = false - elem "AZRFF-NORTH+REP" - name = "NORTH+REP" - command = ".moveup" - is-disabled = false - elem "AZRFF-CTRL+EAST" - name = "CTRL+EAST" - command = "eastface" - is-disabled = false - elem "AZRFF-EAST+REP" - name = "EAST+REP" - command = ".moveright" - is-disabled = false - elem "AZRFF-CTRL+SOUTH" - name = "CTRL+SOUTH" - command = "southface" - is-disabled = false - elem "AZRFF-SOUTH+REP" - name = "SOUTH+REP" - command = ".movedown" - is-disabled = false - elem "AZRFF-INSERT" - name = "INSERT" - command = "a-intent right" - is-disabled = false - elem "AZRFF-DELETE" - name = "DELETE" - command = "delete-key-pressed" - is-disabled = false - elem "AZRFF-CTRL+1" - name = "CTRL+1" - command = "a-intent help" - is-disabled = false - elem "AZRFF-CTRL+2" - name = "CTRL+2" - command = "a-intent disarm" - is-disabled = false - elem "AZRFF-CTRL+3" - name = "CTRL+3" - command = "a-intent grab" - is-disabled = false - elem "AZRFF-CTRL+4" - name = "CTRL+4" - command = "a-intent harm" - is-disabled = false - elem "AZRFF-CTRL+A" - name = "CTRL+A" - command = ".northwest" - is-disabled = false - elem "AZRFF-CTRL+D+REP" - name = "CTRL+D+REP" - command = ".moveright" - is-disabled = false - elem "AZRFF-CTRL+B" - name = "CTRL+B" - command = "resist" - is-disabled = false - elem "AZRFF-CTRL+E" - name = "CTRL+E" - command = "quick-equip" - is-disabled = false - elem "AZRFF-CTRL+F" - name = "CTRL+F" - command = "a-intent left" - is-disabled = false - elem "AZRFF-CTRL+G" - name = "CTRL+G" - command = "a-intent right" - is-disabled = false - elem "AZRFF-CTRL+Q+REP" - name = "CTRL+Q+REP" - command = ".moveleft" - is-disabled = false - elem "AZRFF-CTRL+R" - name = "CTRL+R" - command = ".southwest" - is-disabled = false - elem "AZRFF-CTRL+S+REP" - name = "CTRL+S+REP" - command = ".movedown" - is-disabled = false - elem "AZRFF-CTRL+W" - name = "CTRL+W" - command = "Activate-Held-Object" - is-disabled = false - elem "AZRFF-CTRL+X" - name = "CTRL+X" - command = ".northeast" - is-disabled = false - elem "AZRFF-CTRL+Y" - name = "CTRL+Y" - command = "Activate-Held-Object" - is-disabled = false - elem "AZRFF-CTRL+Z+REP" - name = "CTRL+Z+REP" - command = ".moveup" - is-disabled = false - elem "AZRFF-F1" - name = "F1" - command = "adminhelp" - is-disabled = false - elem "AZRFF-CTRL+SHIFT+F1+REP" - name = "CTRL+SHIFT+F1+REP" - command = ".options" - is-disabled = false - elem "AZRFF-F2" - name = "F2" - command = "ooc" - is-disabled = false - elem "AZRFF-F2+REP" - name = "F2+REP" - command = ".screenshot auto" - is-disabled = false - elem "AZRFF-SHIFT+F2+REP" - name = "SHIFT+F2+REP" - command = ".screenshot" - is-disabled = false - elem "AZRFF-F3" - name = "F3" - command = ".say" - is-disabled = false - elem "AZRFF-F4" - name = "F4" - command = ".me" - is-disabled = false - elem "AZRFF-F5" - name = "F5" - command = "asay" - is-disabled = false - elem "AZRFF-F6" - name = "F6" - command = "Aghost" - is-disabled = false - elem "AZRFF-F7" - name = "F7" - command = "player-panel-new" - is-disabled = false - elem "AZRFF-F8" - name = "F8" - command = "admin-pm-key" - is-disabled = false - elem "AZRFF-F9" - name = "F9" - command = "Invisimin" - is-disabled = false - elem "AZRFF-F12" - name = "F12" - command = "F12" - is-disabled = false - -macro "AZERTYon" - elem "AZRON-TAB" - name = "TAB" - command = ".Toggle-hotkey-mode" - is-disabled = false - elem "AZRON-CENTER+REP" - name = "CENTER+REP" - command = ".center" - is-disabled = false - elem "AZRON-NORTHEAST" - name = "NORTHEAST" - command = ".northeast" - is-disabled = false - elem "AZRON-SOUTHEAST" - name = "SOUTHEAST" - command = ".southeast" - is-disabled = false - elem "AZRON-SOUTHWEST" - name = "SOUTHWEST" - command = ".southwest" - is-disabled = false - elem "AZRON-NORTHWEST" - name = "NORTHWEST" - command = ".northwest" - is-disabled = false - elem "AZRON-CTRL+WEST" - name = "CTRL+WEST" - command = "westface" - is-disabled = false - elem "AZRON-WEST+REP" - name = "WEST+REP" - command = ".moveleft" - is-disabled = false - elem "AZRON-CTRL+NORTH" - name = "CTRL+NORTH" - command = "northface" - is-disabled = false - elem "AZRON-NORTH+REP" - name = "NORTH+REP" - command = ".moveup" - is-disabled = false - elem "AZRON-CTRL+EAST" - name = "CTRL+EAST" - command = "eastface" - is-disabled = false - elem "AZRON-EAST+REP" - name = "EAST+REP" - command = ".moveright" - is-disabled = false - elem "AZRON-CTRL+SOUTH" - name = "CTRL+SOUTH" - command = "southface" - is-disabled = false - elem "AZRON-SOUTH+REP" - name = "SOUTH+REP" - command = ".movedown" - is-disabled = false - elem "AZRON-INSERT" - name = "INSERT" - command = "a-intent right" - is-disabled = false - elem "AZRON-DELETE" - name = "DELETE" - command = "delete-key-pressed" - is-disabled = false - elem "AZRON-1" - name = "1" - command = "a-intent help" - is-disabled = false - elem "AZRON-CTRL+1" - name = "CTRL+1" - command = "a-intent help" - is-disabled = false - elem "AZRON-2" - name = "2" - command = "a-intent disarm" - is-disabled = false - elem "AZRON-CTRL+2" - name = "CTRL+2" - command = "a-intent disarm" - is-disabled = false - elem "AZRON-3" - name = "3" - command = "a-intent grab" - is-disabled = false - elem "AZRON-CTRL+3" - name = "CTRL+3" - command = "a-intent grab" - is-disabled = false - elem "AZRON-4" - name = "4" - command = "a-intent harm" - is-disabled = false - elem "AZRON-CTRL+4" - name = "CTRL+4" - command = "a-intent harm" - is-disabled = false - elem "AZRON-A" - name = "A" - command = ".northwest" - is-disabled = false - elem "AZRON-CTRL+A" - name = "CTRL+A" - command = ".northwest" - is-disabled = false - elem "AZRON-D+REP" - name = "D+REP" - command = ".moveright" - is-disabled = false - elem "AZRON-CTRL+D+REP" - name = "CTRL+D+REP" - command = ".moveright" - is-disabled = false - elem "AZRON-CTRL+B" - name = "CTRL+B" - command = "resist" - is-disabled = false - elem "AZRON-E" - name = "E" - command = "quick-equip" - is-disabled = false - elem "AZRON-CTRL+E" - name = "CTRL+E" - command = "quick-equip" - is-disabled = false - elem "AZRON-F" - name = "F" - command = "a-intent left" - is-disabled = false - elem "AZRON-CTRL+F" - name = "CTRL+F" - command = "a-intent left" - is-disabled = false - elem "AZRON-G" - name = "G" - command = "a-intent right" - is-disabled = false - elem "AZRON-CTRL+G" - name = "CTRL+G" - command = "a-intent right" - is-disabled = false - elem "AZRON-H" - name = "H" - command = "holster" - is-disabled = false - elem "AZRON-CTRL+H" - name = "CTRL+H" - command = "holster" - is-disabled = false - elem "AZRON-Q+REP" - name = "Q+REP" - command = ".moveleft" - is-disabled = false - elem "AZRON-CTRL+Q+REP" - name = "CTRL+Q+REP" - command = ".moveleft" - is-disabled = false - elem "AZRON-R" - name = "R" - command = ".southwest" - is-disabled = false - elem "AZRON-CTRL+R" - name = "CTRL+R" - command = ".southwest" - is-disabled = false - elem "s_key" - name = "S+REP" - command = ".movedown" - is-disabled = false - elem "AZRON-CTRL+S+REP" - name = "CTRL+S+REP" - command = ".movedown" - is-disabled = false - elem "AZRON-T" - name = "T" - command = ".say" - is-disabled = false - elem "AZRON-O" - name = "O" - command = "ooc" - is-disabled = false - elem "AZRON-M" - name = "M" - command = ".me" - is-disabled = false - elem "AZRON-W" - name = "W" - command = "Activate-Held-Object" - is-disabled = false - elem "AZRON-CTRL+W" - name = "CTRL+W" - command = "Activate-Held-Object" - is-disabled = false - elem "AZRON-X" - name = "X" - command = ".northeast" - is-disabled = false - elem "AZRON-CTRL+X" - name = "CTRL+X" - command = ".northeast" - is-disabled = false - elem "AZRON-Y" - name = "Y" - command = "Activate-Held-Object" - is-disabled = false - elem "AZRON-CTRL+Y" - name = "CTRL+Y" - command = "Activate-Held-Object" - is-disabled = false - elem "w_key" - name = "Z+REP" - command = ".moveup" - is-disabled = false - elem "AZRON-CTRL+Z+REP" - name = "CTRL+Z+REP" - command = ".moveup" - is-disabled = false - elem "AZRON-F1" - name = "F1" - command = "adminhelp" - is-disabled = false - elem "AZRON-CTRL+SHIFT+F1+REP" - name = "CTRL+SHIFT+F1+REP" - command = ".options" - is-disabled = false - elem "AZRON-F2" - name = "F2" - command = "ooc" - is-disabled = false - elem "AZRON-F2+REP" - name = "F2+REP" - command = ".screenshot auto" - is-disabled = false - elem "AZRON-SHIFT+F2+REP" - name = "SHIFT+F2+REP" - command = ".screenshot" - is-disabled = false - elem "AZRON-F3" - name = "F3" - command = ".say" - is-disabled = false - elem "AZRON-F4" - name = "F4" - command = ".me" - is-disabled = false - elem "AZRON-F5" - name = "F5" - command = "asay" - is-disabled = false - elem "AZRON-F6" - name = "F6" - command = "Aghost" - is-disabled = false - elem "AZRON-F7" - name = "F7" - command = "player-panel-new" - is-disabled = false - elem "AZRON-F8" - name = "F8" - command = "admin-pm-key" - is-disabled = false - elem "AZRON-F9" - name = "F9" - command = "Invisimin" - is-disabled = false - elem "AZRON-F12" - name = "F12" - command = "F12" - is-disabled = false - -macro "borghotkeymode" - elem "BRGHK-TAB" - name = "TAB" - command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\"" - is-disabled = false - elem "BRGHK-CENTER+REP" - name = "CENTER+REP" - command = ".center" - is-disabled = false - elem "BRGHK-NORTHEAST" - name = "NORTHEAST" - command = ".northeast" - is-disabled = false - elem "BRGHK-SOUTHEAST" - name = "SOUTHEAST" - command = ".southeast" - is-disabled = false - elem "BRGHK-NORTHWEST" - name = "NORTHWEST" - command = "unequip-module" - is-disabled = false - elem "BRGHK-CTRL+WEST" - name = "CTRL+WEST" - command = "westface" - is-disabled = false - elem "BRGHK-WEST+REP" - name = "WEST+REP" - command = ".moveleft" - is-disabled = false - elem "BRGHK-CTRL+NORTH" - name = "CTRL+NORTH" - command = "northface" - is-disabled = false - elem "BRGHK-NORTH+REP" - name = "NORTH+REP" - command = ".moveup" - is-disabled = false - elem "BRGHK-CTRL+EAST" - name = "CTRL+EAST" - command = "eastface" - is-disabled = false - elem "BRGHK-EAST+REP" - name = "EAST+REP" - command = ".moveright" - is-disabled = false - elem "BRGHK-CTRL+SOUTH" - name = "CTRL+SOUTH" - command = "southface" - is-disabled = false - elem "BRGHK-SOUTH+REP" - name = "SOUTH+REP" - command = ".movedown" - is-disabled = false - elem "BRGHK-INSERT" - name = "INSERT" - command = "a-intent right" - is-disabled = false - elem "BRGHK-DELETE" - name = "DELETE" - command = "delete-key-pressed" - is-disabled = false - elem "BRGHK-1" - name = "1" - command = "toggle-module 1" - is-disabled = false - elem "BRGHK-CTRL+1" - name = "CTRL+1" - command = "toggle-module 1" - is-disabled = false - elem "BRGHK-2" - name = "2" - command = "toggle-module 2" - is-disabled = false - elem "BRGHK-CTRL+2" - name = "CTRL+2" - command = "toggle-module 2" - is-disabled = false - elem "BRGHK-3" - name = "3" - command = "toggle-module 3" - is-disabled = false - elem "BRGHK-CTRL+3" - name = "CTRL+3" - command = "toggle-module 3" - is-disabled = false - elem "BRGHK-4" - name = "4" - command = "a-intent left" - is-disabled = false - elem "BRGHK-CTRL+4" - name = "CTRL+4" - command = "a-intent left" - is-disabled = false - elem "BRGHK-A+REP" - name = "A+REP" - command = ".moveleft" - is-disabled = false - elem "BRGHK-CTRL+A+REP" - name = "CTRL+A+REP" - command = ".moveleft" - is-disabled = false - elem "BRGHK-B" - name = "B" - command = "resist" - is-disabled = false - elem "BRGHK-CTRL+B" - name = "CTRL+B" - command = "resist" - is-disabled = false - elem "BRGHK-T" - name = "T" - command = ".say" - is-disabled = false - elem "BRGHK-O" - name = "O" - command = "ooc" - is-disabled = false - elem "BRGHK-M" - name = "M" - command = ".me" - is-disabled = false - elem "BRGHK-CTRL+O" - name = "CTRL+O" - command = "ooc" - is-disabled = false - elem "BRGHK-D+REP" - name = "D+REP" - command = ".moveright" - is-disabled = false - elem "BRGHK-CTRL+D+REP" - name = "CTRL+D+REP" - command = ".moveright" - is-disabled = false - elem "BRGHK-F" - name = "F" - command = "a-intent left" - is-disabled = false - elem "BRGHK-CTRL+F" - name = "CTRL+F" - command = "a-intent left" - is-disabled = false - elem "BRGHK-G" - name = "G" - command = "a-intent right" - is-disabled = false - elem "BRGHK-CTRL+G" - name = "CTRL+G" - command = "a-intent right" - is-disabled = false - elem "BRGHK-Q" - name = "Q" - command = "unequip-module" - is-disabled = false - elem "BRGHK-CTRL+Q" - name = "CTRL+Q" - command = "unequip-module" - is-disabled = false - elem "s_key" - name = "S+REP" - command = ".movedown" - is-disabled = false - elem "BRGHK-CTRL+S+REP" - name = "CTRL+S+REP" - command = ".movedown" - is-disabled = false - elem "w_key" - name = "W+REP" - command = ".moveup" - is-disabled = false - elem "BRGHK-CTRL+W+REP" - name = "CTRL+W+REP" - command = ".moveup" - is-disabled = false - elem "BRGHK-X" - name = "X" - command = ".northeast" - is-disabled = false - elem "BRGHK-CTRL+X" - name = "CTRL+X" - command = ".northeast" - is-disabled = false - elem "BRGHK-Y" - name = "Y" - command = "Activate-Held-Object" - is-disabled = false - elem "BRGHK-CTRL+Y" - name = "CTRL+Y" - command = "Activate-Held-Object" - is-disabled = false - elem "BRGHK-Z" - name = "Z" - command = "Activate-Held-Object" - is-disabled = false - elem "BRGHK-CTRL+Z" - name = "CTRL+Z" - command = "Activate-Held-Object" - is-disabled = false - elem "BRGHK-F1" - name = "F1" - command = "adminhelp" - is-disabled = false - elem "BRGHK-CTRL+SHIFT+F1+REP" - name = "CTRL+SHIFT+F1+REP" - command = ".options" - is-disabled = false - elem "BRGHK-F2" - name = "F2" - command = "ooc" - is-disabled = false - elem "BRGHK-F2+REP" - name = "F2+REP" - command = ".screenshot auto" - is-disabled = false - elem "BRGHK-SHIFT+F2+REP" - name = "SHIFT+F2+REP" - command = ".screenshot" - is-disabled = false - elem "BRGHK-F3" - name = "F3" - command = ".say" - is-disabled = false - elem "BRGHK-F4" - name = "F4" - command = ".me" - is-disabled = false - elem "BRGHK-F5" - name = "F5" - command = "asay" - is-disabled = false - elem "BRGHK-F6" - name = "F6" - command = "Aghost" - is-disabled = false - elem "BRGHK-F7" - name = "F7" - command = "player-panel-new" - is-disabled = false - elem "BRGHK-F8" - name = "F8" - command = "admin-pm-key" - is-disabled = false - elem "BRGHK-F9" - name = "F9" - command = "Invisimin" - is-disabled = false - elem "BRGHK-F12" - name = "F12" - command = "F12" - is-disabled = false - macro "macro" elem "MACRO-TAB" name = "TAB" - command = ".Toggle-hotkey-mode" + command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\"" is-disabled = false elem "MACRO-CENTER+REP" name = "CENTER+REP" @@ -893,7 +187,7 @@ macro "macro" macro "hotkeymode" elem "HKMODE-TAB" name = "TAB" - command = ".Toggle-hotkey-mode" + command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\"" is-disabled = false elem "HKMODE-CENTER+REP" name = "CENTER+REP" @@ -1346,6 +640,712 @@ macro "borgmacro" command = "F12" is-disabled = false +macro "borghotkeymode" + elem "BRGHK-TAB" + name = "TAB" + command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\"" + is-disabled = false + elem "BRGHK-CENTER+REP" + name = "CENTER+REP" + command = ".center" + is-disabled = false + elem "BRGHK-NORTHEAST" + name = "NORTHEAST" + command = ".northeast" + is-disabled = false + elem "BRGHK-SOUTHEAST" + name = "SOUTHEAST" + command = ".southeast" + is-disabled = false + elem "BRGHK-NORTHWEST" + name = "NORTHWEST" + command = "unequip-module" + is-disabled = false + elem "BRGHK-CTRL+WEST" + name = "CTRL+WEST" + command = "westface" + is-disabled = false + elem "BRGHK-WEST+REP" + name = "WEST+REP" + command = ".moveleft" + is-disabled = false + elem "BRGHK-CTRL+NORTH" + name = "CTRL+NORTH" + command = "northface" + is-disabled = false + elem "BRGHK-NORTH+REP" + name = "NORTH+REP" + command = ".moveup" + is-disabled = false + elem "BRGHK-CTRL+EAST" + name = "CTRL+EAST" + command = "eastface" + is-disabled = false + elem "BRGHK-EAST+REP" + name = "EAST+REP" + command = ".moveright" + is-disabled = false + elem "BRGHK-CTRL+SOUTH" + name = "CTRL+SOUTH" + command = "southface" + is-disabled = false + elem "BRGHK-SOUTH+REP" + name = "SOUTH+REP" + command = ".movedown" + is-disabled = false + elem "BRGHK-INSERT" + name = "INSERT" + command = "a-intent right" + is-disabled = false + elem "BRGHK-DELETE" + name = "DELETE" + command = "delete-key-pressed" + is-disabled = false + elem "BRGHK-1" + name = "1" + command = "toggle-module 1" + is-disabled = false + elem "BRGHK-CTRL+1" + name = "CTRL+1" + command = "toggle-module 1" + is-disabled = false + elem "BRGHK-2" + name = "2" + command = "toggle-module 2" + is-disabled = false + elem "BRGHK-CTRL+2" + name = "CTRL+2" + command = "toggle-module 2" + is-disabled = false + elem "BRGHK-3" + name = "3" + command = "toggle-module 3" + is-disabled = false + elem "BRGHK-CTRL+3" + name = "CTRL+3" + command = "toggle-module 3" + is-disabled = false + elem "BRGHK-4" + name = "4" + command = "a-intent left" + is-disabled = false + elem "BRGHK-CTRL+4" + name = "CTRL+4" + command = "a-intent left" + is-disabled = false + elem "BRGHK-A+REP" + name = "A+REP" + command = ".moveleft" + is-disabled = false + elem "BRGHK-CTRL+A+REP" + name = "CTRL+A+REP" + command = ".moveleft" + is-disabled = false + elem "BRGHK-B" + name = "B" + command = "resist" + is-disabled = false + elem "BRGHK-CTRL+B" + name = "CTRL+B" + command = "resist" + is-disabled = false + elem "BRGHK-T" + name = "T" + command = ".say" + is-disabled = false + elem "BRGHK-O" + name = "O" + command = "ooc" + is-disabled = false + elem "BRGHK-M" + name = "M" + command = ".me" + is-disabled = false + elem "BRGHK-CTRL+O" + name = "CTRL+O" + command = "ooc" + is-disabled = false + elem "BRGHK-D+REP" + name = "D+REP" + command = ".moveright" + is-disabled = false + elem "BRGHK-CTRL+D+REP" + name = "CTRL+D+REP" + command = ".moveright" + is-disabled = false + elem "BRGHK-F" + name = "F" + command = "a-intent left" + is-disabled = false + elem "BRGHK-CTRL+F" + name = "CTRL+F" + command = "a-intent left" + is-disabled = false + elem "BRGHK-G" + name = "G" + command = "a-intent right" + is-disabled = false + elem "BRGHK-CTRL+G" + name = "CTRL+G" + command = "a-intent right" + is-disabled = false + elem "BRGHK-Q" + name = "Q" + command = "unequip-module" + is-disabled = false + elem "BRGHK-CTRL+Q" + name = "CTRL+Q" + command = "unequip-module" + is-disabled = false + elem "s_key" + name = "S+REP" + command = ".movedown" + is-disabled = false + elem "BRGHK-CTRL+S+REP" + name = "CTRL+S+REP" + command = ".movedown" + is-disabled = false + elem "w_key" + name = "W+REP" + command = ".moveup" + is-disabled = false + elem "BRGHK-CTRL+W+REP" + name = "CTRL+W+REP" + command = ".moveup" + is-disabled = false + elem "BRGHK-X" + name = "X" + command = ".northeast" + is-disabled = false + elem "BRGHK-CTRL+X" + name = "CTRL+X" + command = ".northeast" + is-disabled = false + elem "BRGHK-Y" + name = "Y" + command = "Activate-Held-Object" + is-disabled = false + elem "BRGHK-CTRL+Y" + name = "CTRL+Y" + command = "Activate-Held-Object" + is-disabled = false + elem "BRGHK-Z" + name = "Z" + command = "Activate-Held-Object" + is-disabled = false + elem "BRGHK-CTRL+Z" + name = "CTRL+Z" + command = "Activate-Held-Object" + is-disabled = false + elem "BRGHK-F1" + name = "F1" + command = "adminhelp" + is-disabled = false + elem "BRGHK-CTRL+SHIFT+F1+REP" + name = "CTRL+SHIFT+F1+REP" + command = ".options" + is-disabled = false + elem "BRGHK-F2" + name = "F2" + command = "ooc" + is-disabled = false + elem "BRGHK-F2+REP" + name = "F2+REP" + command = ".screenshot auto" + is-disabled = false + elem "BRGHK-SHIFT+F2+REP" + name = "SHIFT+F2+REP" + command = ".screenshot" + is-disabled = false + elem "BRGHK-F3" + name = "F3" + command = ".say" + is-disabled = false + elem "BRGHK-F4" + name = "F4" + command = ".me" + is-disabled = false + elem "BRGHK-F5" + name = "F5" + command = "asay" + is-disabled = false + elem "BRGHK-F6" + name = "F6" + command = "Aghost" + is-disabled = false + elem "BRGHK-F7" + name = "F7" + command = "player-panel-new" + is-disabled = false + elem "BRGHK-F8" + name = "F8" + command = "admin-pm-key" + is-disabled = false + elem "BRGHK-F9" + name = "F9" + command = "Invisimin" + is-disabled = false + elem "BRGHK-F12" + name = "F12" + command = "F12" + is-disabled = false + +macro "azertymacro" + elem "AZRFF-TAB" + name = "TAB" + command = ".winset \"mainwindow.macro=azertyhotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\"" + is-disabled = false + elem "AZRFF-CENTER+REP" + name = "CENTER+REP" + command = ".center" + is-disabled = false + elem "AZRFF-NORTHEAST" + name = "NORTHEAST" + command = ".northeast" + is-disabled = false + elem "AZRFF-SOUTHEAST" + name = "SOUTHEAST" + command = ".southeast" + is-disabled = false + elem "AZRFF-SOUTHWEST" + name = "SOUTHWEST" + command = ".southwest" + is-disabled = false + elem "AZRFF-NORTHWEST" + name = "NORTHWEST" + command = ".northwest" + is-disabled = false + elem "AZRFF-CTRL+WEST" + name = "CTRL+WEST" + command = "westface" + is-disabled = false + elem "AZRFF-WEST+REP" + name = "WEST+REP" + command = ".moveleft" + is-disabled = false + elem "AZRFF-CTRL+NORTH" + name = "CTRL+NORTH" + command = "northface" + is-disabled = false + elem "AZRFF-NORTH+REP" + name = "NORTH+REP" + command = ".moveup" + is-disabled = false + elem "AZRFF-CTRL+EAST" + name = "CTRL+EAST" + command = "eastface" + is-disabled = false + elem "AZRFF-EAST+REP" + name = "EAST+REP" + command = ".moveright" + is-disabled = false + elem "AZRFF-CTRL+SOUTH" + name = "CTRL+SOUTH" + command = "southface" + is-disabled = false + elem "AZRFF-SOUTH+REP" + name = "SOUTH+REP" + command = ".movedown" + is-disabled = false + elem "AZRFF-INSERT" + name = "INSERT" + command = "a-intent right" + is-disabled = false + elem "AZRFF-DELETE" + name = "DELETE" + command = "delete-key-pressed" + is-disabled = false + elem "AZRFF-CTRL+1" + name = "CTRL+1" + command = "a-intent help" + is-disabled = false + elem "AZRFF-CTRL+2" + name = "CTRL+2" + command = "a-intent disarm" + is-disabled = false + elem "AZRFF-CTRL+3" + name = "CTRL+3" + command = "a-intent grab" + is-disabled = false + elem "AZRFF-CTRL+4" + name = "CTRL+4" + command = "a-intent harm" + is-disabled = false + elem "AZRFF-CTRL+A" + name = "CTRL+A" + command = ".northwest" + is-disabled = false + elem "AZRFF-CTRL+D+REP" + name = "CTRL+D+REP" + command = ".moveright" + is-disabled = false + elem "AZRFF-CTRL+B" + name = "CTRL+B" + command = "resist" + is-disabled = false + elem "AZRFF-CTRL+E" + name = "CTRL+E" + command = "quick-equip" + is-disabled = false + elem "AZRFF-CTRL+F" + name = "CTRL+F" + command = "a-intent left" + is-disabled = false + elem "AZRFF-CTRL+G" + name = "CTRL+G" + command = "a-intent right" + is-disabled = false + elem "AZRFF-CTRL+Q+REP" + name = "CTRL+Q+REP" + command = ".moveleft" + is-disabled = false + elem "AZRFF-CTRL+R" + name = "CTRL+R" + command = ".southwest" + is-disabled = false + elem "AZRFF-CTRL+S+REP" + name = "CTRL+S+REP" + command = ".movedown" + is-disabled = false + elem "AZRFF-CTRL+W" + name = "CTRL+W" + command = "Activate-Held-Object" + is-disabled = false + elem "AZRFF-CTRL+X" + name = "CTRL+X" + command = ".northeast" + is-disabled = false + elem "AZRFF-CTRL+Y" + name = "CTRL+Y" + command = "Activate-Held-Object" + is-disabled = false + elem "AZRFF-CTRL+Z+REP" + name = "CTRL+Z+REP" + command = ".moveup" + is-disabled = false + elem "AZRFF-F1" + name = "F1" + command = "adminhelp" + is-disabled = false + elem "AZRFF-CTRL+SHIFT+F1+REP" + name = "CTRL+SHIFT+F1+REP" + command = ".options" + is-disabled = false + elem "AZRFF-F2" + name = "F2" + command = "ooc" + is-disabled = false + elem "AZRFF-F2+REP" + name = "F2+REP" + command = ".screenshot auto" + is-disabled = false + elem "AZRFF-SHIFT+F2+REP" + name = "SHIFT+F2+REP" + command = ".screenshot" + is-disabled = false + elem "AZRFF-F3" + name = "F3" + command = ".say" + is-disabled = false + elem "AZRFF-F4" + name = "F4" + command = ".me" + is-disabled = false + elem "AZRFF-F5" + name = "F5" + command = "asay" + is-disabled = false + elem "AZRFF-F6" + name = "F6" + command = "Aghost" + is-disabled = false + elem "AZRFF-F7" + name = "F7" + command = "player-panel-new" + is-disabled = false + elem "AZRFF-F8" + name = "F8" + command = "admin-pm-key" + is-disabled = false + elem "AZRFF-F9" + name = "F9" + command = "Invisimin" + is-disabled = false + elem "AZRFF-F12" + name = "F12" + command = "F12" + is-disabled = false + +macro "azertyhotkeymode" + elem "AZRON-TAB" + name = "TAB" + command = ".winset \"mainwindow.macro=azertymacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\"" + is-disabled = false + elem "AZRON-CENTER+REP" + name = "CENTER+REP" + command = ".center" + is-disabled = false + elem "AZRON-NORTHEAST" + name = "NORTHEAST" + command = ".northeast" + is-disabled = false + elem "AZRON-SOUTHEAST" + name = "SOUTHEAST" + command = ".southeast" + is-disabled = false + elem "AZRON-SOUTHWEST" + name = "SOUTHWEST" + command = ".southwest" + is-disabled = false + elem "AZRON-NORTHWEST" + name = "NORTHWEST" + command = ".northwest" + is-disabled = false + elem "AZRON-CTRL+WEST" + name = "CTRL+WEST" + command = "westface" + is-disabled = false + elem "AZRON-WEST+REP" + name = "WEST+REP" + command = ".moveleft" + is-disabled = false + elem "AZRON-CTRL+NORTH" + name = "CTRL+NORTH" + command = "northface" + is-disabled = false + elem "AZRON-NORTH+REP" + name = "NORTH+REP" + command = ".moveup" + is-disabled = false + elem "AZRON-CTRL+EAST" + name = "CTRL+EAST" + command = "eastface" + is-disabled = false + elem "AZRON-EAST+REP" + name = "EAST+REP" + command = ".moveright" + is-disabled = false + elem "AZRON-CTRL+SOUTH" + name = "CTRL+SOUTH" + command = "southface" + is-disabled = false + elem "AZRON-SOUTH+REP" + name = "SOUTH+REP" + command = ".movedown" + is-disabled = false + elem "AZRON-INSERT" + name = "INSERT" + command = "a-intent right" + is-disabled = false + elem "AZRON-DELETE" + name = "DELETE" + command = "delete-key-pressed" + is-disabled = false + elem "AZRON-1" + name = "1" + command = "a-intent help" + is-disabled = false + elem "AZRON-CTRL+1" + name = "CTRL+1" + command = "a-intent help" + is-disabled = false + elem "AZRON-2" + name = "2" + command = "a-intent disarm" + is-disabled = false + elem "AZRON-CTRL+2" + name = "CTRL+2" + command = "a-intent disarm" + is-disabled = false + elem "AZRON-3" + name = "3" + command = "a-intent grab" + is-disabled = false + elem "AZRON-CTRL+3" + name = "CTRL+3" + command = "a-intent grab" + is-disabled = false + elem "AZRON-4" + name = "4" + command = "a-intent harm" + is-disabled = false + elem "AZRON-CTRL+4" + name = "CTRL+4" + command = "a-intent harm" + is-disabled = false + elem "AZRON-A" + name = "A" + command = ".northwest" + is-disabled = false + elem "AZRON-CTRL+A" + name = "CTRL+A" + command = ".northwest" + is-disabled = false + elem "AZRON-D+REP" + name = "D+REP" + command = ".moveright" + is-disabled = false + elem "AZRON-CTRL+D+REP" + name = "CTRL+D+REP" + command = ".moveright" + is-disabled = false + elem "AZRON-CTRL+B" + name = "CTRL+B" + command = "resist" + is-disabled = false + elem "AZRON-E" + name = "E" + command = "quick-equip" + is-disabled = false + elem "AZRON-CTRL+E" + name = "CTRL+E" + command = "quick-equip" + is-disabled = false + elem "AZRON-F" + name = "F" + command = "a-intent left" + is-disabled = false + elem "AZRON-CTRL+F" + name = "CTRL+F" + command = "a-intent left" + is-disabled = false + elem "AZRON-G" + name = "G" + command = "a-intent right" + is-disabled = false + elem "AZRON-CTRL+G" + name = "CTRL+G" + command = "a-intent right" + is-disabled = false + elem "AZRON-H" + name = "H" + command = "holster" + is-disabled = false + elem "AZRON-CTRL+H" + name = "CTRL+H" + command = "holster" + is-disabled = false + elem "AZRON-Q+REP" + name = "Q+REP" + command = ".moveleft" + is-disabled = false + elem "AZRON-CTRL+Q+REP" + name = "CTRL+Q+REP" + command = ".moveleft" + is-disabled = false + elem "AZRON-R" + name = "R" + command = ".southwest" + is-disabled = false + elem "AZRON-CTRL+R" + name = "CTRL+R" + command = ".southwest" + is-disabled = false + elem "s_key" + name = "S+REP" + command = ".movedown" + is-disabled = false + elem "AZRON-CTRL+S+REP" + name = "CTRL+S+REP" + command = ".movedown" + is-disabled = false + elem "AZRON-T" + name = "T" + command = ".say" + is-disabled = false + elem "AZRON-O" + name = "O" + command = "ooc" + is-disabled = false + elem "AZRON-M" + name = "M" + command = ".me" + is-disabled = false + elem "AZRON-W" + name = "W" + command = "Activate-Held-Object" + is-disabled = false + elem "AZRON-CTRL+W" + name = "CTRL+W" + command = "Activate-Held-Object" + is-disabled = false + elem "AZRON-X" + name = "X" + command = ".northeast" + is-disabled = false + elem "AZRON-CTRL+X" + name = "CTRL+X" + command = ".northeast" + is-disabled = false + elem "AZRON-Y" + name = "Y" + command = "Activate-Held-Object" + is-disabled = false + elem "AZRON-CTRL+Y" + name = "CTRL+Y" + command = "Activate-Held-Object" + is-disabled = false + elem "w_key" + name = "Z+REP" + command = ".moveup" + is-disabled = false + elem "AZRON-CTRL+Z+REP" + name = "CTRL+Z+REP" + command = ".moveup" + is-disabled = false + elem "AZRON-F1" + name = "F1" + command = "adminhelp" + is-disabled = false + elem "AZRON-CTRL+SHIFT+F1+REP" + name = "CTRL+SHIFT+F1+REP" + command = ".options" + is-disabled = false + elem "AZRON-F2" + name = "F2" + command = "ooc" + is-disabled = false + elem "AZRON-F2+REP" + name = "F2+REP" + command = ".screenshot auto" + is-disabled = false + elem "AZRON-SHIFT+F2+REP" + name = "SHIFT+F2+REP" + command = ".screenshot" + is-disabled = false + elem "AZRON-F3" + name = "F3" + command = ".say" + is-disabled = false + elem "AZRON-F4" + name = "F4" + command = ".me" + is-disabled = false + elem "AZRON-F5" + name = "F5" + command = "asay" + is-disabled = false + elem "AZRON-F6" + name = "F6" + command = "Aghost" + is-disabled = false + elem "AZRON-F7" + name = "F7" + command = "player-panel-new" + is-disabled = false + elem "AZRON-F8" + name = "F8" + command = "admin-pm-key" + is-disabled = false + elem "AZRON-F9" + name = "F9" + command = "Invisimin" + is-disabled = false + elem "AZRON-F12" + name = "F12" + command = "F12" + is-disabled = false + menu "menu" elem name = "&File" @@ -1537,11 +1537,11 @@ window "mainwindow" size = 80x20 anchor1 = 100,100 anchor2 = none + background-color = none + saved-params = "" is-flat = false text = "Hotkey Toggle" - command = ".Toggle-hotkey-mode" - is-checked = false - saved-params = "is-checked" + command = ".winset \"mainwindow.macro != macro ? mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5 : mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\"" elem "mainvsplit" type = CHILD pos = 3,0 diff --git a/nano/templates/chem_dispenser.tmpl b/nano/templates/chem_dispenser.tmpl index f8988e35e43..74d694530c9 100644 --- a/nano/templates/chem_dispenser.tmpl +++ b/nano/templates/chem_dispenser.tmpl @@ -16,6 +16,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm Dispense:
+ {{:helper.link('1', 'gear', {'amount' : 1}, (data.amount == 1) ? 'selected' : null)}} {{:helper.link('5', 'gear', {'amount' : 5}, (data.amount == 5) ? 'selected' : null)}} {{:helper.link('10', 'gear', {'amount' : 10}, (data.amount == 10) ? 'selected' : null)}} {{:helper.link('20', 'gear', {'amount' : 20}, (data.amount == 20) ? 'selected' : null)}} @@ -70,6 +71,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
+ {{:helper.link('Isolate', null, {'remove' : value.id, 'removeamount' : -1})}} {{:helper.link('1', null, {'remove' : value.id, 'removeamount' : 1})}} {{:helper.link('5', null, {'remove' : value.id, 'removeamount' : 5})}} {{:helper.link('10', null, {'remove' : value.id, 'removeamount' : 10})}} diff --git a/nano/templates/safe.tmpl b/nano/templates/safe.tmpl index 507534eebe7..15e8eddff86 100644 --- a/nano/templates/safe.tmpl +++ b/nano/templates/safe.tmpl @@ -29,14 +29,14 @@
-
{{:helper.link('Left 50', 'arrow-left', {'increment': 50})}}
-
{{:helper.link('Left 10', 'arrow-left', {'increment': 10})}}
-
{{:helper.link('Left 1', 'arrow-left', {'increment': 1})}}
+
{{:helper.link('Left 50', 'arrow-left', {'turnleft': 50})}}
+
{{:helper.link('Left 10', 'arrow-left', {'turnleft': 10})}}
+
{{:helper.link('Left 1', 'arrow-left', {'turnleft': 1})}}
{{if data.locked}} -
{{:helper.link('Right 1', 'arrow-right', {'decrement': 1})}}
-
{{:helper.link('Right 10', 'arrow-right', {'decrement': 10})}}
-
{{:helper.link('Right 50', 'arrow-right', {'decrement': 50})}}
+
{{:helper.link('Right 1', 'arrow-right', {'turnright': 1})}}
+
{{:helper.link('Right 10', 'arrow-right', {'turnright': 10})}}
+
{{:helper.link('Right 50', 'arrow-right', {'turnright': 50})}}
{{else}}
{{:helper.link('Right 1', 'arrow-right', null, 'disabled')}}
{{:helper.link('Right 10', 'arrow-right', null, 'disabled')}}
@@ -51,15 +51,13 @@
-
How to open your Scarborough Arms - 2 tumbler safe.
+
How to open your Scarborough Arms tumbler safe.
-
1. Turn the dial right two full turns.
-
2. Keep turning right and stop on first number.
-
3. Turn the dial left one full turn.
-
4. Turn left to second number. Do not go past it.
-
5. Turn the dial right until it stops.
-
6. Open the safe.
+
1. Turn the dial right to the first number.
+
2. Turn the dial left to the second number.
+
3. Continue repeating this process for each number, switching between right and left each time.
+
4. Open the safe.
-
To lock fully, turn the dial to the left for three rotations.
+
To lock fully, turn the dial to the left after closing the safe.
{{/if}} diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl index c67dbca9c61..3058bb10bbb 100644 --- a/nano/templates/uplink.tmpl +++ b/nano/templates/uplink.tmpl @@ -46,7 +46,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm {{for value.items :itemValue:itemIndex}}
- {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}} + {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}} {{if itemValue.hijack_only}}(HIJACK AGENTS ONLY){{/if}}
{{/for}} diff --git a/paradise.dme b/paradise.dme index 4f9c776cc99..e478048e4d8 100644 --- a/paradise.dme +++ b/paradise.dme @@ -51,6 +51,7 @@ #include "code\__DEFINES\preferences.dm" #include "code\__DEFINES\process_scheduler.dm" #include "code\__DEFINES\qdel.dm" +#include "code\__DEFINES\radio.dm" #include "code\__DEFINES\reagents.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\rolebans.dm" @@ -131,6 +132,7 @@ #include "code\_onclick\hud\alert.dm" #include "code\_onclick\hud\alien.dm" #include "code\_onclick\hud\alien_larva.dm" +#include "code\_onclick\hud\blob_overmind.dm" #include "code\_onclick\hud\bot.dm" #include "code\_onclick\hud\constructs.dm" #include "code\_onclick\hud\devil.dm" @@ -186,7 +188,6 @@ #include "code\ATMOSPHERICS\pipes\simple\pipe_simple_hidden.dm" #include "code\ATMOSPHERICS\pipes\simple\pipe_simple_insulated.dm" #include "code\ATMOSPHERICS\pipes\simple\pipe_simple_visible.dm" -#include "code\controllers\communications.dm" #include "code\controllers\configuration.dm" #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" @@ -194,10 +195,8 @@ #include "code\controllers\hooks-defs.dm" #include "code\controllers\hooks.dm" #include "code\controllers\master.dm" -#include "code\controllers\master_controller.dm" #include "code\controllers\subsystem.dm" #include "code\controllers\verbs.dm" -#include "code\controllers\voting.dm" #include "code\controllers\Processes\alarm.dm" #include "code\controllers\Processes\event.dm" #include "code\controllers\Processes\fast_process.dm" @@ -213,7 +212,9 @@ #include "code\controllers\subsystem\fires.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\icon_smooth.dm" +#include "code\controllers\subsystem\jobs.dm" #include "code\controllers\subsystem\machinery.dm" +#include "code\controllers\subsystem\mapping.dm" #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\nano_mob_hunter.dm" #include "code\controllers\subsystem\nanoui.dm" @@ -221,14 +222,17 @@ #include "code\controllers\subsystem\npcai.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm" +#include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\shuttles.dm" #include "code\controllers\subsystem\spacedrift.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\throwing.dm" -#include "code\controllers\subsystem\tickets.dm" #include "code\controllers\subsystem\timer.dm" +#include "code\controllers\subsystem\vote.dm" #include "code\controllers\subsystem\weather.dm" #include "code\controllers\subsystem\processing\processing.dm" +#include "code\controllers\subsystem\tickets\mentor_tickets.dm" +#include "code\controllers\subsystem\tickets\tickets.dm" #include "code\datums\action.dm" #include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm" @@ -248,6 +252,7 @@ #include "code\datums\periodic_news.dm" #include "code\datums\pipe_datums.dm" #include "code\datums\progressbar.dm" +#include "code\datums\radio.dm" #include "code\datums\recipe.dm" #include "code\datums\ruins.dm" #include "code\datums\shuttles.dm" @@ -278,6 +283,7 @@ #include "code\datums\diseases\brainrot.dm" #include "code\datums\diseases\cold.dm" #include "code\datums\diseases\cold9.dm" +#include "code\datums\diseases\critical.dm" #include "code\datums\diseases\fake_gbs.dm" #include "code\datums\diseases\flu.dm" #include "code\datums\diseases\fluspanish.dm" @@ -327,6 +333,7 @@ #include "code\datums\helper_datums\construction_datum.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\global_iterator.dm" +#include "code\datums\helper_datums\hotkey_modes.dm" #include "code\datums\helper_datums\icon_snapshot.dm" #include "code\datums\helper_datums\map_template.dm" #include "code\datums\helper_datums\teleport.dm" @@ -540,9 +547,6 @@ #include "code\game\gamemodes\miniantags\sintouched\objectives.dm" #include "code\game\gamemodes\miniantags\slaughter\bloodcrawl.dm" #include "code\game\gamemodes\miniantags\slaughter\slaughter.dm" -#include "code\game\gamemodes\nations\nations.dm" -#include "code\game\gamemodes\nations\nationsdatums.dm" -#include "code\game\gamemodes\nations\nationsprocs.dm" #include "code\game\gamemodes\nuclear\nuclear.dm" #include "code\game\gamemodes\nuclear\nuclear_challenge.dm" #include "code\game\gamemodes\nuclear\nuclearbomb.dm" @@ -565,7 +569,6 @@ #include "code\game\gamemodes\wizard\spellbook.dm" #include "code\game\gamemodes\wizard\wizard.dm" #include "code\game\jobs\access.dm" -#include "code\game\jobs\job_controller.dm" #include "code\game\jobs\job_exp.dm" #include "code\game\jobs\job_objective.dm" #include "code\game\jobs\job_scaling.dm" @@ -830,6 +833,7 @@ #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\floor_painter.dm" +#include "code\game\objects\items\devices\handheld_defib.dm" #include "code\game\objects\items\devices\instruments.dm" #include "code\game\objects\items\devices\laserpointer.dm" #include "code\game\objects\items\devices\lightreplacer.dm" @@ -1104,6 +1108,7 @@ #include "code\game\turfs\unsimulated\floor.dm" #include "code\game\turfs\unsimulated\walls.dm" #include "code\game\verbs\ooc.dm" +#include "code\game\verbs\randomtip.dm" #include "code\game\verbs\suicide.dm" #include "code\game\verbs\who.dm" #include "code\js\byjax.dm" @@ -1136,6 +1141,7 @@ #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" #include "code\modules\admin\tickets\adminticketsverbs.dm" +#include "code\modules\admin\tickets\mentorticketsverbs.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" @@ -1734,7 +1740,6 @@ #include "code\modules\mob\living\carbon\human\logout.dm" #include "code\modules\mob\living\carbon\human\npcs.dm" #include "code\modules\mob\living\carbon\human\say.dm" -#include "code\modules\mob\living\carbon\human\shock.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\update_stat.dm" @@ -1839,7 +1844,6 @@ #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" -#include "code\modules\mob\living\simple_animal\pony.dm" #include "code\modules\mob\living\simple_animal\posessed_object.dm" #include "code\modules\mob\living\simple_animal\powers.dm" #include "code\modules\mob\living\simple_animal\shade.dm" diff --git a/sound/effects/new_siren.ogg b/sound/effects/new_siren.ogg new file mode 100644 index 00000000000..24c4ecca9a1 Binary files /dev/null and b/sound/effects/new_siren.ogg differ diff --git a/sound/effects/powerloss.ogg b/sound/effects/powerloss.ogg new file mode 100644 index 00000000000..9a0835ecdb6 Binary files /dev/null and b/sound/effects/powerloss.ogg differ diff --git a/sound/music/title2.ogg b/sound/music/title2.ogg index af8cc5caae1..7b58ab60e4d 100644 Binary files a/sound/music/title2.ogg and b/sound/music/title2.ogg differ diff --git a/strings/chemistry_tools.json b/strings/chemistry_tools.json index 4a079102a69..5bf45fc6e58 100644 --- a/strings/chemistry_tools.json +++ b/strings/chemistry_tools.json @@ -468,6 +468,7 @@ "prions", "spidereggs", "concentrated_initro", - "heartworms" + "heartworms", + "bacon_grease" ] } diff --git a/strings/sillytips.txt b/strings/sillytips.txt new file mode 100644 index 00000000000..cf49a79c0c7 --- /dev/null +++ b/strings/sillytips.txt @@ -0,0 +1,32 @@ +Occasionally the tip of the round might lie to you. Don't panic, this is normal. +To defeat the slaughter demon, shoot at it until it dies. +Sometimes you won't be able to avoid dying no matter how good you are at the game. Try not to stress too much about it. +When a round ends nearly everything about it is lost forever, leave your salt behind with it. +Just like real life the entropy of the game can only increase with time. If things aren't on fire yet, just wait. +Completing your objectives is good practice, but the best antagonists will strive to do more than the bare minimum to really leave an impression. +The more obscure and underused a game mechanic is, the less likely your victims are to be able to deal with it. +Space is cold and it will quickly freeze you to death if you don't protect yourself. This isn't how thermodynamics really works but just go with it. +Cleanbot. +Sometimes a round will just be a bust. C'est la vie. +This is a game that is constantly being developed for. Expect things to be added, removed, fixed, and broken on a daily basis. +It's fun to try and predict the round type from the tip of the round message. +The quartermaster is not a head of staff and will never be one. +Your sprite represents your hitbox, so that afro makes you easier to kill. The sacrifices we make for style. +Sometimes admins will just do stuff. Roll with it. +The remake will never come out. +Plenty of things that aren't traditionally considered weapons can still be used to slowly brutalize someone to death, get creative! +DEATH IS IMMINENT! +This game is older than most of the people playing it. +Flashbangs can weaken blob tiles, allowing for you and the crew to easily destroy them. +Some people are unable to read text on a game where half of it is based on text. +There are many ways to get through plastic flaps. How many can you name? +Nanotrasen is always watching. +Most items have names longer than "soap". +Ask and you shall receive. +As a Scientist, getting drunk just enough will speed up research. Skol! +Poly speaks truth +Absolutely nothing unusual will happen this shift. Promise. +Send help. Trapped in tip writing factory. +There is no such thing as a cow level. +HONK. +Solars probably gives radiation poisoning or something, considering the other power sources are deadly in their own ways. \ No newline at end of file diff --git a/strings/tips.txt b/strings/tips.txt new file mode 100644 index 00000000000..5237b9ab547 --- /dev/null +++ b/strings/tips.txt @@ -0,0 +1,205 @@ +Where the space map levels connect is randomized every round, but are otherwise kept consistent within rounds. +You can catch thrown items by toggling on your throw mode with an empty hand active. +To crack the safe in the vault, use a stethoscope or thermal drill. +You can climb onto a table by dragging yourself onto one. This takes some time. Clicking on a table that someone else is climbing onto will knock them down. +You can drag other players onto yourself to open the strip menu, letting you remove their equipment or force them to wear something. Note that exosuits or helmets will block your access to the clothing beneath them, and that certain items take longer to strip or put on than others. +Clicking on a windoor rather than bumping into it will keep it open. You can click it again to close it. +You can spray a fire extinguisher, throw items, or fire a gun while floating through space to change your direction. Simply fire in the opposite direction of where you want to go. +You can change the control scheme by pressing tab. One uses WASD for movement, while the other uses the arrow keys. Keep in mind that hotkeys are also changed with this. +Firesuits and winter coats offer mild protection from the cold, allowing you to spend longer periods of time near breaches and space than if wearing nothing at all. +Glass shards can be welded to make glass, and metal rods can be welded to make metal. Ores can be welded too, but this takes a lot of fuel. +If you need to drag multiple people either to safety or to space, bring a locker over and stuff them all in before hauling them off. +You can grab someone by clicking on them with the grab intent, then upgrade the grab by clicking on them once more. An aggressive grab will momentarily stun someone, allow you to place them on a table by clicking on it, or throw them by toggling on throwing. +Holding alt and left clicking a tile will allow you to see its contents in the top right window pane, which is much faster than right clicking. +The resist button will allow you to resist out of handcuffs, being buckled to a chair or bed, out of locked lockers and more. Whenever you're stuck, try resisting! +You can move an item out of the way by dragging it and then clicking on an adjacent tile with an empty hand. +You can recolor certain items like jumpsuits and gloves in washing machines by also throwing in a crayon. +Maintenance is full of equipment that is randomized every round. Look around and see if anything is worth using. +Some roles cannot be antagonists by default, but antag selection is decided first. For instance, you can set Security Officer to High without affecting your chances of becoming an antag -- the game will just select a different role. +There are many places around the station to hide contraband. A few for starters: linen boxes, toilet cisterns, body bags. Experiment to find more! +When in doubt about technicial issues, clear your cache (byond launcher > cogwheel > preferences > game prefs), update your BYOND, and relog. +Most things have special interactions with your middle mouse button, alt, shift, and control click. Experiment! +If you find yourself in a fistfight with another player, running away and calling for help is a perfectly viable option. +Different weapons have different strengths. Some weapons, such as spears, floor tiles, and throwing stars, deal more damage when thrown compared to when attacked normally. +A thrown glass of water can make a slippery tile, allowing you to slow down your pursuers in a pinch. +When dealing with security, you can often get your sentence negated entirely through cooperation and deception. +The P2P chat function found on tablet computers allows for a stealthy way to communicate with people. +We were all new once, be patient and guide new players in the right direction. +On most clothing items that go in the exosuit slot, you can put certain small items into your suit storage, such as a spraycan, your emergency oxygen tank, or a flashlight. +Most job-related exosuit clothing can fit job-related items into it. For example, the atmospheric technician's hardsuit/winter coat can hold an RPD, and labcoats can hold most medicine. +If there's something you need from another department, try asking! This game isn't singleplayer and you'd be surprised what you can get accomplished together! +You'll quickly lose your interest in the game if you play to win and kill. If you find yourself doing this, take a step back and talk to people - it's a much better experience! +Don't be afraid to ask for help, whether from your peers or from mentors. +As the Captain, you are one of the highest priority targets on the station. Everything from nuclear operatives to traitors that need to rob you of your unique lasergun or your life are things to worry about. +As the Captain, always take the nuclear disk and pinpointer with you every shift. It's a good idea to give one of these to another head or Blueshield you can trust with keeping it safe. +As the Captain, you have absolute access and control over the station, but this does not mean that being a horrible person won't result in mutiny and a ban. +As the Chief Medical Officer, your hypospray is like a refillable instant injection syringe that can hold 30 units and the unlike standard hypospray, yours is able to be filled with harmful reagents and injects without telling anyone what have you exactly injected the person with. +As the Chief Medical Officer, coordinate and communicate with your doctors, chemists, and geneticists during a nuclear emergency, blob infestation, or some other crisis to keep people alive and fighting. +As a Medical Doctor, you can surgically implant or extract things from people's chests. This can range from putting in a bomb to pulling out an alien larva. +As a Medical Doctor, you must target the correct limb and be on help intent when trying to perform surgery on someone. Using disarm intent will intentionally fail the surgery step. +As a Medical Doctor, corpses with the "...and their soul has departed" description no longer have a ghost attached to them and aren't revivable or clonable. +As a Medical Doctor, treating plasmamen is not impossible! Salbutamol stops them from suffocating and showers stop them from burning alive. You can even perform surgery on them by doing the procedure on a roller bed under a shower. +As a Chemist, there are dozens of chemicals that can heal, and even more that can cause harm. Experiment! +As a Chemist, some chemicals can only be synthesized by heating up the contents with a chemical heater or manually with lighters and similar tools. +As a Chemist, you will be expected to supply crew with certain chemicals. For example, cryoxadone and mannitol for the cryo tubes, unstable mutagen and saltpetre for botany as well as healing pills and patches for the front desk. +As a Chemist, Water and Potassium mixed together will create an explosion, with power scaling by amount used. Don't do it. +As a Geneticist, you can eject someone from cloning early by disabling power in genetics. Note that they will suffer more genetic damage and may lose vital organs from this. +As a Geneticist, becoming a hulk makes you capable of dealing high melee damage, stunlocking people, and punching through walls. However, you can't fire guns, will lose your hulk status if you go into critical condition. Being hulk also does not allow you to break any server rules and go berserk as non-antagonist. +As the Virologist, your viruses can range from healing powers so great that you can heal out of critical status, to diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment! +As the Research Director, you can take AIs out of their cores by loading them into an intelliCard, which lets you see their laws, even ion/syndicate ones. It can then be placed into an AI system integrity restorer computer to revive and/or repair them. +As the Research Director, you can lock down cyborgs instead of blowing them up. Then you can have their laws reset or if that doesn't work, safely dismantled. +As the Research Director, you can spy on and even forge PDA communications with the message monitor console! The key is in your office. +As a Scientist, you can maximize the number of uses you get out of a slime by feeding it slime steroid, created from purple slimes, while alive. You can then apply extract enhancer, created from cerulean slimes, on each extract. +As a Scientist, you can disable anomalies by scanning them with an analyzer, then send a signal on the frequency it gives you with a remote signaling device, or if researched, hit the anomaly with an anomaly analyzer. This will leave behind an anomaly core, which can be used to construct a Phazon mech or reactive armors! +As a Scientist, researchable stock parts can seriously improve the efficiency and speed of machines around the station. In some cases, it can even unlock new functions. +As a Roboticist, keep an ear out for anomaly announcements. If you get your hands on an anomaly core, you can build a Phazon mech! +As a Roboticist, you can repair your cyborgs with a welding tool. If they have taken burn damage, you can remove their battery, expose the wiring with a screwdriver and replace their wires with a cable coil. +As a Roboticist, you can reset a cyborg's module by cutting and mending the reset wire with a wire cutter or using a cyborg reset module. +As a Roboticist, you can augment people with cyborg limbs. Augmented limbs can easily be repaired with cables and welders. +As the AI, you can click on people's names to look at them. This only works if there are cameras that can see them, they aren't wearing agent IDs, or aren't using digital camouflage as changelings. +As the AI, you can quickly open and close doors by holding shift while clicking them, bolt them when holding ctrl, and even shock them while holding alt. +As the AI, you can take pictures with your camera and upload them to newscasters. +As a Cyborg, choose your module carefully, as only cutting and mending your reset wire or using a cyborg reset module will let you repick it. If possible, refrain from choosing a module until a situation that requires one occurs. +As a Cyborg, you are immune to most forms of stunning, and excel at almost everything far better than humans. However, flashes can easily stunlock you and you cannot do any precision work as you lack hands. +As a Cyborg, you are impervious to fires and heat. If you are rogue, you can release plasma fires everywhere and walk through them without a care in the world! +As a Cyborg, you are extremely vulnerable to EMPs as EMPs both stun you and damage you. The ion rifle in the armory or a traitor with an EMP kit can kill you in seconds. +As an Engineering Cyborg, you can attach air alarm/fire alarm/APC frames to walls by placing them on the floor and using a screwdriver on them. +As a Medical Cyborg, you can fully perform surgery and even augment people. +As a Janitor Cyborg, you are the bane of all slaughter demons. Cleaning up blood stains will severely gimp them. +As the Chief Engineer, you can rename areas or create entirely new ones using your station blueprints. +As the Chief Engineer, your hardsuit is significantly better than everybody else's. It has the best features of both engineering and atmospherics hardsuits, boasting nigh-invulnerability to radiation and all atmospheric conditions. +As the Chief Engineer, the power flow control console in your office will show you APC infos and lets you control them remotely. +As an Engineer, you can electrify grilles by placing wire "nodes" beneath them: the big seemingly unconnected bulges from a half completed wiring job. The wire will be need to be connected to an active power source in order to function. +As an Engineer, return to Engineering once in a while to check on the engine and SMES cells. It's always a good idea to make sure containment isn't compromised. +As an Engineer, you can power the station solely with the solar arrays. They will provide just enough electricity to power the station, however their output is still much worse compared to the true engine. +As an Engineer, you can cool a supermatter shard by spraying it with a fire extinguisher. Only for the brave! +As an Engineer, you can repair windows by using a welding tool on them while on any intent other than harm. +As an Engineer, you can lock APCs, fire alarms, emitters, and radiation collectors using your ID card to prevent others from disabling them. +As an Engineer, don't underestimate the humble P.A.C.M.A.N. generators. With upgraded parts, a couple units working in tandem are sufficient to take over for an exploded engine or shattered solars. +As an Engineer, you can pry open secure storage blast doors by disabling the engine room APC's main breaker. This is obviously a bad idea if the engine is running. +As an Atmospheric Technician, look into replacing your gas pumps with volumetric gas pumps, as those move air in flat numerical amounts, rather than percentages which leave trace gases. +As an Atmospheric Technician, you are better suited to fighting fires than anyone else. As such, you have access to better firesuits, backpack firefighter tanks, and a completely heat and fire proof hardsuit. +As an Atmospheric Technician, your backpack firefighter tank can launch cryofrost. This resin will extinguish fires and very quickly; it's ideal for plasma fires! +As an Atmospheric Technician, your ATMOS holofan projector blocks gases while allowing objects to pass through. With it, you can quickly contain gas spills, fires and hull breaches. Or, use it to seal a plasmaman cloning room. +As the Head of Security, you are expected to coordinate your security force to handle any threat that comes to the station. Sometimes it means making use of the armory to handle a blob, sometimes it means being ruthless during a vampire or cult incursion. +As the Head of Security, don't let the power go to your head. You may have high access, great equipment, and a miniature army at your side, but being a terrible person without a good reason is grounds for banning. +As the Warden, your duty is to be the watchdog of the brig and handler of prisoners when little is happening, and to hand out equipment and weapons to the security officers when a crisis strikes. +As the Warden, keep a close eye on the armory at all times, as it is a favored strike point of nuclear operatives and cocky traitors. +As the Warden, if a prisoner's crimes are heinous enough you can put them in permabrig or the gulag. Make sure to check on them once in a while! +As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals. +As a Security Officer, communicate and coordinate with your fellow officers using the security channel (:s) to avoid confusion. +As a Security Officer, your sechuds or HUDsunglasses can not only see crewmates' job assignments and criminal status, but also if they are mindshield implanted. You can tell by the flashing blue outline around their job icon. +As a Security Officer, mindshield implants can only prevent someone from being turned into a cultist. It will not de-cult them if they have already been converted. +As a Security Officer, examining someone while wearing sechuds or HUDsunglasses will let you set their arrest level, which will cause Beepsky and other security bots to chase after them. +As the Detective, keep in mind that people leave fingerprints everywhere and on everything. With the exception of white latex, gloves will hide them. All is not lost, however, as gloves leave fibers specific to their kind such as black or nitrile, pointing to a general department. +As the Detective, you can use your forensics scanner from a distance. +As the Detective, your revolver can be modified to load .357 ammunition obtained from a hacked autolathe. Firing it has a decent chance to blow up your revolver. +As the IAA, try to negotiate with the Warden if sentences seem too high for the crime. +As the IAA, you can try to convince the Captain and Head of Security to hold trials for prisoners in the courtroom. +As the Head of Personnel, you are not higher ranking than other heads of staff, even though you are expected to take the Captain's place first should he go missing. If the situation seems too rough for you, consider allowing another head to become temporary Captain. +As the Head of Personnel, you are just as large a target as the Captain because of the potential power your ID and computer can hand out. +As the Head of Personnel, consider getting a laptop with an ID slot. It allows you to do your job even when out of your office. +As the Mime, your invisible wall power blocks people as well as projectiles. You can use it in a pinch to delay your pursuer. +As the Mime, your oath of silence is your source of power. Breaking it robs you of your powers and of your honor. +As the Clown, if you lose your banana peel, you can still slip people with your PDA! Honk! +As the Clown, your Grail is the mineral bananium, which can be given to the Roboticist to build you a fun and robust mech beloved by everyone. +As the Clown, you can use your stamp on a sheet of cardboard as the first step of making a honkbot. Fun for the whole crew! +As the Clown, spice your gimmicks up! Nobody likes a one-trick pony. +As the Chaplain, your null rod has anti magic functions: it can destroy cultist runes by hitting them, and it makes you immune to cult magic. +As the Chaplain, your bible is also a container that can store small items. +As the Chaplain, you are much more likely to get a response by praying to the gods than most people. To boost your chances, perform blessings, make altars with colorful crayon runes, lit candles, and wire art. +As a Botanist, you can hack the MegaSeed Vendor to get access to more exotic seeds. These seeds can alternatively be ordered from cargo. +As a Botanist, you can mutate the plants growing in your hydroponics trays with unstable mutagen or, as an alternative, crude radioactives from chemistry to get special variations. +As a Botanist, you should look into increasing the potency of your plants. This increases the size, amount of chemicals, points gained from grinding them in the biogenerator, and lets people know you are a proficient botanist. +As a Botanist, you can combine production trait chemicals just like a Chemist. Chlorine (blumpkin) + radium and phosphorus (glowshrooms) equals unstable mutagen! +As the Chef, you can create a very wide variety of food with the crafting menu. You can find it by looking for the hammer icon near your intents. +As the Chef, you can rename your custom made food with a pen. +As the Chef, if you are low on ingredients, consider making something that has several servings to last longer among the crew. +As the Bartender, you can use a circular saw on your shotgun to make it easier to store. +As a Janitor, if someone steals your janicart, you can instead use your space cleaner spray, grenades, water sprayer or order another from Cargo. +As a Janitor, mousetraps can be used to create bombs or booby-trap containers. +As the Librarian, be sure to keep the shelves stocked and the library clean for crew. +As a Cargo Technician, you can hack MULEbots to make them faster, run over people in their way, and even let you ride them! +As a Cargo Technician, you can order contraband items from the supply shuttle console by de-constructing it and using a multitool on the circuit board, the re-assembling it. +As a Cargo Technician, you can earn more cargo points by shipping back crates from maintenance, liquid containers, plasma sheets, rare seeds from hydroponics, and more! +As a Shaft Miner, the western side of the Asteroid has a lot more rare minerals than on the east, but is a lot more dangerous. +As a Shaft Miner, always have a GPS on you, so a fellow miner or cyborg can come to save you if you die. +As a Traitor, the cryptographic sequencer (emag) can not only open doors, but also lockers, crates, APCs and more. It can hack cyborgs, and even cause bots to go berserk. Use it on the right machines, and you can even order more traitor gear or contact the Syndicate. Experiment! +As a Traitor, subverting the AI to serve you can make it an extremely powerful ally. However, be careful of the wording in the laws you give it, as it may use your poorly written laws against you! +As a Traitor, the Captain and the Head of Security are two of the most difficult to kill targets on the station. If either one is your target, plan carefully. +As a Traitor, you can manufacture and recycle revolver bullets at a hacked autolathe, making the revolver an extremely powerful tool. +As a Traitor, you may sometimes be assigned to hunt other traitors, and in turn be hunted by others. +As a Traitor, the syndicate encryption key is very useful for coordinating plans with your fellow traitors -- or, of course, betraying them. +As a Traitor, plasma can be injected into many things to sabotage them. Power cells, light bulbs, welding tools, cigars and e-cigs will all explode when used. +As a Traitor, if you can find another Traitor and pool your TC you can buy a mega surplus crate, which costs 40TC but contains a lot of random syndicate gear. +As a Nuclear Operative, communication is key! Use ; to speak to your fellow operatives and coordinate an attack plan. +As a Nuclear Operative, you should look into purchasing a syndicate cyborg, as they can provide heavy fire support, full access, are immune to conventional stuns, and can easily take down the AI. +As a Nuclear Operative, stick together! While your equipment is robust, your fellow operatives are much better at saving your life: they can drag you away from danger while stunned and provide cover fire. +As a Nuclear Operative, you might end up in a situation where the AI has bolted you into a room. Having some spare C4 in your pocket can save your life. +As a Monkey, you can still wear a few human items, such as backpacks, gas masks, and hats, and still have two free hands. +As the Malfunctioning AI, you can shunt to an APC if the situation gets bad. This disables your doomsday device if it is active. +As the Malfunctioning AI, you should either order your cyborgs to dismantle the robotics console or blow it up yourself in order to protect them. +As an Alien, your melee prowess is unmatched, but your ranged abilities are sorely lacking. Make use of corners to force a melee confrontation! +As an Alien, you take double damage from all burn attacks, such as lasers, welding tools, and fires. Furthermore, fire can destroy your resin and eggs. Expose areas to space to starve away any flamethrower fires before they can do damage! +As an Alien, resin floors not only regenerate your plasma supply, but also passively heal you. Fight on resin floors to gain a home turf advantage! +As an Alien, the facehugger is by far your most powerful weapon because of its ability to instantly win a fight. Remember however that certain helmets, such as biohoods or space helmets will completely block facehugger attacks. +As an Alien, you are unable to pick up or use any human items or machinery. Instead, you should focus on sabotaging APCs, computers, cameras and either stowing, spacing, or melting any weapons you find. +As the Blob, keep your core some distance from space, as it is both expensive to expand onto space, easy to be attacked from, and does not count towards your win condition. Emitter platforms built in space are especially dangerous. +As the Blob, you can randomly repick your reagent type if the crew has adapted and protected themselves against your current one. +As the Blob, you fight a war of attrition: Take out medbay and fight in chokepoints to prevent continued assaults and coordinated burst damage attacks! +As the Blob, don't neglect the creation of factories. These create spores that carry your reagent and can chase crewmembers far further than you. Spores can also be rallied to swarm the crew and cause panic, and can even take over corpses to create much more dangerous blob zombies! +As the Blob, you can expand by clicking, create strong blobs with ctrl-click, rally spores with middle-click, and remove blobs with alt-click. You do not need to have your camera over the tile to do this. +As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you some resources back as refund. +As the Blob, talking will send a message to all other overminds, allowing you to direct attacks and coordinate. +As a Changeling, the Extract DNA sting counts for your genome absorb objective, but does not let you respec your powers. +As a Changeling, you can absorb someone by strangling them and using the Absorb verb; this gives you the ability to rechoose your powers, the DNA of whoever you absorbed, the memory of the absorbed, and some samples of things the absorbed said. +As a Cultist, do not cause too much chaos before your objective is completed. If the shuttle gets called too soon, you may not have enough time to win. +As a Cultist, your team starts off very weak, but if necessary can quickly convert everything they have into raw power. Make sure you have the numbers and equipment to support going loud, or the cult will fall flat on its face. +As a Cultist, the Blood Boil rune will deal massive amounts of brute damage to non-cultists, and some damage to fellow cultists of Nar'Sie nearby, but will create a fire where the rune stands on use. +As a Cultist, you can create an army of manifested goons using a combination of the Manifest rune, which creates homunculi from ghosts, and the Blood Drain rune, which drains life from anyone standing on any blood drain rune. +As a Cultist, check the alert in the upper-right of your screen for all the details about your cult's current status and objective. +You can deconvert Cultists by feeding them large amounts of holy water. +The Chaplain can bless any container with water by hitting it with their bible. Holy water has a myriad of uses against both cults and large amounts of it are a great contributor to success against them. +As a Wizard, you can turn people to stone, then animate the resulting statue with a staff of animation to create an extremely powerful minion, for all of 5 minutes at least. +As a Wizard, the fireball spell performs very poorly at close range, as it can easily catch you in the blast. It is best used as a form of artillery down long hallways. +As a Wizard, summoning guns will give everyone anything from a floral somatoray to a pulse rifle. Use at your own risk! +As a Wizard, the staff of chaos can fire any type of bolts from the magical wands. This can range from bolts of instant death to healing or reviving someone. +As a Wizard, most spells become unusable if you are not wearing your robe, hat, and sandals. +As an Abductor, you can select where your victims will be sent on the ship control console. +As an Abductor Agent, the combat mode vest has much higher resistance to every kind of weapon, and your helmet prevents the AI from tracking you. +As an Abductor, the baton can cycle between four modes: stun, sleep, cuff and probe. +As a Revenant, the Chaplain is your worst enemy, as they can damage you massively with the null rod and make large swaths of the station impassable with holy water. +As a Revenant, your essence is also your health, so revealing yourself in front of humans to harvest the essence of the living is much safer if you've already stocked up on essences from poorly guarded corpses. +As a Revenant, your Defile ability removes holy water from tiles in a small radius, along with salt, allowing you to reclaim the station from the chaplain if they've been covering the station in holy water. It can also be used to open morgue trays! +As a Revenant, your Overload Lights ability will only shock humans with lights if the lights are still on after a brief delay. +As a Revenant, your Malfunction ability in general damages machinery and mechanical objects, possibly even emagging some objects. Experiment! +As a Revenant, the illness inflicted on humans by Blight can be easily cured by lying down or with holy water, making it best used on targets that have no time to lie down, such as humans in combat. +As a Revenant, fastmos is your friend. Breaking windows to space can cause massive damage and mayhem. +As a Swarmer, you can deconstruct more things than you think. Try deconstructing light switches, buttons, air alarms and more. Experiment! +As a Swarmer, you can teleport fellow swarmers away if you think they are in danger. +As a Ghost, you can double click on just about anything to follow it. Or just warp around! +As a Devil, you gain power for every three souls you control, however you also become more obvious. +As a Devil, as long as you control at least one other soul, you will automatically resurrect, as long as a banishment ritual is not performed. +At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. +As a Security Officer, remember that correlation does not equal causation. Someone may have just been at the wrong place at the wrong time! +As a Security Officer, remember that you can attach a sec-lite to your taser or your helmet! +As a Terror Spider, leave wrapping of corpses to green spiders unless absolutely necessary. They need it to lay eggs! +As a Prince of Terror, you are powerful but usually on your own. Consider hit and run tactics to regenerate your health between engagements. +As a Brown Terror Spider, focus on smashing welded vents. You are weak in direct combat, but you can enable your comrades to go almost anywhere. +As a Terror Spider, protect the queen at all cost! +As a Terror Spider, don't forget you can move your nest if the crew is pressuring you too badly. +As a Terror Spider, try putting webs on white floor tiles, they are much harder to see there. +As a Terror Spider, sometimes quickly pulling an enemy into a web can ensure victory in melee combat. +You can swap floor tiles by holding a crowbar in one hand and a stack of tiles in the other. +When hacking doors, cutting and mending a "test light wire" will restore power to the door. +When crafting most items, you can either manually combine parts or use the crafting menu. +Suit storage units not only remove blood and dirt from clothing, but also radiation! +Sleeping in a bed can heal minor amounts of brute and burn damage. +The Experimentor has a chance to spawn hostile mobs. Be ready to run for your life when using it. +Space ruins can contain all kinds of interesting goodies, even a wand that can raise the dead! +Having a mindshield, or having an agent ID card will make officer Beepsky consider you less arrest-worthy. +You can make lasertag turrets, for the ultimate lasertag tournament. +Blob structures take half damage from brute damage. Use lasers. +You can hide paper in vents, but you have to use a screwdriver to open it first. +While the Standard Operating Procedures aren't fully rules, they are there for safety and professional reasons. +Killing the Wizard usually ends the round, unless they are a lich or Space Wizard Federation is RAGING. \ No newline at end of file