diff --git a/.github/workflows/compile_changelogs.yml b/.github/workflows/compile_changelogs.yml index 141fc9a7d8..f8098df66e 100644 --- a/.github/workflows/compile_changelogs.yml +++ b/.github/workflows/compile_changelogs.yml @@ -17,6 +17,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install pyyaml + sudo apt-get install dos2unix - name: "Checkout" uses: actions/checkout@v1 with: @@ -24,6 +25,9 @@ jobs: - name: "Compile" run: | python tools/ss13_genchangelog.py html/changelog.html html/changelogs + - name: "Convert Lineendings" + run: | + unix2dos html/changelogs/.all_changelog.yml - name: Commit run: | git config --local user.email "action@github.com" diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm index d028ac106f..cfc9e5f4ce 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm @@ -265,12 +265,6 @@ /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 1 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, /obj/machinery/light/small{ dir = 1 }, @@ -299,9 +293,6 @@ /obj/machinery/atmospherics/pipe/manifold/green/visible{ dir = 1 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors) "ba" = ( @@ -945,10 +936,6 @@ /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors) "cO" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, /obj/machinery/light/small, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors) @@ -963,9 +950,6 @@ /obj/machinery/atmospherics/pipe/simple/dark/visible{ dir = 9 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors) "cR" = ( @@ -1218,6 +1202,10 @@ }, /turf/open/floor/plating/icemoon, /area/icemoon/surface/outdoors) +"xh" = ( +/mob/living/simple_animal/hostile/bear/snow, +/turf/open/floor/plating/snowed/smoothed/icemoon, +/area/icemoon/surface/outdoors) "CR" = ( /obj/structure/cable{ icon_state = "0-8" @@ -1279,17 +1267,17 @@ aa ak an ak -ae +ak an ab aa by bQ bQ +aO ae -ae -ae -ae +ak +ak ae aO aa @@ -1564,28 +1552,28 @@ al al al ds -ae +aO aa "} (16,1,1) = {" -ae -ae -ae -ae +aO +aO ae ae ae aO +ae +aO bi ae +aO ae ae +aO ae +aO ae -ae -ae -ae -ae +aO aa "} (17,1,1) = {" @@ -1599,7 +1587,7 @@ ae aL bb bD -ae +aO aa aa aa @@ -1634,9 +1622,9 @@ aa af aa aa -aa +ak an -aB +dj ae aP bk @@ -1644,7 +1632,7 @@ aP ae aB aB -aB +dj aB aB aB @@ -1689,7 +1677,7 @@ aB cE ab cY -aB +dj aa aa "} @@ -1700,7 +1688,7 @@ af ab ab ab -ab +xh ab bj ab @@ -1710,7 +1698,7 @@ aP cH ab de -aB +dj aa aa "} @@ -1826,7 +1814,7 @@ aa aa an an -aB +dj ae bj bH @@ -1872,7 +1860,7 @@ aa ae bq bH -ae +aO aa aa aa @@ -1895,9 +1883,9 @@ bq bJ ae ae +aO ae -ae -ae +aO aa aa aa @@ -1918,10 +1906,10 @@ bZ ck cs cL +aO ae ae -ae -ae +aO aa "} (33,1,1) = {" @@ -1973,7 +1961,7 @@ aa ae ae ae -ae +aO aW bu bN @@ -1982,9 +1970,9 @@ cn cv cO ae -ae -ae -ae +aO +aO +aO aa "} (36,1,1) = {" @@ -2034,8 +2022,8 @@ aa aa aa ae -ae -ae +aO +aO ae aZ bu @@ -2045,9 +2033,9 @@ cd cy cQ ae -ae -ae -ae +aO +aO +aO aa "} (39,1,1) = {" @@ -2079,14 +2067,14 @@ aa aa aa ae +aO +aO ae ae ae +aO ae -ae -ae -ae -ae +aO aa aa aa diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm index 908363dd86..35eb1901f6 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm @@ -198,6 +198,9 @@ /obj/structure/toilet{ dir = 1 }, +/mob/living/simple_animal/hostile/skeleton/eskimo{ + name = "Village Hunter" + }, /turf/open/floor/plating, /area/ruin/powered) "sY" = ( @@ -216,6 +219,9 @@ /area/icemoon/underground/explored) "tt" = ( /obj/effect/decal/cleanable/dirt, +/mob/living/simple_animal/hostile/skeleton/eskimo{ + name = "Village Hunter" + }, /turf/open/floor/plasteel/freezer, /area/ruin/powered) "tF" = ( @@ -415,6 +421,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet, /area/ruin/powered) +"IT" = ( +/mob/living/simple_animal/hostile/skeleton/eskimo{ + name = "Village Hunter" + }, +/turf/open/floor/wood, +/area/ruin/powered) "Kd" = ( /obj/structure/flora/grass/green, /turf/open/floor/plating/asteroid/snow/icemoon, @@ -816,7 +828,7 @@ tF ac Vn AG -aM +IT yb Vn wQ diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index b4abf9b535..80ad86e3c5 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -476,7 +476,7 @@ }, /obj/item/storage/bag/plants/portaseeder, /obj/item/seeds/cotton, -/obj/item/seeds/cotton, +/obj/item/seeds/cotton/durathread, /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) "bk" = ( diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index f5af8b517b..879be286a3 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -4127,13 +4127,12 @@ /turf/open/floor/plasteel, /area/security/main) "ahO" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 - }, /obj/structure/chair/sofa/left{ dir = 1 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ahP" = ( @@ -13863,8 +13862,7 @@ /area/crew_quarters/dorms) "aFk" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 + dir = 4 }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -14364,13 +14362,12 @@ /turf/closed/wall, /area/crew_quarters/theatre) "aGw" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4; - pixel_y = 5 - }, /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/wood, /area/crew_quarters/bar) "aGx" = ( @@ -15021,10 +15018,6 @@ /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aHV" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1; - pixel_x = 5 - }, /obj/machinery/light/small{ dir = 4 }, @@ -15037,6 +15030,9 @@ /obj/item/reagent_containers/rag/towel/random, /obj/item/reagent_containers/rag/towel/random, /obj/item/reagent_containers/rag/towel/random, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/toilet) "aHY" = ( @@ -16644,10 +16640,6 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/structure/sign/poster/contraband/robust_softdrinks{ - pixel_x = -32; - pixel_y = 32 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aMh" = ( @@ -17870,7 +17862,6 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/status_display/evac, /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ id = "bridge blast"; @@ -17895,21 +17886,6 @@ }, /turf/open/floor/plating, /area/bridge) -"aPW" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/status_display/evac, -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - id = "bridge blast"; - name = "bridge blast door" - }, -/turf/open/floor/plating, -/area/bridge) "aPX" = ( /obj/structure/cable{ icon_state = "0-8" @@ -19084,6 +19060,7 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/port) "aSY" = ( @@ -48879,8 +48856,8 @@ "cpn" = ( /obj/machinery/light, /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/engine_smes) @@ -53762,6 +53739,10 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/range) +"dZm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/storage/art) "eaI" = ( /obj/structure/table/reinforced, /obj/item/radio/intercom{ @@ -55075,8 +55056,8 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 }, /turf/closed/wall, /area/quartermaster/warehouse) @@ -55912,6 +55893,10 @@ /area/maintenance/fore/secondary) "khV" = ( /obj/machinery/vending/cola/red, +/obj/structure/sign/poster/contraband/robust_softdrinks{ + pixel_x = -32; + pixel_y = 32 + }, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) "kls" = ( @@ -57544,6 +57529,9 @@ /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/wood, /area/crew_quarters/bar) "plS" = ( @@ -58369,6 +58357,10 @@ }, /turf/open/floor/plasteel, /area/science/mixing) +"rNG" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/ai_monitored/storage/eva) "rPU" = ( /turf/open/floor/plasteel/white/side{ dir = 4 @@ -59444,11 +59436,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "uQS" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1; - pixel_x = 5 - }, /obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/toilet) "uRd" = ( @@ -60797,6 +60788,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"yeA" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/hallway/primary/central) "yhx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 @@ -78938,7 +78933,7 @@ blW blW bqi cyD -blW +aZE cyD bvS blW @@ -81490,7 +81485,7 @@ aPF aQZ aRa aTF -aPG +dZm aSX hPP aZF @@ -87907,7 +87902,7 @@ ayL ayW ayW ayW -ayW +rNG aJq aJq aOE @@ -90481,7 +90476,7 @@ aKF aMf aNB aOE -aPW +aPS aRr aSD ceh @@ -91505,7 +91500,7 @@ gfD woR dgz aJw -aJw +yeA aMh aJq aOE diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index ebb3493a35..b3aad634c5 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -17073,7 +17073,7 @@ /area/security/brig) "aLl" = ( /obj/effect/turf_decal/delivery, -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /turf/open/floor/plasteel, /area/hallway/primary/port/fore) "aLm" = ( @@ -28450,7 +28450,7 @@ /turf/open/floor/plasteel, /area/quartermaster/warehouse) "bjN" = ( -/obj/machinery/vending/autodrobe/all_access, +/obj/machinery/vending/autodrobe, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/quartermaster/office) @@ -72362,6 +72362,9 @@ /obj/item/pen, /turf/open/floor/plasteel, /area/engine/atmos) +"xxP" = ( +/turf/closed/wall, +/area/quartermaster/storage) "xCy" = ( /obj/machinery/atmospherics/components/binary/pump, /obj/machinery/atmospherics/pipe/simple/supplymain/hidden{ @@ -121108,7 +121111,7 @@ bgT bjr bkr ble -bgT +xxP bnC boD bgT diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index d1214fe0a0..e5f8c587ab 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -14150,10 +14150,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/quartermaster/storage) -"aEh" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/quartermaster/storage) "aEi" = ( /obj/structure/cable/white{ icon_state = "0-2" @@ -15901,9 +15897,6 @@ /turf/open/floor/plasteel/dark, /area/maintenance/disposal/incinerator) "aGU" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 6 - }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -15918,9 +15911,6 @@ /turf/open/floor/plasteel/dark, /area/maintenance/disposal/incinerator) "aGV" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 10 - }, /obj/structure/cable/white{ icon_state = "2-4" }, @@ -16807,17 +16797,18 @@ /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) "aIu" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ icon_state = "4-8" }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 6 + }, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) "aIv" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, /obj/structure/cable{ icon_state = "4-8" }, @@ -16828,6 +16819,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) "aIw" = ( @@ -18423,10 +18417,10 @@ /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark/corner, /area/maintenance/disposal/incinerator) "aLi" = ( @@ -18440,26 +18434,15 @@ "aLj" = ( /obj/machinery/meter, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark/corner, -/area/maintenance/disposal/incinerator) -"aLk" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Port to Turbine" - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 4 }, /turf/open/floor/plasteel/dark/corner, /area/maintenance/disposal/incinerator) "aLl" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, @@ -19961,13 +19944,15 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, /obj/machinery/embedded_controller/radio/airlock_controller/incinerator_atmos{ pixel_y = 27 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "aNV" = ( @@ -20022,7 +20007,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -20033,6 +20017,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aOa" = ( @@ -20053,7 +20038,6 @@ /area/engine/atmos) "aOb" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/general/visible, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -20096,9 +20080,6 @@ name = "Station Intercom"; pixel_y = 26 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -20112,7 +20093,7 @@ /turf/open/floor/plasteel/dark, /area/engine/atmos) "aOe" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/neutral{ @@ -20125,12 +20106,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aOf" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/engine/atmos) @@ -20141,9 +20120,6 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -20157,9 +20133,6 @@ /turf/open/floor/plasteel/dark, /area/engine/atmos) "aOj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -20177,16 +20150,10 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/engine/atmos) "aOl" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -20204,9 +20171,6 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -21035,9 +20999,6 @@ /turf/open/floor/plasteel/dark/corner, /area/maintenance/disposal/incinerator) "aPD" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -21048,6 +21009,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aPE" = ( @@ -21061,15 +21025,15 @@ /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/item/pen, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -21080,10 +21044,11 @@ pixel_y = 1 }, /obj/structure/tank_dispenser, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/pipe/simple/general/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark/corner{ @@ -21096,10 +21061,10 @@ pixel_y = 1 }, /obj/machinery/computer/atmos_control, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark/corner{ @@ -21112,11 +21077,10 @@ pixel_y = 1 }, /obj/machinery/computer/atmos_alert, -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark/corner{ @@ -21132,10 +21096,10 @@ /obj/item/crowbar/red, /obj/item/wrench, /obj/item/clothing/mask/gas, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/dark/corner{ @@ -21159,16 +21123,19 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ +/obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/checker, /area/engine/atmos) "aPL" = ( /obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aPM" = ( @@ -21184,15 +21151,15 @@ /obj/item/electronics/airalarm, /obj/item/electronics/firealarm, /obj/item/electronics/firealarm, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -21265,7 +21232,6 @@ dir = 8 }, /obj/structure/table/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/item/stack/rods{ amount = 23 }, @@ -22130,9 +22096,6 @@ /turf/open/floor/plating, /area/maintenance/disposal/incinerator) "aRq" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -22143,6 +22106,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aRr" = ( @@ -22173,6 +22139,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "aRt" = ( @@ -22187,15 +22154,21 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aRu" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/effect/turf_decal/stripes/line{ +/obj/item/twohanded/required/kirbyplants/random, +/obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, /area/engine/atmos) "aRv" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ @@ -22210,11 +22183,7 @@ /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, +/turf/closed/wall/r_wall, /area/engine/atmos) "aRx" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ @@ -22265,7 +22234,6 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -22288,9 +22256,6 @@ /turf/open/floor/plasteel/dark, /area/engine/atmos) "aRD" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -22301,6 +22266,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aRE" = ( @@ -23222,7 +23190,6 @@ /turf/open/space, /area/space/nearstation) "aST" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -23233,6 +23200,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aSU" = ( @@ -23246,15 +23214,19 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/checker, -/area/engine/atmos) -"aSV" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 6 }, +/turf/open/floor/plasteel/checker, +/area/engine/atmos) +"aSV" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "aSW" = ( @@ -23278,10 +23250,6 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Port to Turbine" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -23295,24 +23263,11 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aSY" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 4 +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 10 }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Port to Filter" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/space, /area/engine/atmos) "aSZ" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ @@ -23378,7 +23333,6 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -23392,13 +23346,12 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aTd" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 1 - }, -/obj/machinery/meter, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aTe" = ( @@ -23409,17 +23362,16 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Air to Pure" - }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 + }, +/obj/machinery/meter, /turf/open/floor/plasteel/cafeteria, /area/engine/atmos) "aTf" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -23430,6 +23382,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Air to Pure" + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aTg" = ( @@ -23690,7 +23646,10 @@ /area/crew_quarters/bar/atrium) "aTH" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/food/drinks/coffee, +/obj/item/reagent_containers/food/drinks/coffee{ + pixel_x = -4; + pixel_y = 2 + }, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -24567,7 +24526,6 @@ /turf/open/floor/plating, /area/security/prison) "aUL" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/machinery/light/small{ dir = 8 }, @@ -24581,12 +24539,15 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/engine/atmos) -"aUM" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) +"aUM" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -24598,16 +24559,20 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aUN" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "aUO" = ( @@ -24627,21 +24592,11 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aUP" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/layer_manifold{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "aUQ" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ @@ -24651,6 +24606,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/effect/landmark/start/atmospheric_technician, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "aUR" = ( @@ -24715,7 +24671,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -24729,7 +24684,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aUW" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 }, @@ -24746,12 +24700,13 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "aUY" = ( @@ -25865,16 +25820,13 @@ /area/engine/atmos) "aWy" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/atmos) -"aWz" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ +/obj/machinery/atmospherics/pipe/layer_manifold{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/cyan/visible, +/turf/open/floor/plating, +/area/engine/atmos) +"aWz" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -25886,6 +25838,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "CO2 to Pure" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aWA" = ( @@ -25896,11 +25853,6 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "CO2 to Pure" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -25911,73 +25863,19 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aWB" = ( -/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "aWC" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/heater{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aWD" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aWE" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 4 - }, -/obj/machinery/meter, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aWF" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engine/atmos) "aWG" = ( @@ -26027,48 +25925,24 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aWM" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable/white{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/turf/open/space, /area/engine/atmos) "aWN" = ( +/obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 6 }, -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "aWO" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aWP" = ( @@ -26076,7 +25950,6 @@ dir = 4 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, @@ -26086,6 +25959,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "aWR" = ( @@ -26853,7 +26727,6 @@ /turf/open/floor/engine/co2, /area/engine/atmos) "aXY" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -26865,6 +26738,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aXZ" = ( @@ -26874,7 +26748,6 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -26885,81 +26758,13 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) -"aYa" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aYb" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/heater/on{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aYc" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aYd" = ( +"aYf" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aYe" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aYf" = ( -/obj/structure/table/reinforced, -/obj/item/folder/yellow, -/obj/item/lightreplacer, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /turf/open/floor/plasteel, /area/engine/atmos) "aYg" = ( @@ -26997,27 +26802,23 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aYj" = ( -/obj/structure/table/reinforced, -/obj/item/wrench, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/item/tank/internals/emergency_oxygen/engi, /obj/machinery/newscaster{ pixel_x = 32 }, /obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/machinery/suit_storage_unit/atmos, /turf/open/floor/plasteel, /area/engine/atmos) "aYk" = ( -/obj/structure/table/reinforced, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/mask/gas, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/mask/gas, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/thermomachine/heater{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aYl" = ( @@ -27035,13 +26836,15 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/atmos) "aYm" = ( /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, @@ -27058,7 +26861,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aYn" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -27072,20 +26874,13 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aYo" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "aYp" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "O2 to Pure" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -27096,12 +26891,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 8 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aYq" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 10 - }, /obj/effect/decal/cleanable/dirt, /obj/structure/sign/warning/securearea{ pixel_x = 32 @@ -27124,6 +26919,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "O2 to Pure" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aYr" = ( @@ -28136,10 +27936,6 @@ /turf/open/floor/plating, /area/engine/atmos) "aZT" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -28150,6 +27946,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/co2, /turf/open/floor/plasteel/dark, /area/engine/atmos) "aZU" = ( @@ -28157,7 +27954,6 @@ dir = 8 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/components/trinary/filter/atmos/co2, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -28168,75 +27964,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel/dark, /area/engine/atmos) -"aZV" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 - }, -/obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aZW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aZX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aZY" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/machinery/meter, -/obj/item/wrench, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"aZZ" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 8 - }, -/obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "baa" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -28270,8 +28001,8 @@ "bac" = ( /obj/structure/closet/secure_closet/atmospherics, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/end{ - dir = 1 +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -28300,23 +28031,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bag" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -28337,11 +28051,6 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "O2 to Airmix" - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -28349,10 +28058,13 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bai" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -28363,6 +28075,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "O2 to Airmix" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "baj" = ( @@ -29016,7 +28733,6 @@ /turf/open/space, /area/space/nearstation) "bbA" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/structure/sign/warning/securearea{ pixel_x = -32 }, @@ -29038,10 +28754,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bbB" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -29052,58 +28768,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) -"bbC" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/obj/machinery/meter, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bbD" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/atmospheric_technician, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bbE" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/trinary/filter{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bbF" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -29157,7 +28824,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/landmark/start/atmospheric_technician, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -29171,13 +28837,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bbK" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bbL" = ( /obj/machinery/computer/atmos_control/tank/oxygen_tank{ dir = 8 @@ -29185,11 +28844,11 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bbM" = ( @@ -29205,6 +28864,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bbN" = ( @@ -29870,10 +29530,6 @@ /turf/open/floor/engine/plasma, /area/engine/atmos) "bda" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -29884,6 +29540,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Plasma to Pure" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bdb" = ( @@ -29894,11 +29555,6 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "Plasma to Pure" - }, /obj/effect/turf_decal/tile/purple{ dir = 1 }, @@ -29908,55 +29564,17 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bdc" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 4 - }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bdd" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bde" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bdf" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/machinery/meter, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bdg" = ( @@ -30000,9 +29618,6 @@ dir = 4 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ - dir = 1 - }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -30010,12 +29625,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bdl" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -30026,6 +29639,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ + dir = 1 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bdm" = ( @@ -30711,7 +30327,6 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/purple{ dir = 1 @@ -30719,6 +30334,7 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bey" = ( @@ -30735,28 +30351,9 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bez" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "beA" = ( -/obj/structure/table/reinforced, -/obj/item/analyzer{ - pixel_x = 7; - pixel_y = 3 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -30767,10 +30364,12 @@ dir = 4; pixel_x = -24 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -30795,17 +30394,16 @@ /turf/closed/wall, /area/engine/atmos) "beF" = ( -/obj/structure/table/reinforced, -/obj/item/stack/packageWrap, -/obj/item/hand_labeler, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "beG" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -30818,21 +30416,7 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"beH" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "beI" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "N2 to Pure" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -30843,6 +30427,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 5 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "beJ" = ( @@ -30852,12 +30439,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 10 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -30865,6 +30446,14 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "N2 to Pure" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "beK" = ( @@ -31526,10 +31115,6 @@ /turf/open/floor/engine/plasma, /area/engine/atmos) "bfU" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -31541,6 +31126,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bfV" = ( @@ -31548,7 +31134,6 @@ dir = 8 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma, /obj/effect/turf_decal/tile/purple{ dir = 1 }, @@ -31556,23 +31141,8 @@ /obj/effect/turf_decal/tile/purple{ dir = 8 }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bfW" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Port Mix to Port Ports" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/structure/closet/crate, /turf/open/floor/plasteel, /area/engine/atmos) "bfX" = ( @@ -31590,26 +31160,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bfY" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Port Mix to Starboard Ports" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bfZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -31630,29 +31180,13 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bgb" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 5 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bgc" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 5 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bgd" = ( @@ -31663,11 +31197,6 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "N2 to Airmix" - }, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -31675,11 +31204,13 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bge" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/yellow/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -31690,6 +31221,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "N2 to Airmix" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bgf" = ( @@ -32184,7 +31720,6 @@ /turf/open/floor/plating, /area/security/main) "bhf" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/decal/cleanable/dirt, /obj/structure/sign/warning/securearea{ pixel_x = -32 @@ -32202,50 +31737,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) -"bhg" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 1 - }, -/obj/machinery/meter, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bhh" = ( -/obj/machinery/atmospherics/pipe/manifold4w/general/visible, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bhi" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 10 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/plasteel/dark/corner{ - dir = 1 - }, -/area/engine/atmos) "bhj" = ( /obj/machinery/power/apc/highcap/five_k{ areastring = "/area/engine/atmos"; @@ -32347,7 +31841,6 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -32395,27 +31888,12 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) -"bhu" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/engine/atmos) "bhv" = ( /obj/machinery/air_sensor/atmos/nitrogen_tank, /turf/open/floor/engine/n2, @@ -33356,34 +32834,29 @@ dir = 1; pixel_y = 1 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "N2O to Pure" - }, /obj/effect/turf_decal/tile/red{ dir = 4 }, /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, /area/engine/atmos) "biX" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 5 + }, /turf/open/floor/plasteel, /area/engine/atmos) "biY" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -33394,75 +32867,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 10 + }, /turf/open/floor/plasteel, /area/engine/atmos) "biZ" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Pure to Ports" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bja" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Mix to Ports" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bjb" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Air to Ports" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bjc" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - name = "Port Mix to Engine" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -33473,15 +32883,14 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/obj/machinery/portable_atmospherics/canister, /turf/open/floor/plasteel, /area/engine/atmos) "bjd" = ( /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -33498,7 +32907,6 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -33509,6 +32917,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bjf" = ( @@ -33596,8 +33007,6 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/meter, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -33636,9 +33045,6 @@ dir = 4 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2{ - dir = 1 - }, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 4 @@ -34546,42 +33952,49 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 5 + }, /turf/open/floor/plasteel/white/corner{ dir = 1 }, /area/engine/atmos) "bkK" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Pure to Port" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bkL" = ( /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/manifold4w/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bkM" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/meter, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/manifold4w/general/visible, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "bkN" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/meter, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bkO" = ( /obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -34592,13 +34005,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bkQ" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/trinary/filter{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bkR" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/corner{ @@ -34640,12 +34046,20 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bkU" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 10 + }, +/turf/open/floor/plasteel/dark, /area/engine/atmos) "bkV" = ( /obj/effect/decal/cleanable/dirt, @@ -34667,11 +34081,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bkX" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/atmospherics/components/binary/valve{ - dir = 4; - name = "SM Coolant Loop" - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -34682,6 +34091,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bkY" = ( @@ -34691,9 +34103,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -34704,10 +34113,17 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bkZ" = ( /obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, /turf/open/space, /area/engine/atmos) "bla" = ( @@ -35683,91 +35099,103 @@ dir = 8 }, /obj/structure/window/reinforced, -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/portable_atmospherics/canister/nitrogen, /turf/open/floor/plasteel/cafeteria, /area/engine/atmos) "bmK" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 5 - }, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) "bmL" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 1 - }, /obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/components/binary/pump{ + name = "Port to Mix" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmM" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 9 - }, /obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmN" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/components/binary/pump{ + name = "Mix to Port" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmO" = ( /obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 5 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmP" = ( /obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Port to Waste" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmQ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 1 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, /area/engine/atmos) "bmR" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Air to Ports" + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, /area/engine/atmos) "bmS" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 1 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 1 + }, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, /area/engine/atmos) "bmT" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 1 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, /turf/open/floor/plasteel/checker, /area/engine/atmos) "bmU" = ( @@ -35814,7 +35242,9 @@ /obj/item/stack/sheet/glass/fifty, /obj/item/stack/rods/fifty, /obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bmY" = ( @@ -35850,9 +35280,6 @@ dir = 8 }, /obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -35863,11 +35290,30 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/engine/atmos) "bnb" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 5 +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) +"bnc" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -35879,15 +35325,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark, /area/engine/atmos) -"bnc" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/atmos) "bnd" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/orange/visible{ @@ -36579,28 +36019,15 @@ /area/space/nearstation) "bok" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 8 - }, -/obj/machinery/status_display/evac{ - pixel_x = -32 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plating, /area/engine/atmos) "bol" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/turf/open/floor/plating, -/area/engine/atmos) -"bom" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plating, /area/engine/atmos) "bon" = ( @@ -36620,9 +36047,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "boo" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/turf/open/floor/plating, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 4 + }, +/turf/closed/wall/r_wall, /area/engine/atmos) "bop" = ( /obj/structure/table/reinforced, @@ -36636,9 +36064,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "boq" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 10 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -36649,6 +36074,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bor" = ( @@ -36670,7 +36098,6 @@ /obj/item/clipboard, /obj/effect/decal/cleanable/dirt, /obj/item/toy/figure/atmos, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -37595,7 +37022,6 @@ /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/green{ dir = 1 }, @@ -37605,10 +37031,10 @@ /obj/effect/turf_decal/tile/green{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bpR" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/atmospherics/components/binary/pump/on{ dir = 8; name = "Unfiltered & Air to Mix" @@ -37633,13 +37059,11 @@ }, /area/engine/atmos) "bpT" = ( -/obj/machinery/atmospherics/components/binary/pump{ - name = "Pure to Mix" - }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -37662,6 +37086,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/meter, /turf/open/floor/plasteel/dark/corner{ dir = 1 }, @@ -37734,7 +37159,6 @@ /obj/item/clothing/head/welding, /obj/structure/table/reinforced, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -38947,22 +38371,27 @@ /obj/machinery/computer/atmos_control/tank/mix_tank{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/tile/green{ dir = 1 }, /obj/effect/turf_decal/tile/green{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 5 + }, /turf/open/floor/plasteel, /area/engine/atmos) "brW" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "brX" = ( @@ -39017,17 +38446,11 @@ /obj/item/wrench, /obj/item/clothing/mask/gas, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) "bsd" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -39038,13 +38461,13 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bse" = ( /obj/structure/table/reinforced, /obj/item/storage/belt/utility, /obj/item/t_scanner, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40226,13 +39649,14 @@ dir = 4; pixel_x = -22 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, /turf/open/floor/plasteel, /area/engine/atmos) "btU" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -40243,11 +39667,16 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/atmos) "btV" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 10 + }, /turf/open/floor/plasteel, /area/engine/atmos) "btW" = ( @@ -40326,47 +39755,53 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bub" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "buc" = ( /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/machinery/portable_atmospherics/canister/nitrogen, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bud" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bue" = ( -/obj/machinery/portable_atmospherics/canister/air, /obj/machinery/camera{ c_tag = "Atmospherics - Desk"; dir = 8; name = "atmospherics camera" }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "buf" = ( @@ -41024,9 +40459,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/engine/atmos) "bvn" = ( @@ -41036,9 +40468,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/engine/atmos) "bvo" = ( @@ -41049,9 +40478,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/engine/atmos) "bvp" = ( @@ -41059,9 +40485,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /turf/open/floor/plasteel, /area/engine/atmos) "bvq" = ( @@ -43155,7 +42578,9 @@ /obj/structure/cable/white{ icon_state = "0-2" }, -/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!interrogation_room" + }, /turf/open/floor/plating, /area/security/main) "byP" = ( @@ -44229,7 +43654,9 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!interrogation_room" + }, /turf/open/floor/plating, /area/security/main) "bAt" = ( @@ -45536,10 +44963,12 @@ /area/security/main) "bCm" = ( /obj/structure/cable/white, -/obj/effect/spawner/structure/window/reinforced/tinted, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!interrogation_room" + }, /turf/open/floor/plating, /area/security/main) "bCn" = ( @@ -45559,6 +44988,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/button/electrochromatic{ + id = "!interrogation_room"; + pixel_y = -26 + }, /turf/open/floor/plasteel/dark, /area/security/main) "bCo" = ( @@ -61243,10 +60676,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -61261,10 +60690,6 @@ dir = 4 }, /obj/machinery/light, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -26 - }, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -63314,43 +62739,36 @@ /turf/open/floor/plasteel/dark, /area/library) "cct" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = -32 +/obj/structure/table/wood/fancy, +/obj/machinery/door/window{ + name = "Secure Art Exhibition" }, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 26 - }, -/turf/open/floor/plasteel/dark, -/area/library) -"ccu" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/table/wood, -/obj/item/folder, -/obj/item/pen, -/obj/machinery/newscaster{ +/obj/structure/sign/painting/library_secure{ pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ +/turf/open/floor/carpet, +/area/library) +"ccu" = ( +/obj/structure/table/wood/fancy, +/obj/structure/window/reinforced{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 +/obj/structure/window/reinforced, +/obj/structure/sign/painting/library_secure{ + pixel_y = 32 }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/carpet, /area/library) "ccv" = ( -/obj/machinery/computer/libraryconsole, -/obj/structure/table/wood, -/turf/open/floor/plasteel/dark, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/obj/machinery/camera{ + c_tag = "Library - Aft"; + dir = 2; + name = "library camera" + }, +/turf/open/floor/wood, /area/library) "ccw" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -64492,7 +63910,7 @@ /obj/structure/chair/office/dark{ dir = 8 }, -/obj/effect/landmark/start/librarian, +/obj/effect/landmark/start/assistant, /turf/open/floor/plasteel/dark, /area/library) "ceg" = ( @@ -64505,71 +63923,21 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/library) -"cei" = ( -/obj/structure/chair/comfy/black{ - dir = 8 - }, -/obj/machinery/newscaster{ - pixel_x = 32 - }, -/obj/machinery/camera{ - c_tag = "Library - Fore"; - dir = 8; - name = "library camera" - }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/grimy, /area/library) "cej" = ( -/obj/machinery/photocopier, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/library) -"cek" = ( -/obj/structure/chair/office/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/dark, +/obj/effect/landmark/start/librarian, +/turf/open/floor/plasteel/grimy, /area/library) "cel" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen, -/obj/machinery/status_display/evac{ - pixel_x = 32 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ +/obj/structure/chair/sofa/right{ + icon_state = "sofaend_right"; dir = 8 }, -/turf/open/floor/plasteel/dark, +/obj/structure/sign/painting/library{ + pixel_x = 32 + }, +/turf/open/floor/wood, /area/library) "cem" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -65746,34 +65114,16 @@ }, /turf/open/floor/plasteel/grimy, /area/library) -"cfY" = ( -/obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/light/small{ - dir = 4 +"cfZ" = ( +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/structure/sign/painting/library{ + pixel_y = -32 }, /turf/open/floor/wood, /area/library) -"cfZ" = ( -/obj/structure/sign/warning/nosmoking, -/turf/closed/wall, -/area/library) -"cga" = ( -/obj/machinery/door/morgue{ - name = "Private Study" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/library) "cgb" = ( /obj/structure/sign/plaques/kiddie/library{ pixel_x = -32 @@ -66921,61 +66271,28 @@ /obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/wood, /area/library) -"chQ" = ( -/obj/machinery/bookbinder, -/turf/open/floor/wood, -/area/library) -"chR" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/obj/structure/bookcase/random, -/turf/open/floor/wood, -/area/library) -"chS" = ( -/obj/structure/chair/comfy/brown, -/obj/effect/landmark/start/assistant, -/turf/open/floor/wood, -/area/library) -"chT" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/library) -"chU" = ( -/obj/machinery/photocopier, -/obj/structure/extinguisher_cabinet{ - pixel_y = 32 - }, -/turf/open/floor/wood, -/area/library) "chV" = ( -/obj/machinery/light{ - dir = 1 - }, /obj/machinery/newscaster{ - pixel_y = 32 + pixel_x = -32 }, -/obj/structure/bookcase/manuals/research_and_development, -/obj/machinery/camera{ - c_tag = "Library"; - name = "library camera" - }, -/turf/open/floor/wood, +/turf/open/floor/plasteel/dark, /area/library) "chW" = ( -/obj/structure/chair/comfy/brown, -/obj/item/radio/intercom{ - name = "Station Intercom"; - pixel_y = 26 - }, -/turf/open/floor/wood, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/grimy, /area/library) "chX" = ( -/obj/machinery/vending/coffee, -/turf/open/floor/wood, +/obj/structure/table/wood, +/obj/item/newspaper{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/reagent_containers/food/drinks/coffee{ + pixel_x = -4; + pixel_y = 2 + }, +/turf/open/floor/plasteel/dark, /area/library) "chY" = ( /obj/machinery/door/poddoor/shutters/preopen{ @@ -67864,10 +67181,6 @@ }, /turf/open/floor/plasteel/grimy, /area/library) -"cju" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plasteel/grimy, -/area/library) "cjv" = ( /obj/machinery/door/airlock/public/glass{ name = "Library Access" @@ -69490,10 +68803,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/library) -"cmv" = ( -/obj/machinery/holopad, -/turf/open/floor/wood, -/area/library) "cmw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/extinguisher_cabinet{ @@ -70370,7 +69679,7 @@ /turf/open/floor/wood, /area/library) "cnP" = ( -/obj/structure/bookcase/manuals/medical, +/obj/structure/bookcase/random, /turf/open/floor/wood, /area/library) "cnQ" = ( @@ -75138,8 +74447,6 @@ /area/library) "cwr" = ( /obj/structure/easel, -/obj/item/canvas/twentythreeXnineteen, -/obj/item/canvas/twentythreeXtwentythree, /obj/item/canvas/twentythreeXtwentythree, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -77625,7 +76932,6 @@ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ @@ -79037,7 +78343,10 @@ pixel_x = 3; pixel_y = 3 }, -/obj/item/newspaper, +/obj/item/newspaper{ + pixel_x = 3; + pixel_y = 3 + }, /obj/machinery/status_display/evac{ pixel_x = -32 }, @@ -80750,7 +80059,10 @@ pixel_x = 7; pixel_y = 11 }, -/obj/item/newspaper, +/obj/item/newspaper{ + pixel_x = 3; + pixel_y = 3 + }, /obj/item/pen/red, /turf/open/floor/wood{ icon_state = "wood-broken2" @@ -82740,18 +82052,12 @@ /turf/open/floor/plasteel, /area/crew_quarters/dorms) "cJl" = ( -/obj/structure/cable/white{ - icon_state = "4-8" +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/dorms) +/turf/open/space, +/area/engine/atmos) "cJm" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -84065,9 +83371,6 @@ /turf/open/floor/plasteel, /area/crew_quarters/dorms) "cLa" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -84078,6 +83381,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "cLb" = ( @@ -110653,7 +109959,10 @@ pixel_x = 3; pixel_y = 3 }, -/obj/item/newspaper, +/obj/item/newspaper{ + pixel_x = 3; + pixel_y = 3 + }, /turf/open/floor/plating, /area/security/detectives_office/private_investigators_office) "dFu" = ( @@ -111516,7 +110825,10 @@ /area/crew_quarters/theatre/abandoned) "dGH" = ( /obj/structure/table/wood, -/obj/item/newspaper, +/obj/item/newspaper{ + pixel_x = 3; + pixel_y = 3 + }, /obj/item/clothing/head/bowler, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -125730,6 +125042,14 @@ }, /turf/open/floor/plasteel/dark, /area/library) +"emA" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/turf/open/floor/plating, +/area/engine/atmos) "exE" = ( /obj/machinery/air_sensor/atmos/toxins_mixing_tank, /turf/open/floor/engine/vacuum, @@ -125804,6 +125124,24 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/maintenance/port/fore) +"eRX" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "N2O to Pure" + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) "eTv" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -126006,6 +125344,17 @@ /obj/structure/closet/crate/coffin, /turf/open/floor/plating, /area/chapel/office) +"gjg" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port) "gmj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall/r_wall, @@ -126074,6 +125423,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"gOM" = ( +/obj/structure/sign/painting/library{ + pixel_y = -32 + }, +/turf/open/floor/wood, +/area/library) "gPv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -126170,6 +125525,12 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"hwV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/engine/atmos) "hFo" = ( /obj/structure/lattice, /obj/structure/disposalpipe/segment{ @@ -126321,6 +125682,12 @@ }, /turf/open/floor/plasteel/dark, /area/science/mixing) +"jaZ" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engine/atmos) "jdO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -126361,6 +125728,12 @@ /obj/item/integrated_circuit_printer, /turf/open/floor/plasteel/white/side, /area/science/circuit) +"jqs" = ( +/obj/structure/sign/painting/library{ + pixel_y = 32 + }, +/turf/open/floor/wood, +/area/library) "jqM" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -126479,6 +125852,17 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/science/mixing) +"jVB" = ( +/obj/structure/table/wood/fancy, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced, +/obj/structure/sign/painting/library_secure{ + pixel_y = 32 + }, +/turf/open/floor/carpet, +/area/library) "kam" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ @@ -126582,11 +125966,26 @@ }, /turf/open/floor/plasteel/white, /area/science/mixing) +"kQS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Port to Turbine" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "lak" = ( /turf/open/floor/plasteel/white/side{ dir = 10 }, /area/science/circuit) +"lhL" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible, +/turf/open/space, +/area/engine/atmos) "loI" = ( /obj/machinery/autolathe, /obj/machinery/door/window/southleft{ @@ -126604,6 +126003,20 @@ }, /turf/open/floor/plasteel/white, /area/science/lab) +"lqA" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) "lti" = ( /obj/machinery/atmospherics/components/trinary/mixer/flipped, /obj/effect/turf_decal/tile/neutral{ @@ -126820,6 +126233,16 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/circuit/green, /area/science/research/abandoned) +"mxy" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 8 + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engine/atmos) "mIi" = ( /obj/item/electropack/shockcollar, /obj/item/assembly/signaler, @@ -126852,6 +126275,12 @@ }, /turf/open/floor/plasteel/white, /area/science/research) +"mRS" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/wood, +/area/library) "mWZ" = ( /obj/machinery/atmospherics/components/binary/pump, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -126891,6 +126320,17 @@ /obj/machinery/atmospherics/pipe/simple/general/hidden, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"oek" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Library - Aft"; + dir = 2; + name = "library camera" + }, +/turf/open/floor/plasteel/grimy, +/area/library) "oHk" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -126989,6 +126429,14 @@ }, /turf/open/floor/plasteel/white, /area/science/research) +"oVn" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Ports to Engine" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "oYI" = ( /obj/machinery/igniter/incinerator_toxmix, /turf/open/floor/engine/vacuum, @@ -127098,6 +126546,10 @@ }, /turf/open/floor/plating, /area/science/research/abandoned) +"pLF" = ( +/obj/machinery/light, +/turf/open/floor/wood, +/area/library) "pQm" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/white{ @@ -127115,6 +126567,22 @@ }, /turf/open/floor/plasteel, /area/science/research/abandoned) +"qej" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) "qeN" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ @@ -127283,6 +126751,15 @@ "saw" = ( /turf/closed/wall, /area/science/circuit) +"sby" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/trinary/mixer/airmix{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "sfo" = ( /obj/effect/decal/remains/xeno, /turf/open/floor/engine/vacuum, @@ -127362,6 +126839,15 @@ "tCh" = ( /turf/closed/wall, /area/science/misc_lab) +"tDx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/grimy, +/area/library) "tMk" = ( /turf/open/floor/plasteel/white/side{ dir = 10 @@ -127511,6 +126997,23 @@ /obj/effect/landmark/start/paramedic, /turf/open/floor/plasteel/white, /area/medical/storage) +"vFd" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 5 + }, +/turf/open/floor/plating, +/area/engine/atmos) +"vLX" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/structure/sign/plaques/kiddie/library{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/plasteel/grimy, +/area/library) "wei" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, @@ -127530,6 +127033,38 @@ /obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/misc_lab) +"wEg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -26 + }, +/turf/open/floor/plasteel, +/area/hallway/primary/port) +"wFu" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"wHv" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/turf/open/floor/plasteel/dark, +/area/engine/atmos) "wIf" = ( /obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel, @@ -127552,6 +127087,23 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) +"xbz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "xdZ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -127682,6 +127234,13 @@ /obj/structure/fans/tiny/invisible, /turf/open/space/basic, /area/space) +"yin" = ( +/obj/structure/chair/sofa/left{ + icon_state = "sofaend_left"; + dir = 8 + }, +/turf/open/floor/wood, +/area/library) "yiv" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/neutral{ @@ -149906,22 +149465,22 @@ aNY aMB aMG aMG -aMG +aWN aWy -aMB -aZS -aMG +bol +emA +bol aWy -aMB -aZS -aMG -aWy -aMB -aZS -aMG -aZS -aMB +bol +emA +bol aWy +bol +emA +mxy +emA +vFd +aUP aMG aMG bxE @@ -150169,12 +149728,12 @@ aXY aZT bbA bda -aST +wHv bfU bhf -bda -aST -aZT +eRX +wHv +lqA bok bpQ brV @@ -150432,7 +149991,7 @@ bbB biW bkJ bmJ -bol +aTg bpR brW btN @@ -150672,20 +150231,20 @@ aGV aIv aJO aLj -aMB -aOa +aME +aOe aPF aRs aSV aUN aWB -aYa -aYa -aYa +aWB +aWB +aWB bdc -aYa -aYa -aYa +aWB +aWB +kQS biX bkK bmK @@ -150928,7 +150487,7 @@ aFr aGW aIw aJP -aLk +aLl aMB aOa aPG @@ -150936,17 +150495,17 @@ aRt aSW aUO aWC -aYb -aZV -aZV -bdd -bey -bae -bae +aWC +aWC +aWC +aWC +aWC +aWC +aYn biY bkL bmL -bom +bok bpT brY btP @@ -151186,20 +150745,20 @@ aFr aIx aJQ aLl -aME +aMB aOb aPH -aRu +aRy aSX -aUP -aWD -aYc -aZW -bbC -aYc -bez -bfW -aWD +aUO +aWC +aWC +aWC +aWC +aWC +aWC +aWC +aWC biZ bkM bmM @@ -151449,16 +151008,16 @@ aPI aRv aSW aUO -aWE -aYd -aZX -bbD -bde -bde +aWC +aWC +aWC +aWC +aWC +aWC bfX -bhg -bja -bkM +aWC +biZ +bkL bmN bon bpV @@ -151703,21 +151262,21 @@ aFr aMG aOd aPJ -aRw -aSY -aUP -aWF -aYe -aZY -bbE -bdf -bez -bfY -bhh -bjb +aRv +aSW +aUO +aWC +aWC +aWC +aWC +aWC +aWC +aWC +aWC +aYn bkN bmO -boo +aTg bpW bsb btS @@ -151958,20 +151517,20 @@ ayR aJT aLn aMG -aOe -aOo +aOn +aRu aRv aSW aUQ -aWG +aWC aYf -aZZ -aZZ -aZZ +aWC +aWC +aWC beA -aWK -bhi -bjc +aWC +aWC +aWC bkO bmP aTg @@ -152225,11 +151784,11 @@ aYg aMB aWH aMB -aWH +hwV aWH bhj bjd -bkP +bkO bmQ bop bpY @@ -152472,8 +152031,8 @@ aBf aJV aLp aMG -aOe -aOo +aOn +aRu aRv aSW aUS @@ -152486,12 +152045,12 @@ beB bfZ bhk bje -bkQ +bkN bmR boq bpZ bsd -aYn +boq bvf aMG bxL @@ -152743,7 +152302,7 @@ beC bga bhl bjf -bkP +oVn bmS bor bqa @@ -152986,7 +152545,7 @@ alT aJW aLq aMG -aOe +aOn aPN aRv aSW @@ -153767,7 +153326,7 @@ aYl bae bae bae -bae +xbz aWL bhp bji @@ -154019,7 +153578,7 @@ aPR aRB aTc aUV -aWM +bxS aYm baf bbJ @@ -154028,7 +153587,7 @@ baf baf bhq bjj -bkU +bkP bmX bow bqf @@ -154276,13 +153835,13 @@ aPS aRv aSW aUO -aWN +bxR +aYn aYn -bag aYn aYn beG -bgb +aYn bhr bjk bkV @@ -154535,10 +154094,10 @@ aTd aUW aWO aYo -aWO -bbK -bbK -beH +sby +aYo +aYo +aYo bgc bhs bjl @@ -155046,16 +154605,16 @@ aOo aOn aRD aTf -aOn -aRC +bkU +bnc aYq bai bbM bdl beJ bge -bhu -bdl +aXY +qej bkY bnb aMG @@ -155301,20 +154860,20 @@ alT aML aMG aMG -aMG -aTg +aRw +aUP aMB aTg -aMG -aWy +boo +aUP aMB aZS -aMG -aWy +boo +aUP aMB aZS -aMG -bnc +jaZ +aMB aMG bqk bsn @@ -155558,20 +155117,20 @@ aLy alT aad aad +aSY +aWM aRE aTh -aRE -aTh -aRE -aWx +cJl +lhL aRE aZR -aRE -aWx +cJl +lhL aRE aZR bkZ -aMN +aMM aMG bql bso @@ -158682,7 +158241,7 @@ ccq ceg ccq chO -ceg +vLX ckQ cmr ccq @@ -158935,11 +158494,11 @@ bUt bWD bYM caH -ccr +cwq ceh -cfY -chP -cjt +caG +caG +oek ckR cms cnO @@ -159190,12 +158749,12 @@ bDl bDl bUu bWE -bYO +gjg caG -ccs -cei +mRS +cxV cfZ -chQ +caG cjt ckR cms @@ -159449,11 +159008,11 @@ bUv bWC bYR caG +jqs +cxV +gOM caG -caG -caG -chR -cjt +tDx ckR cmt cmt @@ -159706,10 +159265,10 @@ bUq bWI bYM caG -cct -cej +jqs +cxV +gOM caG -chS cjt ckR cms @@ -159963,11 +159522,11 @@ bUq bWD bYM caG -ccu -cek -cga -chT -cju +jqs +cxV +gOM +caG +cjt ckR cms cnQ @@ -160221,9 +159780,9 @@ bWD bYM caG ccv -cel +cxV +pLF caG -chU cjt ckR xuu @@ -160477,9 +160036,9 @@ bUq bWD bYS caG -caG -caG -caG +jVB +cxV +cmt chV cjt ckT @@ -160736,7 +160295,7 @@ bYM caG cct cej -caG +cxV chW cjt ckR @@ -160992,12 +160551,12 @@ bWD bYM caG ccu -cek -cga -chT -cju +cmt +cmt +ccr +cjt ckR -cmv +cmt cnU cpy cqT @@ -161246,11 +160805,11 @@ bQu bQv bUr bWD -bYM +wEg caG -ccv +chP cel -caG +yin chX cjt ckR @@ -173538,7 +173097,7 @@ azG aAI aCb aDf -aEh +avW aFk aGD aHW @@ -178488,7 +178047,7 @@ cDD cFx cGU cAw -cJl +cJk cLa cMx cIi @@ -182564,7 +182123,7 @@ buU biQ aad ajr -ajr +wFu aad ajr ajr diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 5455070754..4d9dc17dfa 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -2562,6 +2562,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/security/execution/transfer) "afu" = ( @@ -2890,6 +2891,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/security/main) "agb" = ( @@ -3938,13 +3940,12 @@ /turf/open/floor/plasteel, /area/security/main) "ahO" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 - }, /obj/structure/chair/sofa/left{ dir = 1 }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, /turf/open/floor/plasteel, /area/crew_quarters/fitness) "ahP" = ( @@ -4516,6 +4517,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/security/processing) "aiE" = ( @@ -6246,6 +6248,7 @@ /obj/structure/sign/warning/vacuum/external{ pixel_x = 32 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/solars/port/fore) "alT" = ( @@ -7243,6 +7246,7 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/port/fore) "aok" = ( @@ -7470,6 +7474,7 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/fore/secondary) "aoJ" = ( @@ -7480,12 +7485,10 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/structure/chair/stool{ - pixel_y = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/fore/secondary) "aoL" = ( @@ -7599,10 +7602,10 @@ /turf/open/floor/plating, /area/security/warden) "apa" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 4 - }, /obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "apb" = ( @@ -9081,6 +9084,10 @@ dir = 8; pixel_x = 28 }, +/obj/machinery/space_heater{ + desc = "For when you got to turn up the heat on the suspect, or cool down your partners hot temper"; + name = "The Griller" + }, /turf/open/floor/plasteel/dark, /area/security/brig) "asq" = ( @@ -9628,6 +9635,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/construction/mining/aux_base) "aud" = ( @@ -10036,7 +10044,7 @@ name = "Cargo Bay"; width = 12 }, -/turf/closed/mineral/random/snow/no_caves, +/turf/open/floor/plating/asteroid/snow/icemoon, /area/icemoon/surface/outdoors) "avf" = ( /obj/structure/sign/warning/docking{ @@ -12277,6 +12285,7 @@ dir = 1 }, /obj/effect/turf_decal/stripes/line, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aAI" = ( @@ -14109,8 +14118,7 @@ /area/crew_quarters/dorms) "aFk" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 + dir = 4 }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -14603,13 +14611,12 @@ /turf/closed/wall, /area/crew_quarters/theatre) "aGw" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4; - pixel_y = 5 - }, /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/wood, /area/crew_quarters/bar) "aGx" = ( @@ -15250,10 +15257,6 @@ /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aHV" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1; - pixel_x = 5 - }, /obj/machinery/light/small{ dir = 4 }, @@ -15266,6 +15269,9 @@ /obj/item/reagent_containers/rag/towel/random, /obj/item/reagent_containers/rag/towel/random, /obj/item/reagent_containers/rag/towel/random, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/toilet) "aHY" = ( @@ -15291,6 +15297,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/starboard/fore) "aIc" = ( @@ -16873,10 +16880,6 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/structure/sign/poster/contraband/robust_softdrinks{ - pixel_x = -32; - pixel_y = 32 - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "aMh" = ( @@ -18099,7 +18102,6 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/status_display/evac, /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ id = "bridge blast"; @@ -18124,21 +18126,6 @@ }, /turf/open/floor/plating, /area/bridge) -"aPW" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/machinery/status_display/evac, -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - id = "bridge blast"; - name = "bridge blast door" - }, -/turf/open/floor/plating, -/area/bridge) "aPX" = ( /obj/structure/cable{ icon_state = "0-8" @@ -19304,15 +19291,16 @@ name = "Art Storage"; pixel_y = 24 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ icon_state = "0-8" }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/port) "aSY" = ( @@ -19851,6 +19839,7 @@ dir = 1 }, /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/storage/tools) "aUx" = ( @@ -24182,7 +24171,6 @@ /area/maintenance/port) "bfe" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/maintenance/port) "bff" = ( @@ -24556,7 +24544,7 @@ dir = 1 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/landmark/start/assistant, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bgj" = ( @@ -24633,6 +24621,7 @@ /area/maintenance/port) "bgt" = ( /obj/effect/spawner/lootdrop/maintenance, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/maintenance/port) "bgu" = ( @@ -24762,6 +24751,7 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = -32 }, +/obj/machinery/space_heater, /turf/open/floor/wood, /area/bridge/meeting_room) "bgM" = ( @@ -27002,6 +26992,7 @@ /area/crew_quarters/dorms) "blV" = ( /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/disposal) "blW" = ( @@ -32895,6 +32886,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/machinery/space_heater, /turf/open/floor/plasteel/dark, /area/science/server) "bzz" = ( @@ -35617,8 +35609,7 @@ pixel_y = 3 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 + dir = 4 }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -36529,6 +36520,7 @@ department = "Tech storage"; pixel_y = -32 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/storage/tech) "bHO" = ( @@ -37658,6 +37650,7 @@ /area/quartermaster/miningdock) "bKo" = ( /obj/machinery/light, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/quartermaster/miningdock) "bKp" = ( @@ -38522,9 +38515,13 @@ /turf/open/floor/plating, /area/science/xenobiology) "bMs" = ( -/obj/effect/spawner/structure/window/reinforced, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/machinery/space_heater, /turf/open/floor/plating, -/area/science/research) +/area/maintenance/fore/secondary) "bMt" = ( /obj/structure/sign/warning/vacuum/external{ pixel_y = 32 @@ -38668,11 +38665,20 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bMM" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/heater, +/obj/structure/rack, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas, /turf/open/floor/plasteel, /area/engine/atmos) "bMN" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer, +/obj/machinery/atmospherics/components/unary/thermomachine/heater, /turf/open/floor/plasteel, /area/engine/atmos) "bMO" = ( @@ -38742,15 +38748,13 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bMY" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 1 }, -/turf/closed/wall/r_wall, +/turf/open/floor/plasteel, /area/engine/atmos) "bMZ" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 6 - }, +/obj/machinery/atmospherics/components/unary/thermomachine/heater/on, /turf/open/floor/plasteel, /area/engine/atmos) "bNc" = ( @@ -39078,6 +39082,9 @@ /obj/machinery/light{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bNU" = ( @@ -39139,7 +39146,7 @@ /area/engine/atmos) "bOe" = ( /obj/machinery/meter, -/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bOf" = ( @@ -39150,13 +39157,7 @@ /turf/open/floor/plating, /area/engine/atmos) "bOg" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Mix to Incinerator" - }, +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bOh" = ( @@ -39463,17 +39464,16 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bOR" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold/purple/visible{ dir = 1 }, -/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "bOS" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/obj/structure/tank_dispenser, /turf/open/floor/plasteel, /area/engine/atmos) "bOT" = ( @@ -39486,8 +39486,8 @@ /area/engine/atmos) "bOU" = ( /obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -39574,35 +39574,34 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bPe" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible, +/obj/machinery/atmospherics/pipe/manifold/purple/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bPf" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ +/obj/machinery/atmospherics/pipe/simple/purple/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bPg" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/purple/visible{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bPh" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/layer_manifold{ dir = 4 }, -/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/engine/atmos) "bPi" = ( /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/yellow/visible, /obj/effect/turf_decal/tile/green{ dir = 1 }, @@ -39610,6 +39609,9 @@ /obj/effect/turf_decal/tile/green{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/purple/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bPj" = ( @@ -40033,8 +40035,8 @@ /obj/machinery/computer/atmos_alert{ dir = 8 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) @@ -40048,7 +40050,11 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/spawner/structure/window, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" + }, /turf/open/floor/plating, /area/engine/atmos) "bQo" = ( @@ -40092,7 +40098,7 @@ /turf/open/floor/plasteel, /area/security/checkpoint/engineering) "bQr" = ( -/obj/structure/closet/crate, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer, /turf/open/floor/plasteel, /area/engine/atmos) "bQs" = ( @@ -40116,38 +40122,31 @@ /turf/open/floor/plasteel/dark/corner, /area/hallway/primary/aft) "bQu" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/mask/gas, -/obj/item/clothing/mask/gas, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/closet/crate, /turf/open/floor/plasteel, /area/engine/atmos) "bQv" = ( +/obj/machinery/atmospherics/pipe/simple/purple/visible, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bQw" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 9 +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) "bQx" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 6 }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Mix to Distro" +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40164,6 +40163,9 @@ /obj/effect/turf_decal/tile/green{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 10 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bQA" = ( @@ -40439,6 +40441,11 @@ /area/hallway/primary/aft) "bRr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, +/obj/structure/tank_dispenser, /turf/open/floor/plasteel, /area/engine/atmos) "bRs" = ( @@ -40450,11 +40457,7 @@ /turf/open/floor/plating, /area/engine/atmos) "bRt" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 - }, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel, /area/engine/atmos) "bRu" = ( @@ -40464,7 +40467,6 @@ /obj/machinery/computer/atmos_alert{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bRv" = ( @@ -40483,8 +40485,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bRx" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, /area/engine/atmos) "bRy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ @@ -40502,8 +40506,9 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Waste to Filter" }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40519,26 +40524,26 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bRD" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bRE" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 1 +/obj/machinery/atmospherics/components/binary/pump{ + name = "Air to Ports" }, -/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "bRF" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump{ + name = "Mix to Ports" }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bRG" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 5 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40555,6 +40560,14 @@ dir = 4; name = "Unfiltered & Air to Mix" }, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bRL" = ( @@ -40842,11 +40855,7 @@ /area/hallway/primary/aft) "bSB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/atmos/glass{ - name = "Atmospherics Monitoring"; - req_access_txt = "24" - }, -/turf/open/floor/plasteel, +/turf/closed/wall, /area/engine/atmos) "bSC" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible{ @@ -40856,13 +40865,19 @@ /area/engine/atmos) "bSD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Monitoring"; + req_access_txt = "24" + }, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel, /area/engine/atmos) "bSE" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Pure to Mix" }, -/turf/closed/wall, +/turf/open/floor/plasteel, /area/engine/atmos) "bSF" = ( /obj/effect/turf_decal/bot, @@ -40894,13 +40909,15 @@ /area/engine/atmos) "bSM" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 5 + }, /turf/open/floor/plating, /area/engine/atmos) "bSN" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 10 }, /turf/open/floor/plating, /area/engine/atmos) @@ -41238,7 +41255,12 @@ /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, /area/engine/atmos) "bTM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -41251,14 +41273,16 @@ /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bTO" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "External to Waste" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bTP" = ( @@ -41268,19 +41292,14 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bTQ" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "Waste to Filter" +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 5 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bTR" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "Filter to Waste" - }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/pipe/manifold/orange/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bTS" = ( @@ -41288,15 +41307,16 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bTU" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 5 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Pure to Ports" }, /turf/open/floor/plasteel, /area/engine/atmos) "bTV" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; - name = "N2O Outlet Pump" + name = "N2O to Pure" }, /obj/effect/turf_decal/tile/red{ dir = 4 @@ -41642,7 +41662,9 @@ /area/engine/atmos) "bUL" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 4 + }, /turf/open/floor/plating, /area/engine/atmos) "bUM" = ( @@ -41656,9 +41678,7 @@ /area/engine/atmos) "bUN" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 10 - }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plating, /area/engine/atmos) "bUO" = ( @@ -41684,7 +41704,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/cyan/visible, -/obj/machinery/atmospherics/components/binary/pump/on{ +/obj/machinery/atmospherics/components/binary/pump{ dir = 8; name = "Mix to External" }, @@ -41698,6 +41718,9 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "bUU" = ( @@ -42026,10 +42049,10 @@ /turf/closed/wall/r_wall, /area/engine/atmos) "bVP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "External to Pumps" }, -/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bVQ" = ( @@ -42125,6 +42148,12 @@ /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ dir = 1 }, +/obj/effect/turf_decal/tile/red{ + dir = 4 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "bWd" = ( @@ -42405,7 +42434,12 @@ dir = 4; pixel_x = -22 }, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, /area/engine/atmos) "bWO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ @@ -42414,8 +42448,10 @@ /turf/closed/wall/r_wall, /area/engine/atmos) "bWP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/turf/closed/wall, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, /area/engine/atmos) "bWQ" = ( /turf/closed/wall/r_wall, @@ -42439,7 +42475,7 @@ /obj/structure/cable{ icon_state = "1-4" }, -/turf/open/floor/plating, +/turf/open/floor/plasteel, /area/engine/atmos) "bWU" = ( /obj/machinery/light{ @@ -42777,7 +42813,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 9 }, -/turf/closed/wall, +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, /area/engine/atmos) "bXM" = ( /obj/machinery/door/poddoor/preopen{ @@ -42856,7 +42897,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bXU" = ( -/obj/structure/reagent_dispensers/fueltank, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Ports to External" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bXV" = ( @@ -42866,12 +42910,19 @@ }, /obj/machinery/atmospherics/components/binary/pump{ dir = 8; - name = "Plasma Outlet Pump" + name = "Plasma to Pure" }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/turf_decal/stripes/line{ dir = 5 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bXW" = ( @@ -43075,6 +43126,7 @@ /obj/structure/sign/warning/vacuum/external{ pixel_x = -32 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/port/aft) "bYv" = ( @@ -43174,17 +43226,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bYJ" = ( -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics"; - req_access_txt = "24" - }, -/obj/machinery/door/firedoor/heavy, -/turf/open/floor/plasteel/dark/corner{ - dir = 1 - }, +/obj/machinery/atmospherics/pipe/manifold4w/general/visible, +/turf/open/floor/plasteel, /area/engine/atmos) "bYK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, @@ -43217,11 +43260,8 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bYN" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 - }, -/turf/open/floor/plating, +/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible, +/turf/open/floor/plasteel, /area/engine/atmos) "bYO" = ( /obj/structure/disposalpipe/segment{ @@ -43237,10 +43277,14 @@ /obj/machinery/computer/atmos_control/tank/toxin_tank{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/engine/atmos) "bYU" = ( @@ -43541,16 +43585,32 @@ /area/engine/atmos) "bZH" = ( /obj/machinery/portable_atmospherics/canister, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bZI" = ( -/obj/machinery/portable_atmospherics/scrubber, +/obj/machinery/space_heater, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bZK" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/plasma{ dir = 1 }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bZL" = ( @@ -43603,6 +43663,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/aft) "bZS" = ( @@ -43934,13 +43995,18 @@ /turf/closed/wall/r_wall, /area/security/checkpoint/engineering) "caE" = ( -/obj/structure/reagent_dispensers/watertank/high, +/obj/machinery/atmospherics/pipe/manifold/general/visible{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/atmos) "caF" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/atmos) "caG" = ( @@ -43954,12 +44020,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "caH" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 5 - }, /obj/effect/decal/cleanable/oil{ icon_state = "floor6" }, +/obj/machinery/atmospherics/pipe/manifold/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "caI" = ( @@ -44367,14 +44431,17 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cbA" = ( -/obj/machinery/portable_atmospherics/pump, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Ports to Incinerator" + }, /turf/open/floor/plasteel, /area/engine/atmos) "cbB" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/atmospherics/components/binary/pump{ dir = 8; - name = "Air Outlet Pump" + name = "Air to Pure" }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -44408,7 +44475,7 @@ "cbG" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; - name = "CO2 Outlet Pump" + name = "CO2 to Pure" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -44641,8 +44708,6 @@ /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) "cci" = ( -/obj/structure/table, -/obj/item/multitool, /obj/effect/turf_decal/tile/yellow{ dir = 1 }, @@ -44652,6 +44717,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/tcommsat/computer) "ccj" = ( @@ -44785,7 +44851,10 @@ /turf/closed/wall/r_wall, /area/engine/engineering) "ccy" = ( -/obj/machinery/space_heater, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "ccz" = ( @@ -45134,15 +45203,24 @@ /turf/open/floor/plating/snowed/smoothed/icemoon, /area/engine/atmos) "cdB" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 9 +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "cdC" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/co2{ dir = 1 }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cdD" = ( @@ -45203,6 +45281,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/aft) "cdK" = ( @@ -45329,6 +45408,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/item/multitool, /turf/open/floor/plasteel, /area/tcommsat/computer) "cef" = ( @@ -45735,7 +45815,10 @@ /turf/open/floor/plasteel, /area/engine/break_room) "cfi" = ( -/obj/machinery/portable_atmospherics/scrubber/huge, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel, /area/engine/atmos) "cfj" = ( @@ -46029,6 +46112,7 @@ pixel_y = 26 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/maintenance/disposal/incinerator) "cga" = ( @@ -46230,6 +46314,7 @@ /obj/structure/sign/warning/vacuum/external{ pixel_x = -32 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "cgB" = ( @@ -46426,6 +46511,13 @@ /obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ dir = 4 }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/atmos) "chb" = ( @@ -46468,8 +46560,11 @@ /turf/open/floor/plasteel/cafeteria, /area/engine/atmos) "che" = ( -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics"; +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "Atmospherics External Airlock"; req_access_txt = "24" }, /turf/open/floor/plating, @@ -46940,8 +47035,8 @@ /turf/closed/wall/r_wall, /area/engine/atmos) "ciu" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/layer_manifold, /turf/open/floor/plating, /area/engine/atmos) "civ" = ( @@ -48405,6 +48500,7 @@ /obj/structure/sign/warning/vacuum/external{ pixel_y = -32 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/solars/starboard/aft) "cmy" = ( @@ -48775,6 +48871,7 @@ /obj/structure/disposalpipe/junction/flip{ dir = 4 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/aft) "cnF" = ( @@ -49444,6 +49541,7 @@ c_tag = "Engineering Escape Pod"; dir = 4 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/engine/engineering) "cqr" = ( @@ -49508,6 +49606,7 @@ /obj/machinery/light/small{ dir = 4 }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/port/aft) "cqM" = ( @@ -49627,6 +49726,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/engine/engineering) "cry" = ( @@ -49846,6 +49946,7 @@ pixel_y = -29 }, /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) "cti" = ( @@ -49864,6 +49965,7 @@ }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) "ctk" = ( @@ -51426,6 +51528,7 @@ dir = 8 }, /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/hallway/secondary/entry) "cxm" = ( @@ -51472,6 +51575,7 @@ dir = 8 }, /obj/machinery/light/small, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/hallway/secondary/entry) "cya" = ( @@ -52232,7 +52336,9 @@ /area/science/mixing) "cBF" = ( /obj/effect/landmark/event_spawn, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cBH" = ( @@ -52421,10 +52527,10 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "cCE" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ +/obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cCF" = ( @@ -52517,10 +52623,7 @@ /turf/open/floor/wood, /area/crew_quarters/theatre) "cGG" = ( -/obj/effect/spawner/structure/window, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, +/obj/machinery/atmospherics/pipe/simple/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cHf" = ( @@ -52978,6 +53081,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/starboard) "cNT" = ( @@ -53099,7 +53203,7 @@ dir = 4 }, /obj/machinery/door/airlock/external{ - req_access_txt = "13" + req_access_txt = "13;8;12" }, /turf/open/floor/plating, /area/maintenance/starboard/aft) @@ -53108,7 +53212,7 @@ dir = 8 }, /obj/machinery/door/airlock/external{ - req_access_txt = "13" + req_access_txt = "13;8;12" }, /turf/open/floor/plating, /area/maintenance/starboard/aft) @@ -53542,6 +53646,7 @@ /obj/structure/sign/poster/official/safety_internals{ pixel_x = -32 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel/white, /area/science/xenobiology) "cTZ" = ( @@ -53710,6 +53815,13 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"dkV" = ( +/obj/machinery/space_heater, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "dly" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -53842,6 +53954,11 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"dDV" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/quartermaster/warehouse) "dFX" = ( /turf/closed/wall, /area/crew_quarters/fitness/pool) @@ -53967,12 +54084,8 @@ }, /area/crew_quarters/fitness/pool) "ecE" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Mix to Waste" +/obj/machinery/atmospherics/pipe/simple/general/visible{ + dir = 5 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -54122,6 +54235,10 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"eyr" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/fore) "eyM" = ( /obj/machinery/mineral/ore_redemption{ input_dir = 2; @@ -54630,6 +54747,11 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/hydroponics) +"fzU" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "fAj" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -54724,6 +54846,11 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/science/circuit) +"fKv" = ( +/obj/machinery/portable_atmospherics/scrubber/huge, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/atmos) "fMp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, @@ -54905,13 +55032,9 @@ /turf/open/floor/carpet, /area/crew_quarters/cryopod) "gfJ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ +/obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 4 }, -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics"; - req_access_txt = "24" - }, /turf/open/floor/plasteel, /area/engine/atmos) "ghD" = ( @@ -54948,11 +55071,12 @@ dir = 4 }, /obj/structure/closet/secure_closet/atmospherics, -/obj/item/cartridge/atmos, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/turf/open/floor/plasteel, /area/engine/atmos) "gnf" = ( /obj/structure/disposalpipe/segment{ @@ -55107,6 +55231,7 @@ /obj/item/radio/intercom{ pixel_y = 20 }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/security/processing) "gGH" = ( @@ -55450,13 +55575,19 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"hOd" = ( +/obj/machinery/portable_atmospherics/scrubber, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "hOv" = ( /obj/structure/table/wood/fancy, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4; - pixel_y = 5 - }, /obj/item/reagent_containers/food/snacks/burger/plain, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/wood, /area/crew_quarters/bar) "hOI" = ( @@ -55486,8 +55617,8 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 }, /turf/closed/wall, /area/quartermaster/warehouse) @@ -55542,6 +55673,10 @@ }, /turf/open/floor/wood, /area/crew_quarters/bar) +"hUv" = ( +/obj/machinery/space_heater, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "hVs" = ( /turf/open/floor/plasteel/dark, /area/engine/engineering) @@ -55643,6 +55778,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/pool) "ipA" = ( +/obj/machinery/space_heater, /turf/open/floor/plating, /area/maintenance/department/medical/morgue) "itD" = ( @@ -55859,9 +55995,17 @@ /turf/open/floor/plasteel, /area/engine/engineering) "iYC" = ( -/obj/effect/spawner/structure/window, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/airlock/atmos{ + name = "Atmospherics"; + req_access_txt = "24" + }, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, /area/engine/atmos) "iYE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -56037,12 +56181,16 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness) "jxF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 }, -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plating, -/area/maintenance/port) +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/construction/mining/aux_base) "jyO" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -56181,6 +56329,37 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"jLl" = ( +/obj/structure/rack, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/obj/item/shovel{ + pixel_x = -5 + }, +/obj/item/shovel{ + pixel_x = -5 + }, +/obj/item/shovel{ + pixel_x = -5 + }, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/obj/item/storage/bag/ore/large, +/obj/item/storage/bag/ore/large, +/obj/item/storage/bag/ore/large, +/obj/item/clothing/suit/hooded/wintercoat/aformal, +/obj/item/clothing/suit/hooded/wintercoat/aformal, +/obj/item/clothing/suit/hooded/wintercoat/aformal, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/obj/item/clothing/shoes/winterboots, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) "jLn" = ( /obj/machinery/door/airlock/engineering{ name = "Gravity Generator"; @@ -56359,8 +56538,19 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"khU" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "N2 to Pure" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "khV" = ( /obj/machinery/vending/cola/red, +/obj/structure/sign/poster/contraband/robust_softdrinks{ + pixel_x = -32; + pixel_y = 32 + }, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) "kjm" = ( @@ -56452,6 +56642,13 @@ }, /turf/open/floor/plasteel, /area/security/range) +"kvI" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/aft) "kvL" = ( /obj/structure/cable{ icon_state = "1-2" @@ -56746,6 +56943,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/range) +"lcu" = ( +/obj/effect/spawner/lootdrop/maintenance, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/maintenance/port) +"lfj" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/disposal) "lfB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 4 @@ -57256,6 +57462,12 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"mCy" = ( +/obj/machinery/space_heater{ + anchored = 1 + }, +/turf/open/floor/plasteel/dark, +/area/engine/engineering) "mDB" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -57636,6 +57848,13 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/locker) +"nNP" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "O2 to Pure" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "nQi" = ( /obj/machinery/recharge_station, /turf/open/floor/plating, @@ -57674,6 +57893,10 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/dorms) +"nTd" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/ai_monitored/turret_protected/aisat/hallway) "nTG" = ( /obj/structure/chair{ dir = 1 @@ -57748,8 +57971,7 @@ pixel_y = 20 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4; - pixel_y = 5 + dir = 4 }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -58024,10 +58246,18 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"oEr" = ( +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/engine/engineering) "oEZ" = ( /obj/effect/spawner/lootdrop/keg, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"oFT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/storage/art) "oHB" = ( /turf/open/floor/plasteel/dark, /area/crew_quarters/dorms) @@ -58067,6 +58297,15 @@ }, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) +"oMH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/machinery/space_heater{ + anchored = 1 + }, +/turf/open/floor/engine, +/area/engine/engineering) "oNz" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -58177,6 +58416,11 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"pck" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/aft) "pem" = ( /obj/machinery/button/door{ desc = "Bolts the doors to the Private Study."; @@ -58226,6 +58470,13 @@ }, /turf/open/floor/wood, /area/crew_quarters/bar) +"plL" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "plS" = ( /obj/machinery/door/window/brigdoor/security/cell{ id = "Cell 1"; @@ -58541,6 +58792,13 @@ }, /turf/open/floor/plasteel, /area/security/processing) +"pZr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/aft) "qaY" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/bar, @@ -58793,11 +59051,12 @@ dir = 4 }, /obj/structure/closet/secure_closet/atmospherics, -/obj/item/cartridge/atmos, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/corner{ dir = 1 }, -/turf/open/floor/plasteel, /area/engine/atmos) "rcD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58870,6 +59129,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/security/processing) +"rjG" = ( +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) "rjH" = ( /obj/structure/cable{ icon_state = "2-4" @@ -58985,6 +59248,13 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) +"rto" = ( +/obj/machinery/portable_atmospherics/scrubber, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "rtC" = ( /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating, @@ -59303,6 +59573,12 @@ /obj/effect/spawner/lootdrop/maintenance, /turf/open/floor/plating, /area/maintenance/fore) +"siv" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "slk" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -59569,6 +59845,10 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness) +"sKd" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/hallway/primary/central) "sLa" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -59653,6 +59933,15 @@ }, /turf/open/floor/plasteel, /area/quartermaster/office) +"sRO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/maintenance{ + req_one_access_txt = "8;12" + }, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "sRT" = ( /obj/machinery/vending/cola/random, /turf/open/floor/wood, @@ -59679,6 +59968,13 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"sTP" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/port/aft) "sUh" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/closed/wall, @@ -59727,6 +60023,13 @@ /obj/machinery/vending/boozeomat, /turf/closed/wall, /area/maintenance/bar) +"sXM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/aft) "sXV" = ( /turf/closed/wall/r_wall, /area/security/range) @@ -59785,6 +60088,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/crew_quarters/bar) +"tiF" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/aft) "tkq" = ( /obj/structure/cable{ icon_state = "4-8" @@ -60500,11 +60807,10 @@ /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) "uQS" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1; - pixel_x = 5 - }, /obj/machinery/light/small, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/toilet) "uRd" = ( @@ -60565,6 +60871,13 @@ }, /turf/open/floor/plating, /area/maintenance/starboard/aft) +"uWy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/starboard/fore) "uXt" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, @@ -60761,6 +61074,15 @@ /obj/structure/cable, /turf/open/floor/carpet, /area/crew_quarters/cryopod) +"vsQ" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/closet/emcloset, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/hallway/secondary/entry) "vsT" = ( /obj/structure/closet/crate, /obj/item/book/manual/wiki/telescience, @@ -61096,6 +61418,10 @@ }, /turf/open/floor/engine, /area/engine/engineering) +"vUI" = ( +/obj/machinery/status_display/evac, +/turf/closed/wall, +/area/ai_monitored/storage/eva) "vZA" = ( /obj/structure/cable, /turf/open/floor/plating/snowed/smoothed/icemoon, @@ -61137,6 +61463,11 @@ }, /turf/open/floor/plasteel/white, /area/medical/medbay/central) +"wcr" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/atmos) "wcB" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 @@ -61174,6 +61505,10 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/pool) +"wiI" = ( +/obj/machinery/space_heater, +/turf/open/floor/wood, +/area/security/vacantoffice) "wje" = ( /obj/structure/rack, /obj/item/instrument/banjo, @@ -61222,6 +61557,10 @@ }, /turf/open/floor/plating, /area/construction/mining/aux_base) +"wpr" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/port) "wql" = ( /obj/structure/extinguisher_cabinet, /turf/closed/wall/r_wall, @@ -61282,7 +61621,7 @@ /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/layer_manifold, /turf/open/floor/plating, /area/engine/atmos) "wAh" = ( @@ -61316,6 +61655,14 @@ }, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"wHR" = ( +/obj/machinery/light, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/space_heater, +/turf/open/floor/plasteel/white/corner, +/area/hallway/secondary/entry) "wHT" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plating, @@ -61326,6 +61673,10 @@ }, /turf/open/floor/plasteel/dark, /area/engine/engineering) +"wJF" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/storage/tech) "wKe" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -61718,6 +62069,12 @@ /obj/item/radio/headset/headset_cargo, /turf/open/floor/plasteel, /area/quartermaster/storage) +"xBF" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "xDM" = ( /obj/machinery/camera{ c_tag = "Locker Room South"; @@ -61923,10 +62280,18 @@ }, /turf/open/floor/plating, /area/security/processing) +"xXg" = ( +/obj/machinery/space_heater, +/turf/open/floor/plasteel, +/area/quartermaster/warehouse) "xXi" = ( /obj/machinery/vending/clothing, /turf/open/floor/plasteel, /area/crew_quarters/fitness) +"xZo" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/construction) "xZD" = ( /obj/structure/closet/lasertag/red, /obj/item/clothing/under/misc/pj/red, @@ -62009,6 +62374,11 @@ /obj/item/folder/blue, /turf/open/floor/plasteel/dark, /area/hallway/primary/central) +"yjo" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/starboard) "ykN" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/plating/snowed/smoothed/icemoon, @@ -68798,11 +69168,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM -aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69055,6 +69425,11 @@ aBM aBM aBM aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69064,16 +69439,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69312,9 +69682,11 @@ aBM aBM aBM aBM -aBM -aBM +crk +crk aud +crk +crk aBM aBM aBM @@ -69324,13 +69696,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM +crk +crk auC -aBM -aBM +crk +crk aBM aBM aBM @@ -69569,6 +69939,11 @@ aBM aBM aBM aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69578,16 +69953,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69826,6 +70196,11 @@ aBM aBM aBM aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -69835,16 +70210,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -70083,6 +70453,11 @@ aBM aBM aBM aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -70092,16 +70467,11 @@ aBM aBM aBM aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +crk +crk +crk +crk +crk aBM aBM aBM @@ -70340,11 +70710,11 @@ aBM aBM aBM aBM -aBM +crk crk auj crk -aBM +crk aBM aBM crk @@ -70354,11 +70724,11 @@ crk crk aBM aBM -aBM +crk crk auj crk -aBM +crk aBM aBM aBM @@ -71385,7 +71755,7 @@ awW awW awW aQG -aRX +wHR arB aBM aBM @@ -71393,7 +71763,7 @@ aBM aBM aBM arB -awZ +vsQ ayk awW aAD @@ -72422,9 +72792,9 @@ aBM aBM awW awZ +jHh ayl -ayl -aAE +jLl awW aBM aBM @@ -72679,7 +73049,7 @@ aBM aBM awW awZ -ayl +jHh ayl bgi awW @@ -73679,7 +74049,7 @@ atI atI arE ayq -ayq +jxF auc avp axI @@ -74476,7 +74846,7 @@ azz ayl azz aPu -ayl +aNh aIK ayl beM @@ -74733,10 +75103,10 @@ ayl ayl aWc baG -ayl +aNh aIK ayl -beM +fzU arB aBM aBM @@ -76017,7 +76387,7 @@ aUO aUO aXL aXZ -aUO +wiI czK bbe beO @@ -76026,7 +76396,7 @@ bgj bgj bjc cAF -cAF +lfj bja wWu wWu @@ -76759,7 +77129,7 @@ ayF ayF alU aoT -amC +atJ aqO arG asc @@ -77555,7 +77925,7 @@ aPz aPz aPz aPz -aSg +wpr aWj aXP aZr @@ -77569,14 +77939,14 @@ bfh aPz aPz aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -77825,17 +78195,17 @@ bea bfq bji bkF -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -78082,17 +78452,17 @@ bdZ bhO bjh bkE -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -78339,18 +78709,18 @@ aPz bhQ bjj bkF -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -78596,18 +78966,18 @@ gQX bhQ bjj bkF -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -78853,18 +79223,18 @@ bgr iwB hew bkF -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -79110,18 +79480,18 @@ gfr bhQ bjk bkE -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF +ayF aBM aBM aBM @@ -79367,17 +79737,17 @@ bgs hnl bjk bkF -aBM -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF +ayF avd -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF aBM aBM aBM @@ -79624,8 +79994,8 @@ aPz bhQ bjk aPz -aBM -aBM +ayF +ayF boI bqi brJ @@ -79633,8 +80003,8 @@ boI brJ bvS boI -aBM -aBM +ayF +ayF aBM aBM aBM @@ -79881,8 +80251,8 @@ bgt bhS bjk aPz -aBM -aBM +ayF +ayF blW bqj brK @@ -79890,9 +80260,9 @@ blW brK bvT blW -aBM -aBM -aBM +ayF +ayF +ayF aBM aBM aBM @@ -80134,7 +80504,7 @@ aQN cBh bdL aPA -bgt +lcu bhR bjk aZE @@ -80143,14 +80513,14 @@ blW blW bqi cyD -blW +aZE cyD bvS blW -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF aBM aBM ayF @@ -80356,7 +80726,7 @@ alU amE ann amC -amC +atJ alU amC alU @@ -80404,11 +80774,11 @@ btr bnw bvV blW -aBM -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF +ayF ayF ayF ayF @@ -80663,8 +81033,8 @@ bvU aZE ayF ayF -aBM -aBM +ayF +ayF ayF ayF ayF @@ -80918,10 +81288,10 @@ bjt biq bvV blW -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF ayF ayF ayF @@ -81175,10 +81545,10 @@ bjr buC bvV blW -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF ayF ayF bxy @@ -81432,10 +81802,10 @@ bjr bkt bvV blW -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF ayF ayF bxy @@ -81689,10 +82059,10 @@ bjr bjr bvV bxu -aBM -aBM -aBM -aBM +ayF +ayF +ayF +ayF ayF ayF bxy @@ -81932,7 +82302,7 @@ aQW aQW xDM aPA -jxF +aWv aYb aZE bjp @@ -82695,7 +83065,7 @@ aPF aQZ aRa aTF -aPG +oFT aSX hPP aZF @@ -82752,7 +83122,7 @@ cAh chT bHE bHE -ckv +sTP bHE bCq bLv @@ -82955,7 +83325,7 @@ aPJ aPJ aVC aXJ -bgA +dDV aZp baY bcJ @@ -83983,9 +84353,9 @@ aTJ aPK aWA aWC -baS +xXg aZI -baS +xXg cCn bdS bdU @@ -84011,7 +84381,7 @@ bEK byE byE avl -byE +rjG bGi ayF ayF @@ -84787,7 +85157,7 @@ bxy crk crk bCq -bHE +ceW bRh bLu bCq @@ -85809,7 +86179,7 @@ bAo bTE bGo bHC -bHE +ceW bCq bCq bLv @@ -86016,7 +86386,7 @@ arl arP asS sfs -aqR +eyr awb axt ayG @@ -86347,7 +86717,7 @@ bLw bLw caq cbw -bHE +ceW ciT bCq bSs @@ -88413,7 +88783,7 @@ ccw cnZ coH cgR -cgR +oEr cig nEI ccw @@ -88897,7 +89267,7 @@ bJj bKu bLy bCs -bNJ +xZo bNJ bKx cjL @@ -89112,7 +89482,7 @@ ayL ayW ayW ayW -ayW +vUI aJq aJq aOE @@ -89154,7 +89524,7 @@ bFa bFa bFa bCs -bNJ +xZo bNJ apV cjL @@ -89193,7 +89563,7 @@ hOI qmG uqX oEe -tcF +oMH uSL fft ccw @@ -89456,7 +89826,7 @@ vOF fAX hVs iWD -hVs +hUv fPM ccw ayF @@ -90174,7 +90544,7 @@ aXf aJq bBi bCs -bFa +wJF bFa bFa bET @@ -91686,7 +92056,7 @@ aKF aMf aNB aOE -aPW +aPS aRr aSD ceh @@ -91991,7 +92361,7 @@ bUF bVN bWN bXM -bYJ +bLK bRi bZy cbu @@ -92241,14 +92611,14 @@ alk bNQ bOV bQk -bRt +bVQ bSD bTM bUH bVQ bVZ bXM -bLK +iYC cew bTh cdt @@ -92497,13 +92867,13 @@ bLL bOd bNQ bOU -bTO -bRr -bSE +bQj +bOd +bMK bTN -gfJ -bVP -bWP +bTP +bRy +cfN bXL bLK bRj @@ -92540,7 +92910,7 @@ ccw dSF vLM sAQ -hVs +hUv gAE ccw ayF @@ -92710,7 +93080,7 @@ gfD woR dgz aJw -aJw +sKd aMh aJq aOE @@ -92756,8 +93126,8 @@ bNS bOX bQm bRv -cGG -glY +bRs +rca bTP bVX bWQ @@ -93013,7 +93383,7 @@ bNR bOW bQl bRu -iYC +bRs rca bUI bVR @@ -93269,7 +93639,7 @@ bMK bMK bOY bQn -bRx +bRs bMK bUP bUJ @@ -93524,7 +93894,7 @@ bKz bLK bQr bNT -bOV +bQu bQo bRw bSF @@ -93561,8 +93931,8 @@ jIb qXZ dVX dVX -hVs -hVs +mCy +mCy ccw ayF ayF @@ -94037,7 +94407,7 @@ bJv bKB bLK bMM -bNV +bOd bOQ bQj bRy @@ -94306,12 +94676,12 @@ bVV bVV bWT bZG -caE -cbA -ccy -bZH -bZI -bQu +bOd +bOd +bOd +bOd +bOd +bOd bOd cgW cit @@ -94554,19 +94924,19 @@ bMO bIF bOZ bQp -bRA -bTP -bOd +bRx +bTO +bTR bOd bOd bOd bOd bXS bOd -bXU -cbA -ccy -bZH +bOd +bOd +bOd +bOd bZI cfi bOd @@ -94810,10 +95180,10 @@ bLK bMR bIH bJF -bRy -bTQ -ecE -bOd +bRt +bRA +bTP +bVP bOd bOd bOd @@ -94824,8 +95194,8 @@ bOd bOd bOd bOd -bOd -bOd +dkV +fKv cfQ cgY ciu @@ -95067,11 +95437,11 @@ bLK bMQ bNY bPa -bYN +bMQ bRC bSK -bOd -bOd +bWP +bZH bOd bOd bOd @@ -95081,8 +95451,8 @@ bOd bOd bOd bOd -bOd -bOd +rto +wcr apa cgX apF @@ -95327,8 +95697,8 @@ bPd cBF bRD bSK -bOd -bOd +bWP +bZH bOd bOd bOd @@ -95338,9 +95708,9 @@ bOd bOd cBJ bOd -bOd -bOd -bOd +hOd +plL +bTP cha civ axs @@ -95582,10 +95952,10 @@ bMS cfQ bPc bQs -bTR +cez bSJ -bOd -bOd +bWP +bZH bOd bOd bOd @@ -95595,9 +95965,9 @@ bOd bOd bOd bOd -bOd -bOd -bOd +cfQ +cez +siv cgZ bSK crk @@ -95841,9 +96211,7 @@ bOR bQv bRF bSM -bTS -bOd -bOd +bXU bOd bOd bOd @@ -95854,6 +96222,8 @@ bOd bOd bOd bOd +bTP +cfQ cbD chb wzX @@ -96095,15 +96465,13 @@ bLK bMU bOc bPe -bTP +bMY bRE bUL -cfT -bOd -bOd -bOd -bOd -bOd +bYJ +caE +cGG +ecE bOd bOd bOd @@ -96111,6 +96479,8 @@ bOd bOd bOd bOd +khU +nNP cfP ccz bSJ @@ -96350,12 +96720,15 @@ bvd bKH bLK bMX -bTP +bMY bPg bQx -bRF -bSM +bSE +bTQ bTU +cbA +bOd +gfJ bOd bOd bOd @@ -96363,10 +96736,7 @@ bOd bOd bOd bOd -bOd -bOd -bMZ -bTS +xBF caH cbE chd @@ -96612,8 +96982,8 @@ bPf bQw bRG bSN -bPg -bTS +bYN +ccy bTS cCE bWa @@ -96622,7 +96992,7 @@ bTS bTS bYL bTS -cdB +bTS caF cbB cfT @@ -96796,7 +97166,7 @@ uhm ahn aiA ahn -grc +bMs anE aod ahn @@ -97120,14 +97490,14 @@ bvj bvd bKH bLK -bMY +bLK bOf bPh bQy bRI ceA bPh -bQy +cdB bRI cCF bPh @@ -99241,7 +99611,7 @@ cvk cvX cvX cvX -cvX +nTd cwq cwq cva @@ -99444,12 +99814,12 @@ bUY pRg bWe pRg -bWe +kvI bWe cdE bAw bzs -bAw +tiF caK cfj ciB @@ -99689,7 +100059,7 @@ bFA bIm bJD bKK -bLS +pck bNc bOj bNc @@ -100213,7 +100583,7 @@ bMa bTZ bKH bzs -bAw +tiF bXZ bAw bZN @@ -101948,8 +102318,8 @@ crk alO arp alO -anf -anf +aBF +aBF anf anf anf @@ -102544,7 +102914,7 @@ ceJ cAe cmj cne -bHd +sXM bPn ayF ayF @@ -103029,7 +103399,7 @@ bFH bHb bIw bBN -bKT +pZr bMb bNd bOt @@ -103310,7 +103680,7 @@ cfq bKT bAw ciH -bHd +sXM bzs bAw cmk @@ -103489,8 +103859,8 @@ aoO apB aqx art -anf -anf +aBF +aBF auF alP awH @@ -103535,7 +103905,7 @@ bon buG bvA bon -bAw +tiF bzg bLS bLS @@ -104013,7 +104383,7 @@ alP alP alP alP -ayf +uWy aFm aGF aIq @@ -105543,7 +105913,7 @@ ayF ayF ayF alO -anf +aBF anf asy anf @@ -106570,7 +106940,7 @@ aBM ayF ayF alO -anf +aBF anf arw nuw @@ -108684,9 +109054,9 @@ bEz bFS bJT bLh -bMs -bMs -bMs +bvx +bvx +bvx bPN bQS bSf @@ -110763,7 +111133,7 @@ lZl cNW chC ciL -cOe +cou cOe clv cQw @@ -110975,8 +111345,8 @@ aTm aTm bgd bhG -bhG -bhG +yjo +yjo blO bmc bnq @@ -111231,8 +111601,8 @@ bcC cBl aPq bgg -aNa -ayF +aMZ +bky bky bqh bme @@ -112557,7 +112927,7 @@ cNW cNW cNW cNW -clt +sRO cNW cNW cNW @@ -113068,13 +113438,13 @@ kAJ clt cac cbh -cNW +cou ccV cOe clt cfv cBL -cOe +cou cNW ayF ayF @@ -113829,16 +114199,16 @@ ayF ayF ayF ayF -aBM -aBM +crk +crk ayF -aBM -aBM +crk +crk ayF ayF ayF -aBM -aBM +crk +crk ayF ayF cNW @@ -114077,8 +114447,8 @@ bky bky ayF aBM -aBM -aBM +crk +crk crk crk crk @@ -114337,7 +114707,7 @@ aBM aBM aBM ayF -ayF +crk ayF ayF ayF @@ -114851,7 +115221,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -115108,7 +115478,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -115879,7 +116249,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -116136,7 +116506,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -116393,7 +116763,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -116907,7 +117277,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -117164,7 +117534,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -117421,7 +117791,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -117678,7 +118048,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -117935,7 +118305,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -118192,7 +118562,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -118706,7 +119076,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM @@ -118963,7 +119333,7 @@ aBM aBM aBM ayF -ayF +crk ayF aBM aBM diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 636e0a18c4..45876d0267 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -29551,6 +29551,14 @@ /obj/machinery/light/small{ dir = 8 }, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching the test chamber."; + dir = 4; + layer = 4; + name = "Test Chamber Telescreen"; + network = list("toxins"); + pixel_x = -32 + }, /turf/open/floor/plasteel/dark, /area/science/mixing) "aVT" = ( @@ -33297,14 +33305,6 @@ /obj/structure/chair{ dir = 4 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -33806,14 +33806,6 @@ pixel_x = 24; pixel_y = -24 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -62919,6 +62911,11 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 24 }, +/obj/machinery/button/electrochromatic{ + pixel_x = 38; + pixel_y = -5; + id = "!interrogation_room" + }, /turf/open/floor/plasteel, /area/security/warden) "bWO" = ( @@ -73525,7 +73522,7 @@ }, /mob/living/simple_animal/bot/cleanbot{ auto_patrol = 1; - name = "\imprper Cleaner Bot" + name = "\improper Cleaner Bot" }, /turf/open/floor/plasteel/showroomfloor, /area/security/prison) @@ -85510,6 +85507,12 @@ "uRM" = ( /turf/open/floor/wood, /area/security/vacantoffice) +"vjT" = ( +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!interrogation_room" + }, +/turf/open/floor/plating, +/area/security/warden) "vle" = ( /obj/structure/festivus, /turf/open/floor/wood, @@ -107876,7 +107879,7 @@ agX agX agX aef -acH +vjT aBH aef aef @@ -126368,7 +126371,7 @@ bki bhQ bkN bIG -bki +bhQ bMB blH bhQ diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index 6bb3807ea4..a24d5d666d 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -707,27 +707,11 @@ /turf/open/floor/plasteel, /area/science/mixing) "acc" = ( -/obj/machinery/computer/security/telescreen/toxins{ - layer = 4; - network = list("toxins"); - pixel_y = 30 - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, /turf/open/floor/plasteel, /area/science/mixing) -"acd" = ( -/obj/machinery/computer/security/telescreen/toxins{ - layer = 4; - network = list("toxins"); - pixel_y = 30 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/science/mixing) "ace" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -1183,6 +1167,10 @@ name = "Mass Driver Door"; req_access_txt = "7" }, +/obj/machinery/computer/security/telescreen/toxins{ + dir = 1; + pixel_y = -32 + }, /turf/open/floor/plasteel, /area/science/mixing) "adg" = ( @@ -112984,7 +112972,7 @@ aAY aAY aAY abK -acd +ace acH ajC abJ @@ -134611,7 +134599,7 @@ aab aab aJw aKk -aKk +aPB aLY aMU aNT diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index d4e3f285f1..7f2fd0994c 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -3807,7 +3807,8 @@ movement_type = 1; name = "Sergeant Araneus"; real_name = "Sergeant Araneus"; - response_help = "pets"; + response_help_continuous = "pets"; + response_help_simple = "pet"; turns_per_move = 10 }, /turf/open/floor/carpet, @@ -6660,9 +6661,7 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "amc" = ( @@ -7778,9 +7777,6 @@ "aop" = ( /obj/structure/bed, /obj/item/bedsheet, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -7792,6 +7788,9 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/white, /area/security/brig) "aoq" = ( @@ -9147,6 +9146,7 @@ /area/maintenance/port/fore) "aqY" = ( /obj/machinery/computer/security/labor, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/security/brig) "aqZ" = ( @@ -10144,14 +10144,6 @@ /obj/structure/chair, /turf/open/floor/plasteel/grimy, /area/security/main) -"asN" = ( -/obj/structure/chair, -/obj/machinery/computer/security/telescreen/interrogation{ - dir = 1; - pixel_y = -30 - }, -/turf/open/floor/plasteel/grimy, -/area/security/main) "asO" = ( /obj/item/paper_bin{ pixel_x = -3; @@ -10708,7 +10700,9 @@ /turf/open/floor/plating, /area/security/main) "atZ" = ( -/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic{ + electrochromatic_id = "!interrogation_room" + }, /turf/open/floor/plating, /area/security/main) "aua" = ( @@ -11924,9 +11918,6 @@ /turf/open/floor/plating, /area/maintenance/fore) "awC" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, /obj/machinery/light/small{ dir = 1 }, @@ -14823,6 +14814,9 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/security/brig) "aCr" = ( @@ -14830,6 +14824,9 @@ name = "Court Cell"; req_access_txt = "63" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/security/brig) "aCs" = ( @@ -46062,7 +46059,7 @@ /area/bridge/showroom/corporate) "bNg" = ( /obj/machinery/light_switch{ - pixel_y = 24 + pixel_y = 25 }, /obj/machinery/light/small{ dir = 1 @@ -52627,7 +52624,9 @@ /area/maintenance/starboard) "caX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/light_switch, +/obj/machinery/light_switch{ + pixel_y = 25 + }, /turf/closed/wall, /area/maintenance/disposal/incinerator) "caY" = ( @@ -62341,7 +62340,7 @@ dir = 10 }, /obj/machinery/light_switch{ - pixel_y = 24 + pixel_y = 25 }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -63856,7 +63855,7 @@ dir = 8 }, /obj/machinery/light_switch{ - pixel_y = 24 + pixel_y = 25 }, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -66248,6 +66247,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/sign/warning/biohazard, /turf/closed/wall, /area/science/mixing) "cAM" = ( @@ -66273,14 +66273,6 @@ /obj/structure/chair{ dir = 4 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, @@ -66704,14 +66696,6 @@ pixel_x = 24; pixel_y = -24 }, -/obj/machinery/computer/security/telescreen{ - desc = "Used for watching the test chamber."; - dir = 8; - layer = 4; - name = "Test Chamber Telescreen"; - network = list("toxins"); - pixel_x = 30 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -67124,6 +67108,15 @@ req_access_txt = "7" }, /obj/effect/turf_decal/loading_area, +/obj/machinery/computer/security/telescreen{ + desc = "Used for watching the test chamber."; + dir = 4; + layer = 4; + name = "Test Chamber Telescreen"; + network = list("toxins"); + pixel_x = -32; + pixel_y = 0 + }, /turf/open/floor/plasteel, /area/science/mixing) "cCH" = ( @@ -74479,7 +74472,7 @@ dir = 8 }, /obj/machinery/light_switch{ - pixel_x = -23 + pixel_y = 25 }, /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -79797,13 +79790,13 @@ c_tag = "Chapel - Funeral Parlour"; dir = 8 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, /turf/open/floor/plasteel/dark, /area/chapel/main) "djk" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/closed/wall, /area/chapel/main) "djr" = ( @@ -80546,10 +80539,12 @@ /area/security/brig) "dBH" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/yellow{ icon_state = "0-4" }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /turf/open/floor/plating, /area/security/brig) "dBI" = ( @@ -81808,6 +81803,14 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/port) +"kRi" = ( +/obj/structure/chair, +/obj/machinery/button/electrochromatic{ + id = "!interrogation_room"; + pixel_x = -25 + }, +/turf/open/floor/plasteel/grimy, +/area/security/main) "kVo" = ( /obj/structure/cable/yellow{ icon_state = "1-2" @@ -82098,6 +82101,12 @@ /obj/item/storage/fancy/candle_box, /turf/open/floor/engine/cult, /area/library) +"oaM" = ( +/obj/machinery/computer/security/telescreen/interrogation{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/grimy, +/area/security/main) "obb" = ( /obj/structure/target_stake, /obj/effect/turf_decal/stripes/line{ @@ -82151,6 +82160,10 @@ /obj/machinery/status_display/supply, /turf/closed/wall, /area/quartermaster/sorting) +"orJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall, +/area/security/brig) "oub" = ( /obj/structure/sign/poster/official/random, /turf/closed/wall, @@ -82235,6 +82248,12 @@ }, /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) +"pvk" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/security/detectives_office) "pvA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -99872,7 +99891,7 @@ aIg aIg aKN dIs -aIg +aUe dIs aQg aIg @@ -104326,7 +104345,7 @@ cLa cPF cQb djj -djr +cQb cRq cPA aaa @@ -107306,7 +107325,7 @@ akv alO anf aop -ahx +orJ aqY asn atK @@ -112713,7 +112732,7 @@ axp dBF azO aBi -ajm +axw ajm ajm ajm @@ -113227,7 +113246,7 @@ axr ayF ayF ayF -ayF +pvk ayJ ayJ aGt @@ -115275,7 +115294,7 @@ aiJ aoK aqa arv -asM +kRi atZ avk aww @@ -115531,8 +115550,8 @@ amr anD aoL ajD -arv -asN +oaM +asM atZ avk awx @@ -118443,7 +118462,7 @@ krD czD cAL cBG -cyy +czD czD czD cFu diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 97984fa656..085522a4a5 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -2367,9 +2367,7 @@ /obj/item/seeds/cotton{ yield = 5 }, -/obj/item/seeds/cotton{ - yield = 5 - }, +/obj/item/seeds/cotton/durathread, /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) "Vj" = ( diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 8a951881f9..4fbfabaf2b 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -2150,11 +2150,6 @@ /obj/machinery/status_display/supply, /turf/closed/wall, /area/quartermaster/storage) -"adq" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/vacuum, -/turf/open/floor/plating, -/area/quartermaster/storage) "adr" = ( /obj/structure/cable{ icon_state = "4-8" @@ -37688,6 +37683,10 @@ /obj/machinery/atmospherics/miner/carbon_dioxide, /turf/open/floor/engine/co2, /area/engine/atmos) +"hQH" = ( +/obj/structure/sign/warning/vacuum, +/turf/closed/wall, +/area/quartermaster/storage) "hTn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/research/glass{ @@ -38292,14 +38291,6 @@ /obj/structure/flora/ausbushes/ywflowers, /turf/open/floor/grass, /area/hallway/secondary/entry) -"lvt" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/warning/vacuum, -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/plating, -/area/quartermaster/storage) "lvw" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible, /obj/effect/decal/cleanable/dirt, @@ -91224,7 +91215,7 @@ aac swM aeh agB -ado +adn agB ahq adp @@ -91478,13 +91469,13 @@ aaa aaa aaa aaa -adq +ado aeg aeX -adp +hQH agC ahr -lvt +ado aae aae aae diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 5f3a789f6f..c4a5c794bf 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -4058,6 +4058,7 @@ pixel_y = -3 }, /obj/item/gun/energy/e_gun/advtaser, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden, /turf/open/floor/plasteel/dark, /area/security/armory) "akM" = ( @@ -20051,20 +20052,6 @@ /obj/machinery/conveyor_switch/oneway{ id = "QMLoad" }, -/obj/machinery/button/door{ - id = "QMLoaddoor2"; - layer = 4; - name = "Loading Doors"; - pixel_x = 24; - pixel_y = -8 - }, -/obj/machinery/button/door{ - id = "QMLoaddoor"; - layer = 4; - name = "Loading Doors"; - pixel_x = 24; - pixel_y = 8 - }, /obj/machinery/camera{ c_tag = "Cargo Supply Dock"; dir = 8 @@ -21503,6 +21490,20 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/button/door{ + id = "QMLoaddoor2"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = -8 + }, +/obj/machinery/button/door{ + id = "QMLoaddoor"; + layer = 4; + name = "Loading Doors"; + pixel_x = 24; + pixel_y = 8 + }, /turf/open/floor/plasteel, /area/quartermaster/storage) "aYC" = ( @@ -52345,6 +52346,23 @@ }, /turf/open/floor/plasteel/dark, /area/library) +"cBi" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/armory) "cBk" = ( /obj/machinery/vending/boozeomat/pubby_maint, /turf/closed/wall, @@ -52521,12 +52539,6 @@ /obj/machinery/status_display/ai, /turf/closed/wall/r_wall, /area/engine/supermatter) -"cCO" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/closed/wall, -/area/security/brig) "cCP" = ( /obj/effect/turf_decal/bot/right, /turf/open/floor/plasteel/white, @@ -55211,6 +55223,9 @@ /turf/open/floor/plasteel/dark, /area/science/xenobiology) "ivO" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, /mob/living/simple_animal/bot/secbot{ arrest_type = 1; health = 45; @@ -55604,6 +55619,13 @@ }, /turf/open/floor/plasteel/dark, /area/science/xenobiology) +"juw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/armory) "jvi" = ( /obj/structure/cable{ icon_state = "4-8" @@ -58182,6 +58204,15 @@ }, /turf/open/floor/plating, /area/security/execution/transfer) +"pfB" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/cyan/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/dark, +/area/security/armory) "pfP" = ( /obj/structure/table, /obj/item/storage/box/syringes, @@ -84433,7 +84464,7 @@ aiL ajg ajP akL -alA +cBi amh amV anF @@ -84690,7 +84721,7 @@ aiM aiM ajQ akM -akM +juw ami amW anG @@ -85204,7 +85235,7 @@ aiN aji ajS akO -akO +pfB amk amY anI @@ -89068,7 +89099,7 @@ apj ajM ajM ajM -cCO +ajM ajM ajM avL diff --git a/_maps/map_files/debug/multiz.dmm b/_maps/map_files/debug/multiz.dmm index 085a64bf97..3f7cacd1a8 100644 --- a/_maps/map_files/debug/multiz.dmm +++ b/_maps/map_files/debug/multiz.dmm @@ -473,12 +473,6 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"bs" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) "bt" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -654,7 +648,9 @@ pixel_x = -25 }, /obj/structure/closet/firecloset/full, -/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, /turf/open/floor/plasteel{ dir = 9 }, @@ -793,7 +789,9 @@ }, /area/hallway/primary/central) "cl" = ( -/obj/structure/cable, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel{ dir = 8 }, @@ -3614,8 +3612,8 @@ ak aT ak ak -bs -bL +ak +bE bE bE cc @@ -3669,7 +3667,7 @@ aU bg bq ak -bL +bE bE bE cd @@ -3723,7 +3721,7 @@ bh bh br ak -bL +bE bE bE cc diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 40d02bcd0c..0a73818ab3 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -9437,7 +9437,7 @@ fh fh eY eR -fh +et eR fc fh diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 633a998fdb..66072817f4 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -58771,7 +58771,7 @@ iX iX jm jr -iX +iF jr jK iX diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 0b46f21a97..e8e75c132a 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -83,10 +83,3 @@ #define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu #define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you - -///Max length of a keypress command before it's considered to be a forged packet/bogus command -#define MAX_KEYPRESS_COMMANDLENGTH 16 -///Max amount of keypress messages per second over two seconds before client is autokicked -#define MAX_KEYPRESS_AUTOKICK 100 -///Length of max held keys -#define MAX_HELD_KEYS 15 diff --git a/code/__DEFINES/admin/keybindings.dm b/code/__DEFINES/admin/keybindings.dm new file mode 100644 index 0000000000..3efc26c7d5 --- /dev/null +++ b/code/__DEFINES/admin/keybindings.dm @@ -0,0 +1,18 @@ +// Defines for managed input/keybinding system. +/// Max length of a keypress command before it's considered to be a forged packet/bogus command +#define MAX_KEYPRESS_COMMANDLENGTH 16 +/// Maximum keys that can be bound to one button +#define MAX_COMMANDS_PER_KEY 5 +/// Maximum keys per keybind +#define MAX_KEYS_PER_KEYBIND 3 +/// Max amount of keypress messages per second over two seconds before client is autokicked +#define MAX_KEYPRESS_AUTOKICK 100 +/// Max keys that can be held down at once by a client +#define MAX_HELD_KEYS 15 + +/// Macroset name of hotkeys/keybind only/modern mode +#define SKIN_MACROSET_HOTKEYS "hotkeys" +/// Macroset name of classic hotkey mode +#define SKIN_MACROSET_CLASSIC_HOTKEYS "oldhotkeys" +/// Macroset name of classic input mode +#define SKIN_MACROSET_CLASSIC_INPUT "oldinput" diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 77ec97f47e..65e1d0e980 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -103,4 +103,9 @@ #define RCD_COMPUTER 16 #define RCD_UPGRADE_FRAMES 1 -#define RCD_UPGRADE_SIMPLE_CIRCUITS 2 \ No newline at end of file +#define RCD_UPGRADE_SIMPLE_CIRCUITS 2 + +//Electrochromatic window defines. +#define NOT_ELECTROCHROMATIC 0 +#define ELECTROCHROMATIC_OFF 1 +#define ELECTROCHROMATIC_DIMMED 2 diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index c74a8cdb05..d78cecf9b1 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -89,7 +89,7 @@ #define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) #define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user) -#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) +#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob), return flags also used by other signals. #define COMPONENT_ALLOW_EXAMINATE 1 #define COMPONENT_DENY_EXAMINATE 2 //Higher priority compared to the above one @@ -141,13 +141,17 @@ #define HEARING_SOURCE 8*/ #define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) #define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) + // /mind signals #define COMSIG_PRE_MIND_TRANSFER "pre_mind_transfer" //from base of mind/transfer_to() before it's done: (new_character, old_character) #define COMPONENT_STOP_MIND_TRANSFER 1 //stops the mind transfer from happening. #define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to() when it's done: (new_character, old_character) // /mob signals -#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A) +#define COMSIG_MOB_CLICKED_SHIFT_ON "mob_shift_click_on" //from base of /atom/ShiftClick(): (atom/A), for return values, see COMSIG_CLICK_SHIFT +#define COMSIG_MOB_FOV_VIEW "mob_visible_atoms" //from base of mob/fov_view(): (list/visible_atoms) +#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A), for return values, see COMSIG_CLICK_SHIFT + #define COMPONENT_EXAMINATE_BLIND 3 //outputs the "something is there but you can't see it" message. #define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) #define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat. #define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params) @@ -181,30 +185,14 @@ #define SPEECH_LANGUAGE 5 // #define SPEECH_IGNORE_SPAM 6 // #define SPEECH_FORCED 7 +#define COMSIG_MOB_FOV_VIEWER "mob_is_viewer" //from base of /fov_viewers(): (atom/center, depth, viewers_list) +#define COMSIG_MOB_GET_VISIBLE_MESSAGE "mob_get_visible_message" //from base of atom/visible_message(): (atom/A, msg, range, ignored_mobs) + #define COMPONENT_NO_VISIBLE_MESSAGE 1 //exactly what's said on the tin. #define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum) #define COMSIG_MOB_SPELL_CAN_CAST "mob_spell_can_cast" //from base of /obj/effect/proc_holder/spell/can_cast(): (spell) -#define COMSIG_MOB_ACTION_SKILL_MOD "mob_action_skill_mod" //from base of /datum/skill_holder/action_skills_mod() : (proc args list, list/mod_values) - #define ACTION_SKILL_MOD_SKILL 1 //redundancy. - #define ACTION_SKILL_MOD_VALUE 2 - #define ACTION_SKILL_MOD_THRESHOLD 3 - #define ACTION_SKILL_MOD_IS_MULTI 4 - //other mod values, kept separate from the args - #define MOD_VALUES_SKILL_MOD 1 - -#define COMSIG_MOB_ITEM_ACTION_SKILLS_MOD "mob_item_action_skills_mod" //from base of /datum/skill_holder/item_action_skills_mod() : (proc args list, mod_values) - #define ITEM_SKILLS_MOD_ITEM 1 //redundancy - #define ITEM_SKILLS_MOD_VALUE 2 - #define ITEM_SKILLS_MOD_FLAGS 3 - #define ITEM_SKILLS_MOD_BAD_FLAGS 4 - #define ITEM_SKILLS_MOD_IS_MULTI 5 - //other mod values, kept separate from the args - #define MOD_VALUES_ITEM_SKILLS_SUM 1 - #define MOD_VALUES_ITEM_SKILLS_DIV 2 - #define MOD_VALUES_ITEM_SKILLS_CHECKED 3 - -#define COMSIG_MOB_SKILL_GET_AFFINITY "mob_skill_get_affinity" //from base of /datum/skill_holder/get_skill_affinity(): (skill_path, list/return_value) +#define COMSIG_ROBOT_UPDATE_ICONS "robot_update_icons" //from base of robot/update_icons(): () // /mob/living signals #define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) @@ -214,9 +202,13 @@ #define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags) #define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () #define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive) -#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client) -#define COMSIG_MOB_CLIENT_LOGOUT "comsig_mob_client_logout" //sent when a mob/logout() starts: (client) -#define COMSIG_MOB_CLIENT_MOVE "comsig_mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) + +#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client) +#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client) +#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc) +#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view) + +#define COMSIG_MOB_RESET_PERSPECTIVE "mob_reset_perspective" //from base of /mob/reset_perspective(): (atom/target) #define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override) // This returns flags as defined for block in __DEFINES/combat.dm! #define COMSIG_LIVING_RUN_BLOCK "living_do_run_block" //from base of mob/living/do_run_block(): (real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone) @@ -277,6 +269,9 @@ // THE FOLLOWING TWO BLOCKS SHOULD RETURN BLOCK FLAGS AS DEFINED IN __DEFINES/combat.dm! #define COMSIG_ITEM_CHECK_BLOCK "check_block" //from base of obj/item/check_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) #define COMSIG_ITEM_RUN_BLOCK "run_block" //from base of obj/item/run_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) +// Item mouse siganls +#define COMSIG_ITEM_MOUSE_EXIT "item_mouse_exit" //from base of obj/item/MouseExited(): (location, control, params) +#define COMSIG_ITEM_MOUSE_ENTER "item_mouse_enter" //from base of obj/item/MouseEntered(): (location, control, params) #define COMSIG_ITEM_DECONSTRUCTOR_DEEPSCAN "deconstructor_deepscan" //Called by deconstructive analyzers deepscanning an item: (obj/machinery/rnd/destructive_analyzer/analyzer_machine, mob/user, list/information_list) // Uncovered information #define COMPONENT_DEEPSCAN_UNCOVERED_INFORMATION 1 @@ -323,6 +318,9 @@ #define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) #define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species) +// /datum/mutation signals +#define COMSIG_HUMAN_MUTATION_LOSS "human_mutation_loss" //from datum/mutation/human/on_losing(): (datum/mutation/human/lost_mutation) + /*******Component Specific Signals*******/ //Janitor #define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values. diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 396cf25be1..9facaf5d70 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -20,26 +20,41 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define DF_ISPROCESSING (1<<2) //FLAGS BITMASK - -#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. -#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this. -#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.) -#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff -#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay -#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving -#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows +///This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. +#define HEAR_1 (1<<3) +///Projectiels will check ricochet on things impacted that have this. +#define CHECK_RICOCHET_1 (1<<4) +///Conducts electricity (metal etc.). +#define CONDUCT_1 (1<<5) +///For machines and structures that should not break into parts, eg, holodeck stuff. +#define NODECONSTRUCT_1 (1<<7) +///Atom queued to SSoverlay. +#define OVERLAY_QUEUED_1 (1<<8) +///Item has priority to check when entering or leaving. +#define ON_BORDER_1 (1<<9) +///Prevent clicking things below it on the same turf eg. doors/ fulltile windows. +#define PREVENT_CLICK_UNDER_1 (1<<11) #define HOLOGRAM_1 (1<<12) -#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity -#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object -#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff. -#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) /// should not get harmed if this gets caught by an explosion? +///Prevents mobs from getting chainshocked by teslas and the supermatter. +#define SHOCKED_1 (1<<13) +///Whether /atom/Initialize() has already run for the object. +#define INITIALIZED_1 (1<<14) +///was this spawned by an admin? used for stat tracking stuff. +#define ADMIN_SPAWNED_1 (1<<15) +/// should not get harmed if this gets caught by an explosion? +#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) +/// Early returns mob.face_atom() +#define BLOCK_FACE_ATOM_1 (1<<17) //turf-only flags #define NOJAUNT_1 (1<<0) #define UNUSED_RESERVATION_TURF_1 (1<<1) -#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas. -#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf -#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf +///If a turf can be made dirty at roundstart. This is also used in areas. +#define CAN_BE_DIRTY_1 (1<<2) +///Blocks lava rivers being generated on the turf. +#define NO_LAVA_GEN_1 (1<<6) +///Blocks ruins spawning on the turf. +#define NO_RUINS_1 (1<<10) /* These defines are used specifically with the atom/pass_flags bitmask @@ -75,14 +90,15 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define GOLIATH_WEAKNESS (1<<9) //CIT CHANGE //tesla_zap -#define TESLA_MACHINE_EXPLOSIVE (1<<0) -#define TESLA_ALLOW_DUPLICATES (1<<1) -#define TESLA_OBJ_DAMAGE (1<<2) -#define TESLA_MOB_DAMAGE (1<<3) -#define TESLA_MOB_STUN (1<<4) +#define ZAP_MACHINE_EXPLOSIVE (1<<0) +#define ZAP_ALLOW_DUPLICATES (1<<1) +#define ZAP_OBJ_DAMAGE (1<<2) +#define ZAP_MOB_DAMAGE (1<<3) +#define ZAP_MOB_STUN (1<<4) -#define TESLA_DEFAULT_FLAGS ALL -#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN +#define ZAP_DEFAULT_FLAGS ALL +#define ZAP_FUSION_FLAGS ZAP_OBJ_DAMAGE | ZAP_MOB_DAMAGE | ZAP_MOB_STUN +#define ZAP_SUPERMATTER_FLAGS NONE //EMP protection #define EMP_PROTECT_SELF (1<<0) diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index 16d763606b..5acda2274c 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -24,6 +24,15 @@ #define FOOTPRINT_SNAKE "snake" #define FOOTPRINT_DRAG "drag" +//footstep mob defines +#define FOOTSTEP_MOB_CLAW 1 +#define FOOTSTEP_MOB_BAREFOOT 2 +#define FOOTSTEP_MOB_HEAVY 3 +#define FOOTSTEP_MOB_SHOE 4 +#define FOOTSTEP_MOB_HUMAN 5 //Warning: Only works on /mob/living/carbon/human +#define FOOTSTEP_MOB_SLIME 6 +#define FOOTSTEP_MOB_CRAWL 7 + /* id = list( diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 122ba67402..28ec3383ae 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -148,50 +148,6 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define isclown(A) (istype(A, /mob/living/simple_animal/hostile/retaliate/clown)) -GLOBAL_LIST_INIT(shoefootmob, typecacheof(list( - /mob/living/carbon/human/, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/hostile/cat_butcherer, - /mob/living/simple_animal/hostile/faithless, - /mob/living/simple_animal/hostile/nanotrasen, - /mob/living/simple_animal/hostile/pirate, - /mob/living/simple_animal/hostile/russian, - /mob/living/simple_animal/hostile/syndicate, - /mob/living/simple_animal/hostile/wizard, - /mob/living/simple_animal/hostile/zombie, - /mob/living/simple_animal/hostile/retaliate/clown, - /mob/living/simple_animal/hostile/retaliate/spaceman, - /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace, - /mob/living/simple_animal/hostile/retaliate/goat, - /mob/living/carbon/true_devil, - ))) - -GLOBAL_LIST_INIT(clawfootmob, typecacheof(list( - /mob/living/carbon/alien/humanoid, - /mob/living/simple_animal/hostile/alien, - /mob/living/simple_animal/pet/cat, - /mob/living/simple_animal/pet/dog, - /mob/living/simple_animal/pet/fox, - /mob/living/simple_animal/chicken, - /mob/living/simple_animal/hostile/bear, - /mob/living/simple_animal/hostile/jungle/mega_arachnid, - /mob/living/simple_animal/hostile/asteroid/ice_whelp, - /mob/living/simple_animal/hostile/asteroid/wolf, - /mob/living/simple_animal/hostile/asteroid/polarbear - ))) - -GLOBAL_LIST_INIT(barefootmob, typecacheof(list( - /mob/living/carbon/monkey, - /mob/living/simple_animal/pet/penguin, - /mob/living/simple_animal/hostile/gorilla, - /mob/living/simple_animal/hostile/jungle/mook - ))) - -GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list( - /mob/living/simple_animal/hostile/megafauna, - /mob/living/simple_animal/hostile/jungle/leaper - ))) - //Misc mobs #define isobserver(A) (istype(A, /mob/dead/observer)) diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index a6c31bf965..6f33bb1a0e 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -11,16 +11,38 @@ #define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX" #define OPENSPACE_LAYER 17 //Openspace layer over all -#define OPENSPACE_PLANE -4 //Openspace plane below all turfs -#define OPENSPACE_BACKDROP_PLANE -3 //Black square just over openspace plane to guaranteed cover all in openspace turf +#define OPENSPACE_PLANE -10 //Openspace plane below all turfs +#define OPENSPACE_BACKDROP_PLANE -9 //Black square just over openspace plane to guaranteed cover all in openspace turf -#define FLOOR_PLANE -2 +#define FLOOR_PLANE -8 #define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE" -#define GAME_PLANE -1 + +#define WALL_PLANE -7 +#define WALL_PLANE_RENDER_TARGET "WALL_PLANE" + +#define ABOVE_WALL_PLANE -6 +#define ABOVE_WALL_PLANE_RENDER_TARGET "ABOVE_WALL_PLANE" + +#define FIELD_OF_VISION_BLOCKER_PLANE -5 +#define FIELD_OF_VISION_BLOCKER_RENDER_TARGET "*FIELD_OF_VISION_BLOCKER_PLANE" + +#define FIELD_OF_VISION_PLANE -4 +#define FIELD_OF_VISION_RENDER_TARGET "*FIELD_OF_VISION_PLANE" +#define FIELD_OF_VISION_LAYER 17 //used to place the visual (not the mask) shadow cone above any other floor plane stuff. + +#define GAME_PLANE -3 #define GAME_PLANE_RENDER_TARGET "GAME_PLANE" + +#define FIELD_OF_VISION_VISUAL_PLANE -2 //Yea, FoV does require quite a few planes to work with 513 filters to a decent degree. +#define FIELD_OF_VISION_VISUAL_RENDER_TARGET "FIELD_OF_VISION_VISUAL_PLANE" + +#define CHAT_PLANE -1 //We don't want heard messages to be hidden by FoV. +#define CHAT_LAYER 12.1 //Legacy, it doesn't matter that much because we are displayed above the game plane anyway. + #define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals #define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE" +///Layers most often used by atoms of plane lower than GAME_PLANE #define SPACE_LAYER 1.8 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define #define MID_TURF_LAYER 2.02 @@ -40,11 +62,12 @@ #define GAS_PIPE_VISIBLE_LAYER 2.47 #define GAS_FILTER_LAYER 2.48 #define GAS_PUMP_LAYER 2.49 + #define LOW_OBJ_LAYER 2.5 #define LOW_SIGIL_LAYER 2.52 #define SIGIL_LAYER 2.54 #define HIGH_SIGIL_LAYER 2.56 - +///Layers most often used by atoms of plane equal or higher than GAME_PLANE #define BELOW_OPEN_DOOR_LAYER 2.6 #define BLASTDOOR_LAYER 2.65 #define OPEN_DOOR_LAYER 2.7 @@ -80,8 +103,9 @@ #define SPACEVINE_LAYER 4.8 #define SPACEVINE_MOB_LAYER 4.9 //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define -#define GASFIRE_LAYER 5.05 -#define RIPPLE_LAYER 5.1 +#define ABOVE_FLY_LAYER 5.1 +#define GASFIRE_LAYER 5.2 +#define RIPPLE_LAYER 5.3 #define GHOST_LAYER 6 #define LOW_LANDMARK_LAYER 9 @@ -91,8 +115,6 @@ #define MASSIVE_OBJ_LAYER 11 #define POINT_LAYER 12 -#define CHAT_LAYER 12.1 - #define EMISSIVE_BLOCKER_PLANE 12 #define EMISSIVE_BLOCKER_LAYER 12 #define EMISSIVE_BLOCKER_RENDER_TARGET "*EMISSIVE_BLOCKER_PLANE" @@ -136,19 +158,20 @@ #define HUD_LAYER 21 #define HUD_RENDER_TARGET "HUD_PLANE" -#define VOLUMETRIC_STORAGE_BOX_PLANE 23 -#define VOLUMETRIC_STORAGE_BOX_LAYER 23 +#define VOLUMETRIC_STORAGE_BOX_PLANE 22 +#define VOLUMETRIC_STORAGE_BOX_LAYER 22 #define VOLUMETRIC_STORAGE_BOX_RENDER_TARGET "VOLUME_STORAGE_BOX_PLANE" -#define VOLUMETRIC_STORAGE_ITEM_PLANE 24 -#define VOLUMETRIC_STORAGE_ITEM_LAYER 24 +#define VOLUMETRIC_STORAGE_ITEM_PLANE 23 +#define VOLUMETRIC_STORAGE_ITEM_LAYER 23 +#define VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER 25 +#define VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE 25 #define VOLUMETRIC_STORAGE_ITEM_RENDER_TARGET "VOLUME_STORAGE_ITEM_PLANE" -#define ABOVE_HUD_PLANE 25 -#define ABOVE_HUD_LAYER 25 +#define ABOVE_HUD_PLANE 30 +#define ABOVE_HUD_LAYER 30 #define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE" -#define SPLASHSCREEN_LAYER 30 -#define SPLASHSCREEN_PLANE 30 +#define SPLASHSCREEN_LAYER 90 +#define SPLASHSCREEN_PLANE 90 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" - diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 2cdd7d0240..71de692410 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -18,6 +18,7 @@ #define INVESTIGATE_CIRCUIT "circuit" #define INVESTIGATE_FERMICHEM "fermichem" #define INVESTIGATE_RCD "rcd" +#define INVESTIGATE_CRYOGENICS "cryogenics" // Logging types for log_message() #define LOG_ATTACK (1 << 0) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 55aec7022f..12828191ae 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -463,7 +463,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define PDAIMG(what) {""} //Filters -#define AMBIENT_OCCLUSION list("type"="drop_shadow","x"=0,"y"=-2,"size"=4,"color"="#04080FAA") +#define AMBIENT_OCCLUSION(_size, _color) list("type"="drop_shadow","x"=0,"y"=-2,"size"=_size,"color"=_color) #define EYE_BLUR(size) list("type"="blur", "size"=size) #define GRAVITY_MOTION_BLUR list("type"="motion_blur","x"=0,"y"=0) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e0df69bfe9..29ab67271c 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -290,8 +290,15 @@ #define HUMAN_FIRE_STACK_ICON_NUM 3 +#define TYPING_INDICATOR_TIMEOUT 5 MINUTES + #define GRAB_PIXEL_SHIFT_PASSIVE 6 #define GRAB_PIXEL_SHIFT_AGGRESSIVE 12 #define GRAB_PIXEL_SHIFT_NECK 16 #define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; + +/// Field of vision defines. +#define FOV_90_DEGREES 90 +#define FOV_180_DEGREES 180 +#define FOV_270_DEGREES 270 diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index affa23d30a..09cea91540 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -51,6 +51,19 @@ #define ASSEMBLY_FOURTH_STEP 3 #define ASSEMBLY_FIFTH_STEP 4 +//Bot Upgrade defines +#define UPGRADE_CLEANER_ADVANCED_MOP (1<<0) +#define UPGRADE_CLEANER_BROOM (1<<1) + +#define UPGRADE_MEDICAL_HYPOSPRAY (1<<0) +#define UPGRADE_MEDICAL_CHEM_BOARD (1<<1) +#define UPGRADE_MEDICAL_CRYO_BOARD (1<<2) +#define UPGRADE_MEDICAL_CHEM_MASTER (1<<3) +#define UPGRADE_MEDICAL_SLEEP_BOARD (1<<4) +#define UPGRADE_MEDICAL_PIERERCING (1<<5) + +#define UPGRADE_FLOOR_ARTBOX (1<<0) +#define UPGRADE_FLOOR_SYNDIBOX (1<<1) //Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta #define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert)) diff --git a/code/__DEFINES/rust_g.config.dm b/code/__DEFINES/rust_g.config.dm deleted file mode 100644 index 68a1b42fb1..0000000000 --- a/code/__DEFINES/rust_g.config.dm +++ /dev/null @@ -1 +0,0 @@ -#define RUSTG_OVERRIDE_BUILTINS \ No newline at end of file diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index d7b82c6c8e..aeacdb7c51 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -1,11 +1,27 @@ // rust_g.dm - DM API for rust_g extension library #define RUST_G "rust_g" +#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET" +#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB" +#define RUSTG_JOB_ERROR "JOB PANICKED" + #define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname) #define rustg_dmi_create_png(fname,width,height,data) call(RUST_G, "dmi_create_png")(fname,width,height,data) #define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev) #define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev) -#define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text) +#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format) /proc/rustg_log_close_all() return call(RUST_G, "log_close_all")() + +// RUST-G defines & procs for HTTP component +#define RUSTG_HTTP_METHOD_GET "get" +#define RUSTG_HTTP_METHOD_POST "post" +#define RUSTG_HTTP_METHOD_PUT "put" +#define RUSTG_HTTP_METHOD_DELETE "delete" +#define RUSTG_HTTP_METHOD_PATCH "patch" +#define RUSTG_HTTP_METHOD_HEAD "head" + +#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers) +#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers) +#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id) diff --git a/code/__DEFINES/skills/defines.dm b/code/__DEFINES/skills/defines.dm index 73be86e128..659c0fe11b 100644 --- a/code/__DEFINES/skills/defines.dm +++ b/code/__DEFINES/skills/defines.dm @@ -20,34 +20,34 @@ // Standard values for job starting skill affinities -#define STARTING_SKILL_AFFINITY_SURGERY_MEDICAL 1.2 - -#define STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO 1.2 +#define STARTING_SKILL_AFFINITY_DEF_JOB 1.2 // Standard values for skill gain (this is multiplied by affinity) #define DEF_SKILL_GAIN 1 #define SKILL_GAIN_SURGERY_PER_STEP 0.25 -#define SKILL_AFFINITY_MOOD_BONUS 1.25 +//An extra point for each few seconds of delay when using a tool. Before the multiplier. +#define SKILL_GAIN_DELAY_DIVISOR 3 SECONDS -///Items skill_flags and other defines -#define SKILL_USE_TOOL (1<<0) -#define SKILL_TRAINING_TOOL (1<<1) -#define SKILL_ATTACK_MOB (1<<2) -#define SKILL_TRAIN_ATTACK_MOB (1<<3) -#define SKILL_ATTACK_OBJ (1<<4) -#define SKILL_TRAIN_ATTACK_OBJ (1<<5) -#define SKILL_STAMINA_COST (1<<6) //Influences the stamina cost from weapon usage. -#define SKILL_THROW_STAM_COST (1<<7) -#define SKILL_COMBAT_MODE (1<<8) //The user must have combat mode on. -#define SKILL_USE_MOOD (1<<9) //Is the skill negatively affected by bad mood. -#define SKILL_TRAIN_MOOD (1<<10) //Is this skill training affected by good mood. +///Items skill_traits and other defines +#define SKILL_USE_TOOL "use_tool" +#define SKILL_TRAINING_TOOL "training_tool" +#define SKILL_ATTACK_MOB "attack_mob" +#define SKILL_TRAIN_ATTACK_MOB "train_attack_mob" +#define SKILL_ATTACK_OBJ "attack_obj" +#define SKILL_TRAIN_ATTACK_OBJ "train_attack_obj" +#define SKILL_STAMINA_COST "stamina_cost" //Influences the stamina cost from weapon usage. +#define SKILL_THROW_STAM_COST "throw_stam_cost" +#define SKILL_COMBAT_MODE "combat_mode" //The user must have combat mode on. +#define SKILL_SANITY "sanity" //Is the skill affected by (in)sanity. +#define SKILL_INTELLIGENCE "intelligence" //Is the skill affected by brain damage? -///competency_threshold index defines -#define THRESHOLD_COMPETENT 1 -#define THRESHOLD_EXPERT 2 -#define THRESHOLD_MASTER 3 +///competency_threshold defines +#define THRESHOLD_UNTRAINED "untrained" +#define THRESHOLD_COMPETENT "competent" +#define THRESHOLD_EXPERT "expert" +#define THRESHOLD_MASTER "master" /// Level/Experience skills defines. #define STD_XP_LVL_UP 100 @@ -75,3 +75,29 @@ #define DORF_SKILL_COMPETENT 3 #define DORF_SKILL_EXPERT 8 #define DORF_SKILL_MASTER 12 + +/// Skill modifier defines and flags. +#define MODIFIER_SKILL_VALUE (1<<0) +#define MODIFIER_SKILL_AFFINITY (1<<1) +#define MODIFIER_SKILL_LEVEL (1<<2) +///makes the skill modifier a multiplier, not an addendum. +#define MODIFIER_SKILL_MULT (1<<3) +///Sets the skill to the defined value if lower than that. Highly reccomended you don't use it with MODIFIER_SKILL_MULT. +#define MODIFIER_SKILL_VIRTUE (1<<4) +///Does the opposite of the above. combining both effectively results in the skill being locked to the specified value. +#define MODIFIER_SKILL_HANDICAP (1<<5) +///Makes it untransferred by mind.transfer_to() +#define MODIFIER_SKILL_BODYBOUND (1<<6) +///Adds the difference of the current value and the value stored at the time the modifier was added to the result. +#define MODIFIER_SKILL_ORIGIN_DIFF (1<<7) +///Will this skill use competency thresholds instead of preset values +#define MODIFIER_USE_THRESHOLDS (1<<8) + +#define MODIFIER_TARGET_VALUE "value" +#define MODIFIER_TARGET_LEVEL "level" +#define MODIFIER_TARGET_AFFINITY "affinity" + +///Ascending priority defines. +#define MODIFIER_SKILL_PRIORITY_LOW 100 +#define MODIFIER_SKILL_PRIORITY_DEF 50 +#define MODIFIER_SKILL_PRIORITY_MAX 1 //max priority, meant for job/antag modifiers so they don't null out other (de)buffs \ No newline at end of file diff --git a/code/__DEFINES/skills/helpers.dm b/code/__DEFINES/skills/helpers.dm index 23669b3739..dde412fd7d 100644 --- a/code/__DEFINES/skills/helpers.dm +++ b/code/__DEFINES/skills/helpers.dm @@ -6,3 +6,43 @@ //More experience value getter macros #define GET_STANDARD_LVL(lvl) XP_LEVEL(STD_XP_LVL_UP, STD_XP_LVL_MULTI, lvl) #define GET_DORF_LVL(lvl) DORF_XP_LEVEL(DORF_XP_LVL_UP, DORF_XP_LVL_MULTI, lvl) + +#define IS_SKILL_VALUE_GREATER(path, existing, new_value) GLOB.skill_datums[path].is_value_greater(existing, new_value) + +#define SANITIZE_SKILL_VALUE(path, value) GLOB.skill_datums[path].sanitize_value(value) + +///Doesn't automatically round the value. +#define SANITIZE_SKILL_LEVEL(path, lvl) clamp(lvl, 0, GLOB.skill_datums[path].max_levels) + +/// Simple generic identifier macro. +#define GET_SKILL_MOD_ID(path, id) (id ? "[path]&[id]" : path) + +/** + * A simple universal comsig for body bound skill modifiers. + * Technically they are still bound to the mind, but other signal procs will take care of adding and removing the modifier + * from/to new/old minds. + */ +#define ADD_SKILL_MODIFIER_BODY(path, id, body, prototype) \ + prototype = GLOB.skill_modifiers[GET_SKILL_MOD_ID(path, id)] || new path(id, TRUE);\ + if(body.mind){\ + body.mind.add_skill_modifier(prototype.identifier)\ + } else {\ + prototype.RegisterSignal(body, COMSIG_MOB_ON_NEW_MIND, /datum/skill_modifier.proc/on_mob_new_mind, TRUE)\ + } + +/// Same as above but to remove the skill modifier. +#define REMOVE_SKILL_MODIFIER_BODY(path, id, body) \ + if(GLOB.skill_modifiers[GET_SKILL_MOD_ID(path, id)]){\ + if(body.mind){\ + body.mind.remove_skill_modifier(GET_SKILL_MOD_ID(path, id))\ + } else {\ + GLOB.skill_modifiers[GET_SKILL_MOD_ID(path, id)].UnregisterSignal(body, COMSIG_MOB_ON_NEW_MIND)\ + }\ + } + +///Macro used when adding generic singleton skill modifiers. +#define ADD_SINGLETON_SKILL_MODIFIER(mind, path, id) \ + if(!GLOB.skill_modifiers[GET_SKILL_MOD_ID(path, id)]){\ + new path(id, TRUE)\ + };\ + mind.add_skill_modifier(GET_SKILL_MOD_ID(path, id)) diff --git a/code/__DEFINES/storage.dm b/code/__DEFINES/storage/_storage.dm similarity index 79% rename from code/__DEFINES/storage.dm rename to code/__DEFINES/storage/_storage.dm index b4240455fe..3a05293d2d 100644 --- a/code/__DEFINES/storage.dm +++ b/code/__DEFINES/storage/_storage.dm @@ -11,7 +11,21 @@ #define STORAGE_LIMIT_MAX_W_CLASS (1<<3) #define STORAGE_FLAGS_LEGACY_DEFAULT (STORAGE_LIMIT_MAX_ITEMS | STORAGE_LIMIT_COMBINED_W_CLASS | STORAGE_LIMIT_MAX_W_CLASS) -#define STORAGE_FLAGS_VOLUME_DEFAULT (STORAGE_LIMIT_MAX_ITEMS | STORAGE_LIMIT_VOLUME | STORAGE_LIMIT_MAX_W_CLASS) +#define STORAGE_FLAGS_VOLUME_DEFAULT (STORAGE_LIMIT_VOLUME | STORAGE_LIMIT_MAX_W_CLASS) + +// UI defines +/// Size of volumetric box icon +#define VOLUMETRIC_STORAGE_BOX_ICON_SIZE 32 +/// Size of EACH left/right border icon for volumetric boxes +#define VOLUMETRIC_STORAGE_BOX_BORDER_SIZE 1 +/// Minimum pixels an item must have in volumetric scaled storage UI +#define MINIMUM_PIXELS_PER_ITEM 8 +/// Maximum number of objects that will be allowed to be displayed using the volumetric display system. Arbitrary number to prevent server lockups. +#define MAXIMUM_VOLUMETRIC_ITEMS 256 +/// How much padding to give between items +#define VOLUMETRIC_STORAGE_ITEM_PADDING 4 +/// How much padding to give to edges +#define VOLUMETRIC_STORAGE_EDGE_PADDING 1 //ITEM INVENTORY WEIGHT, FOR w_class /// Usually items smaller then a human hand, ex: Playing Cards, Lighter, Scalpel, Coins/Money @@ -26,22 +40,3 @@ #define WEIGHT_CLASS_HUGE 5 /// Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe - Can not fit in Boh #define WEIGHT_CLASS_GIGANTIC 6 - -/// Macro for automatically getting the volume of an item from its w_class. -#define AUTO_SCALE_VOLUME(w_class) (2 ** w_class) -/// Macro for automatically getting the volume of a storage item from its max_w_class and max_combined_w_class. -#define AUTO_SCALE_STORAGE_VOLUME(w_class, max_combined_w_class) (AUTO_SCALE_VOLUME(w_class) * (max_combined_w_class / w_class)) - -// UI defines -/// Size of volumetric box icon -#define VOLUMETRIC_STORAGE_BOX_ICON_SIZE 32 -/// Size of EACH left/right border icon for volumetric boxes -#define VOLUMETRIC_STORAGE_BOX_BORDER_SIZE 1 -/// Minimum pixels an item must have in volumetric scaled storage UI -#define MINIMUM_PIXELS_PER_ITEM 6 -/// Maximum number of objects that will be allowed to be displayed using the volumetric display system. Arbitrary number to prevent server lockups. -#define MAXIMUM_VOLUMETRIC_ITEMS 256 -/// How much padding to give between items -#define VOLUMETRIC_STORAGE_ITEM_PADDING 1 -/// How much padding to give to edges -#define VOLUMETRIC_STORAGE_EDGE_PADDING 1 diff --git a/code/__DEFINES/storage/volumetrics.dm b/code/__DEFINES/storage/volumetrics.dm new file mode 100644 index 0000000000..62eaa226c4 --- /dev/null +++ b/code/__DEFINES/storage/volumetrics.dm @@ -0,0 +1,39 @@ +// PLEASE KEEP ALL VOLUME DEFINES IN THIS FILE, it's going to be hell to keep track of them later. + +#define DEFAULT_VOLUME_TINY 2 +#define DEFAULT_VOLUME_SMALL 3 +#define DEFAULT_VOLUME_NORMAL 4 +#define DEFAULT_VOLUME_BULKY 8 +#define DEFAULT_VOLUME_HUGE 16 +#define DEFAULT_VOLUME_GIGANTIC 32 + +GLOBAL_LIST_INIT(default_weight_class_to_volume, list( + "[WEIGHT_CLASS_TINY]" = DEFAULT_VOLUME_TINY, + "[WEIGHT_CLASS_SMALL]" = DEFAULT_VOLUME_SMALL, + "[WEIGHT_CLASS_NORMAL]" = DEFAULT_VOLUME_NORMAL, + "[WEIGHT_CLASS_BULKY]" = DEFAULT_VOLUME_BULKY, + "[WEIGHT_CLASS_HUGE]" = DEFAULT_VOLUME_HUGE, + "[WEIGHT_CLASS_GIGANTIC]" = DEFAULT_VOLUME_GIGANTIC + )) + +/// Macro for automatically getting the volume of an item from its w_class. +#define AUTO_SCALE_VOLUME(w_class) (GLOB.default_weight_class_to_volume["[w_class]"]) +/// Macro for automatically getting the volume of a storage item from its max_w_class and max_combined_w_class. +#define AUTO_SCALE_STORAGE_VOLUME(w_class, max_combined_w_class) (AUTO_SCALE_VOLUME(w_class) * (max_combined_w_class / w_class)) + +// Let's keep all of this in one place. given what we put above anyways.. + +// volume amount for items +#define ITEM_VOLUME_DISK DEFAULT_VOLUME_TINY + +// #define SAMPLE_VOLUME_AMOUNT 2 + +// max_weight_class for storages +#define MAX_WEIGHT_CLASS_BACKPACK WEIGHT_CLASS_NORMAL +#define MAX_WEIGHT_CLASS_BAG_OF_HOLDING WEIGHT_CLASS_BULKY + +// max_volume for storages +#define STORAGE_VOLUME_BACKPACK (DEFAULT_VOLUME_NORMAL * 7) +#define STORAGE_VOLUME_DUFFLEBAG (DEFAULT_VOLUME_NORMAL * 10) +#define STORAGE_VOLUME_BAG_OF_HOLDING (DEFAULT_VOLUME_NORMAL * 20) + diff --git a/code/__DEFINES/tgs.config.dm b/code/__DEFINES/tgs.config.dm index 9f4f63a1fc..a2fcc7855a 100644 --- a/code/__DEFINES/tgs.config.dm +++ b/code/__DEFINES/tgs.config.dm @@ -4,8 +4,9 @@ #define TGS_READ_GLOBAL(Name) GLOB.##Name #define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value #define TGS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") -#define TGS_INFO_LOG(message) log_world("TGS: Info: [##message]") -#define TGS_ERROR_LOG(message) log_world("TGS: Error: [##message]") +#define TGS_INFO_LOG(message) log_world("TGS Info: [##message]") +#define TGS_WARNING_LOG(message) log_world("TGS Warn: [##message]") +#define TGS_ERROR_LOG(message) log_world("TGS Error: [##message]") #define TGS_NOTIFY_ADMINS(event) message_admins(##event) #define TGS_CLIENT_COUNT GLOB.clients.len #define TGS_PROTECT_DATUM(Path) GENERAL_PROTECT_DATUM(##Path) diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index dcccfc9295..e164a4ec96 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,5 +1,7 @@ //tgstation-server DMAPI +#define TGS_DMAPI_VERSION "5.1.1" + //All functions and datums outside this document are subject to change with any version and should not be relied on //CONFIGURATION @@ -17,7 +19,6 @@ //Required interfaces (fill in with your codebase equivalent): //create a global variable named `Name` and set it to `Value` -//These globals must not be modifiable from anywhere outside of the server tools #define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) //Read the value in the global variable `Name` @@ -26,10 +27,10 @@ //Set the value in the global variable `Name` to `Value` #define TGS_WRITE_GLOBAL(Name, Value) -//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game priveledge escalation +//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities #define TGS_PROTECT_DATUM(Path) -//display an announcement `message` from the server to all players +//Display an announcement `message` from the server to all players #define TGS_WORLD_ANNOUNCE(message) //Notify current in-game administrators of a string `event` @@ -38,6 +39,9 @@ //Write an info `message` to a server log #define TGS_INFO_LOG(message) +//Write an warning `message` to a server log +#define TGS_WARNING_LOG(message) + //Write an error `message` to a server log #define TGS_ERROR_LOG(message) @@ -48,10 +52,12 @@ //EVENT CODES -#define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port -#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums +#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //Before a reboot mode change, extras parameters are the current and new reboot mode enums +#define TGS_EVENT_PORT_SWAP -2 //Before a port change is about to happen, extra parameters is new port +#define TGS_EVENT_INSTANCE_RENAMED -3 //Before the instance is renamed, extra parameter is the new name +#define TGS_EVENT_WATCHDOG_REATTACH -4 //After the watchdog reattaches to DD, extra parameter is the new /datum/tgs_version of the server -//See the descriptions for these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs +//See the descriptions for the parameters of these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs #define TGS_EVENT_REPO_RESET_ORIGIN 0 #define TGS_EVENT_REPO_CHECKOUT 1 #define TGS_EVENT_REPO_FETCH 2 @@ -63,9 +69,12 @@ #define TGS_EVENT_COMPILE_START 8 #define TGS_EVENT_COMPILE_CANCELLED 9 #define TGS_EVENT_COMPILE_FAILURE 10 -#define TGS_EVENT_COMPILE_COMPLETE 11 +#define TGS_EVENT_COMPILE_COMPLETE 11 // Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the TGS_EVENT_DEPLOYMENT_COMPLETE instead #define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12 #define TGS_EVENT_REPO_MERGE_CONFLICT 13 +#define TGS_EVENT_DEPLOYMENT_COMPLETE 14 +#define TGS_EVENT_WATCHDOG_SHUTDOWN 15 +#define TGS_EVENT_WATCHDOG_DETACH 16 //OTHER ENUMS @@ -80,6 +89,7 @@ //REQUIRED HOOKS //Call this somewhere in /world/New() that is always run +//IMPORTANT: This function may sleep! //event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels //minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated /world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) @@ -109,12 +119,12 @@ //represents a version of tgstation-server /datum/tgs_version - var/suite //The suite version, can be >=3 + var/suite //The suite/major version, can be >=3 //this group of variables can be null to represent a wild card - var/major //The major version var/minor //The minor version var/patch //The patch version + var/deprecated_patch //The legacy version var/raw_parameter //The unparsed parameter var/deprefixed_parameter //The version only bit of raw_parameter @@ -123,6 +133,10 @@ /datum/tgs_version/proc/Wildcard() return +//if the tgs_version equals some other_version +/datum/tgs_version/proc/Equals(datum/tgs_version/other_version) + return + //represents a merge of a GitHub pull request /datum/tgs_revision_information/test_merge var/number //pull request number @@ -179,14 +193,45 @@ return //Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise -//No function below this succeeds if it returns FALSE +//No function below this succeeds if it returns FALSE or if TgsNew() has yet to be called /world/proc/TgsAvailable() return +//Forces a hard reboot of BYOND by ending the process +//unlike del(world) clients will try to reconnect +//If the service has not requested a shutdown, the next server will take over +/world/proc/TgsEndProcess() + return + +//Send a message to non-admin connected chats +//message: The message to send +//admin_only: If TRUE, message will instead be sent to only admin connected chats +/world/proc/TgsTargetedChatBroadcast(message, admin_only) + return + +//Send a private message to a specific user +//message: The message to send +//user: The /datum/tgs_chat_user to send to +/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) + return + +//The following functions will sleep if a call to TgsNew() is sleeping + +//Sends a message to connected game chats +//message: The message to send +//channels: optional channels to limit the broadcast to +/world/proc/TgsChatBroadcast(message, list/channels) + return + //Gets the current /datum/tgs_version of the server tools running the server /world/proc/TgsVersion() return +//Gets the current /datum/tgs_version of the DMAPI being used +/world/proc/TgsApiVersion() + return + +//Gets the name of the TGS instance running the game /world/proc/TgsInstanceName() return @@ -202,34 +247,10 @@ /world/proc/TgsTestMerges() return -//Forces a hard reboot of BYOND by ending the process -//unlike del(world) clients will try to reconnect -//If the service has not requested a shutdown, the next server will take over -/world/proc/TgsEndProcess() - return - //Gets a list of connected tgs_chat_channel /world/proc/TgsChatChannelInfo() return -//Sends a message to connected game chats -//message: The message to send -//channels: optional channels to limit the broadcast to -/world/proc/TgsChatBroadcast(message, list/channels) - return - -//Send a message to non-admin connected chats -//message: The message to send -//admin_only: If TRUE, message will instead be sent to only admin connected chats -/world/proc/TgsTargetedChatBroadcast(message, admin_only) - return - -//Send a private message to a specific user -//message: The message to send -//user: The /datum/tgs_chat_user to send to -/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) - return - /* The MIT License @@ -255,4 +276,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ \ No newline at end of file +*/ diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 91a4a6f2c3..a63a59c75f 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -88,6 +88,7 @@ #define TRAIT_SLEEPIMMUNE "sleep_immunity" #define TRAIT_PUSHIMMUNE "push_immunity" #define TRAIT_SHOCKIMMUNE "shock_immunity" +#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity" #define TRAIT_STABLEHEART "stable_heart" #define TRAIT_STABLELIVER "stable_liver" #define TRAIT_RESISTHEAT "resist_heat" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 32bf4b66f9..64438a163e 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -123,3 +123,6 @@ // misc #define VV_HK_SPACEVINE_PURGE "spacevine_purge" #define VV_HK_REMOVE_PAINTING "remove_painting" + +// paintings +#define VV_HK_REMOVE_PAINTING "remove_painting" diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index 86e8d1bc2b..5e57dd5328 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -1,9 +1,6 @@ //THIS FILE CONTAINS CONSTANTS, PROCS, AND OTHER THINGS// ///////////////////////////////////////////////////////// -/mob/proc/setClickCooldown(var/timeout) - next_move = max(world.time + timeout, next_move) - /proc/get_matrix_largest() var/matrix/mtrx=new() return mtrx.Scale(2) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index c913a8ea5c..ba29205452 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -37,6 +37,7 @@ * TYPECONT: The typepath of the contents of the list * COMPARE: The object to compare against, usualy the same as INPUT * COMPARISON: The variable on the objects to compare + * COMPTYPE: How the current bin item to compare against COMPARE is fetched. By key or value. */ #define BINARY_INSERT(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \ do {\ @@ -670,3 +671,13 @@ for(var/key in input) ret += key return ret + +/proc/is_type_in_ref_list(path, list/L) + if(!ispath(path))//not a path + return + for(var/i in L) + var/datum/D = i + if(!istype(D))//not an usable reference + continue + if(istype(D, path)) + return TRUE diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 362dbbe802..7b304f968d 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -4,7 +4,9 @@ #define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound) #define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text) #define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text) -#define WRITE_LOG(log, text) rustg_log_write(log, text) +//This is an external call, "true" and "false" are how rust parses out booleans +#define WRITE_LOG(log, text) rustg_log_write(log, text, "true") +#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false") //print a warning message to world.log #define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].") diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ac07b80900..38b1d0500e 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -270,6 +270,15 @@ SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing, .) processing += A.contents +//viewers() but with a signal, for blacklisting. +/proc/fov_viewers(depth = world.view, atom/center) + if(!center) + return + . = viewers(depth, center) + for(var/k in .) + var/mob/M = k + SEND_SIGNAL(M, COMSIG_MOB_FOV_VIEWER, center, depth, .) + /proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios) . = list() // Returns a list of mobs who can hear any of the radios given in @radios diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index bcfaa1bed2..0b5c60a95a 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -75,6 +75,8 @@ var/datum/emote/E = new path() E.emote_list[E.key] = E + init_keybindings() + //Uplink Items for(var/path in subtypesof(/datum/uplink_item)) var/datum/uplink_item/I = path diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index dadd4322fb..cbe1817233 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -18,6 +18,12 @@ return text return default +/proc/sanitize_islist(value, default) + if(islist(value) && length(value)) + return value + if(default) + return default + /proc/sanitize_inlist(value, list/List, default) if(value in List) return value diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 09047d32bf..2c8497d5ed 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -629,3 +629,45 @@ return null r += ascii2text(c) return r + +/proc/slot_to_string(slot) + switch(slot) + if(SLOT_BACK) + return "Backpack" + if(SLOT_WEAR_MASK) + return "Mask" + if(SLOT_HANDS) + return "Hands" + if(SLOT_BELT) + return "Belt" + if(SLOT_EARS) + return "Ears" + if(SLOT_GLASSES) + return "Glasses" + if(SLOT_GLOVES) + return "Gloves" + if(SLOT_NECK) + return "Neck" + if(SLOT_HEAD) + return "Head" + if(SLOT_SHOES) + return "Shoes" + if(SLOT_WEAR_SUIT) + return "Suit" + if(SLOT_W_UNIFORM) + return "Uniform" + if(SLOT_IN_BACKPACK) + return "In backpack" + +/proc/tg_ui_icon_to_cit_ui(ui_style) + switch(ui_style) + if('icons/mob/screen_plasmafire.dmi') + return 'modular_citadel/icons/ui/screen_plasmafire.dmi' + if('icons/mob/screen_slimecore.dmi') + return 'modular_citadel/icons/ui/screen_slimecore.dmi' + if('icons/mob/screen_operative.dmi') + return 'modular_citadel/icons/ui/screen_operative.dmi' + if('icons/mob/screen_clockwork.dmi') + return 'modular_citadel/icons/ui/screen_clockwork.dmi' + else + return 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index b2c6c94590..1f6c9c13a9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1,5 +1,3 @@ - - /* * A large number of misc global procs. */ @@ -391,6 +389,16 @@ Turf and target are separate in case you want to teleport some distance from a t break return loc +//Returns a list of all locations the target is within. +/proc/get_nested_locs(atom/movable/M, include_turf = FALSE) + . = list() + var/atom/A = M.loc + while(A && !isturf(A)) + . += A + A = A.loc + if(A && include_turf) //At this point, only the turf is left. + . += A + // returns the turf located at the map edge in the specified direction relative to A // used for mass driver /proc/get_edge_target_turf(atom/A, direction) @@ -1594,8 +1602,13 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) //empty string - use TgsTargetBroadcast with admin_only = FALSE //other string - use TgsChatBroadcast with the tag that matches config_setting, only works with TGS4, if using TGS3 the above method is used /proc/send2chat(message, config_setting) - if(config_setting == null || !world.TgsAvailable()) + if(config_setting == null) return + + UNTIL(GLOB.tgs_initialized) + if(!world.TgsAvailable()) + return + var/datum/tgs_version/version = world.TgsVersion() if(config_setting == "" || version.suite == 3) world.TgsTargetedChatBroadcast(message, FALSE) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 52eff15492..1aab96f85e 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -132,9 +132,11 @@ GLOBAL_LIST_INIT(bitfields, list( "NO_RUINS_1" = NO_RUINS_1, "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, "HOLOGRAM_1" = HOLOGRAM_1, - "TESLA_IGNORE_1" = TESLA_IGNORE_1, + "SHOCKED_1" = SHOCKED_1, "INITIALIZED_1" = INITIALIZED_1, "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, + "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1, + "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1 ), "clothing_flags" = list( "LAVAPROTECT" = LAVAPROTECT, @@ -148,12 +150,12 @@ GLOBAL_LIST_INIT(bitfields, list( "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, "SCAN_REAGENTS" = SCAN_REAGENTS ), - "tesla_flags" = list( - "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE, - "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE, - "TESLA_MOB_STUN" = TESLA_MOB_STUN, - "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES, - "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE, + "zap_flags" = list( + "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE, + "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE, + "ZAP_MOB_STUN" = ZAP_MOB_STUN, + "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES, + "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE, ), "smooth" = list( "SMOOTH_TRUE" = SMOOTH_TRUE, diff --git a/code/_globalvars/lists/client.dm b/code/_globalvars/lists/client.dm new file mode 100644 index 0000000000..5181d870c4 --- /dev/null +++ b/code/_globalvars/lists/client.dm @@ -0,0 +1,21 @@ +GLOBAL_LIST_EMPTY(classic_keybinding_list_by_key) +GLOBAL_LIST_EMPTY(hotkey_keybinding_list_by_key) +GLOBAL_LIST_EMPTY(keybindings_by_name) + +// This is a mapping from JS keys to Byond - ref: https://keycode.info/ +GLOBAL_LIST_INIT(_kbMap, list( + "UP" = "North", + "RIGHT" = "East", + "DOWN" = "South", + "LEFT" = "West", + "INSERT" = "Insert", + "HOME" = "Northwest", + "PAGEUP" = "Northeast", + "DEL" = "Delete", + "END" = "Southwest", + "PAGEDOWN" = "Southeast", + "SPACEBAR" = "Space", + "ALT" = "Alt", + "SHIFT" = "Shift", + "CONTROL" = "Ctrl" + )) diff --git a/code/_globalvars/lists/keybindings.dm b/code/_globalvars/lists/keybindings.dm new file mode 100644 index 0000000000..7e5b016a95 --- /dev/null +++ b/code/_globalvars/lists/keybindings.dm @@ -0,0 +1,31 @@ +/// Creates and sorts all the keybinding datums +/proc/init_keybindings() + for(var/KB in subtypesof(/datum/keybinding)) + var/datum/keybinding/keybinding = KB + if(!initial(keybinding.hotkey_keys)) + continue + add_keybinding(new keybinding) + // init_emote_keybinds() - Disabled - I don't particularly want this. + +/// Adds an instanced keybinding to the global tracker +/proc/add_keybinding(datum/keybinding/instance) + GLOB.keybindings_by_name[instance.name] = instance + + // Classic + if(LAZYLEN(instance.classic_keys)) + for(var/bound_key in instance.classic_keys) + LAZYADD(GLOB.classic_keybinding_list_by_key[bound_key], list(instance.name)) + + // Hotkey + if(LAZYLEN(instance.hotkey_keys)) + for(var/bound_key in instance.hotkey_keys) + LAZYADD(GLOB.hotkey_keybinding_list_by_key[bound_key], list(instance.name)) + +/proc/init_emote_keybinds() + for(var/i in subtypesof(/datum/emote)) + var/datum/emote/faketype = i + if(!initial(faketype.key)) + continue + var/datum/keybinding/emote/emote_kb = new + emote_kb.link_to_emote(faketype) + add_keybinding(emote_kb) diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index dd8b9f0d94..1b100bebaf 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -29,6 +29,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SLEEPIMMUNE" = TRAIT_SLEEPIMMUNE, "TRAIT_PUSHIMMUNE" = TRAIT_PUSHIMMUNE, "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, + "TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE, "TRAIT_STABLEHEART" = TRAIT_STABLEHEART, "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, "TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT, diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 9ce96585d3..5d2f916fba 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -77,7 +77,7 @@ if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON) return - + var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["middle"]) ShiftMiddleClickOn(A) @@ -324,10 +324,9 @@ return /atom/proc/ShiftClick(mob/user) - var/flags = SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) + var/flags = SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) | SEND_SIGNAL(user, COMSIG_MOB_CLICKED_SHIFT_ON, src) if(!(flags & COMPONENT_DENY_EXAMINATE) && user.client && (user.client.eye == user || user.client.eye == user.loc || flags & COMPONENT_ALLOW_EXAMINATE)) user.examinate(src) - return /* Ctrl click @@ -424,32 +423,36 @@ LE.fire() // Simple helper to face what you clicked on, in case it should be needed in more than one place -/mob/proc/face_atom(atom/A) - if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y ) +/mob/proc/face_atom(atom/A, ismousemovement = FALSE) + if( buckled || stat != CONSCIOUS || !loc || !A || !A.x || !A.y ) return - var/dx = A.x - x - var/dy = A.y - y + var/atom/L = loc + if(L.flags_1 & BLOCK_FACE_ATOM_1) + return + var/turf/T = get_turf(src) + var/dx = A.x - T.x + var/dy = A.y - T.y if(!dx && !dy) // Wall items are graphically shifted but on the floor if(A.pixel_y > 16) - setDir(NORTH) + setDir(NORTH, ismousemovement) else if(A.pixel_y < -16) - setDir(SOUTH) + setDir(SOUTH, ismousemovement) else if(A.pixel_x > 16) - setDir(EAST) + setDir(EAST, ismousemovement) else if(A.pixel_x < -16) - setDir(WEST) + setDir(WEST, ismousemovement) return if(abs(dx) < abs(dy)) if(dy > 0) - setDir(NORTH) + setDir(NORTH, ismousemovement) else - setDir(SOUTH) + setDir(SOUTH, ismousemovement) else if(dx > 0) - setDir(EAST) + setDir(EAST, ismousemovement) else - setDir(WEST) + setDir(WEST, ismousemovement) //debug /obj/screen/proc/scale_to(x1,y1) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index a0dade37bd..7a8b0a1121 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -24,6 +24,10 @@ blend_mode = BLEND_MULTIPLY alpha = 255 +/obj/screen/plane_master/openspace/Initialize() + . = ..() + filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE) + /obj/screen/plane_master/openspace/backdrop(mob/mymob) filters = list() filters += filter(type = "drop_shadow", color = "#04080FAA", size = -10) @@ -46,6 +50,32 @@ appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY +/obj/screen/plane_master/wall + name = "wall plane master" + plane = WALL_PLANE + appearance_flags = PLANE_MASTER + +/obj/screen/plane_master/wall/backdrop(mob/mymob) + if(mymob?.client?.prefs.ambientocclusion) + add_filter("ambient_occlusion", 0, AMBIENT_OCCLUSION(4, "#04080FAA")) + else + remove_filter("ambient_occlusion") + +/obj/screen/plane_master/above_wall + name = "above wall plane master" + plane = ABOVE_WALL_PLANE + appearance_flags = PLANE_MASTER + +/obj/screen/plane_master/above_wall/Initialize() + . = ..() + add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) + +/obj/screen/plane_master/above_wall/backdrop(mob/mymob) + if(mymob?.client?.prefs.ambientocclusion) + add_filter("ambient_occlusion", 0, AMBIENT_OCCLUSION(3, "#04080F64")) + else + remove_filter("ambient_occlusion") + ///Contains most things in the game world /obj/screen/plane_master/game_world name = "game world plane master" @@ -53,12 +83,50 @@ appearance_flags = PLANE_MASTER //should use client color blend_mode = BLEND_OVERLAY +/obj/screen/plane_master/game_world/Initialize() + . = ..() + add_filter("vision_cone", 100, list(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE)) + /obj/screen/plane_master/game_world/backdrop(mob/mymob) - if(istype(mymob) && mymob.client && mymob.client.prefs && mymob.client.prefs.ambientocclusion) - add_filter("ambient_occlusion", 0, AMBIENT_OCCLUSION) + if(mymob?.client?.prefs.ambientocclusion) + add_filter("ambient_occlusion", 0, AMBIENT_OCCLUSION(4, "#04080FAA")) else remove_filter("ambient_occlusion") - update_filters() + +//Reserved to chat messages, so they are still displayed above the field of vision masking. +/obj/screen/plane_master/chat_messages + name = "chat messages plane master" + plane = CHAT_PLANE + appearance_flags = PLANE_MASTER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +///Contains all shadow cone masks, whose image overrides are displayed only to their respective owners. +/obj/screen/plane_master/field_of_vision + name = "field of vision mask plane master" + plane = FIELD_OF_VISION_PLANE + render_target = FIELD_OF_VISION_RENDER_TARGET + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/plane_master/field_of_vision/Initialize() + . = ..() + filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) + +///Used to display the owner and its adjacent surroundings through the FoV plane mask. +/obj/screen/plane_master/field_of_vision_blocker + name = "field of vision blocker plane master" + plane = FIELD_OF_VISION_BLOCKER_PLANE + render_target = FIELD_OF_VISION_BLOCKER_RENDER_TARGET + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +///Stores the visible portion of the FoV shadow cone. +/obj/screen/plane_master/field_of_vision_visual + name = "field of vision visual plane master" + plane = FIELD_OF_VISION_VISUAL_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/plane_master/field_of_vision_visual/Initialize() + . = ..() + filters += filter(type="alpha", render_source=FIELD_OF_VISION_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) ///Contains all lighting objects /obj/screen/plane_master/lighting @@ -87,11 +155,12 @@ /obj/screen/plane_master/emissive/Initialize() . = ..() filters += filter(type="alpha", render_source=EMISSIVE_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) + filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE) /** * Things placed on this always mask the lighting plane. Doesn't render directly. * - * Always masks the light plane, isn't blocked by anything. Use for on mob glows, + * Always masks the light plane, isn't blocked by anything (except Field of Vision). Use for on mob glows, * magic stuff, etc. */ @@ -101,6 +170,10 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT render_target = EMISSIVE_UNBLOCKABLE_RENDER_TARGET +/obj/screen/plane_master/emissive_unblockable/Initialize() + . = ..() + filters += filter(type="alpha", render_source=FIELD_OF_VISION_RENDER_TARGET, flags=MASK_INVERSE) + /** * Things placed on this layer mask the emissive layer. Doesn't render directly * diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 1dce4ecc42..1ead41d513 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -238,6 +238,7 @@ GLOBAL_LIST_EMPTY(radial_menus) var/mutable_appearance/MA = new /mutable_appearance(E) if(MA) MA.layer = ABOVE_HUD_LAYER + MA.plane = ABOVE_HUD_PLANE MA.appearance_flags |= RESET_TRANSFORM return MA diff --git a/code/_onclick/hud/screen_objects/storage.dm b/code/_onclick/hud/screen_objects/storage.dm index bdcca70d9b..d7d711917d 100644 --- a/code/_onclick/hud/screen_objects/storage.dm +++ b/code/_onclick/hud/screen_objects/storage.dm @@ -54,10 +54,14 @@ /obj/screen/storage/volumetric_box icon_state = "stored_continue" + layer = VOLUMETRIC_STORAGE_BOX_LAYER + plane = VOLUMETRIC_STORAGE_BOX_PLANE var/obj/item/our_item -/obj/screen/storage/volumetric_box/Initialize(mapload, new_master, our_item) +/obj/screen/storage/volumetric_box/Initialize(mapload, new_master, obj/item/our_item) src.our_item = our_item + RegisterSignal(our_item, COMSIG_ITEM_MOUSE_ENTER, .proc/on_item_mouse_enter) + RegisterSignal(our_item, COMSIG_ITEM_MOUSE_EXIT, .proc/on_item_mouse_exit) return ..() /obj/screen/storage/volumetric_box/Destroy() @@ -70,10 +74,30 @@ /obj/screen/storage/volumetric_box/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) return our_item.MouseDrop(over, src_location, over_location, src_control, over_control, params) +/obj/screen/storage/volumetric_box/MouseExited(location, control, params) + makeItemInactive() + +/obj/screen/storage/volumetric_box/MouseEntered(location, control, params) + makeItemActive() + +/obj/screen/storage/volumetric_box/proc/on_item_mouse_enter() + makeItemActive() + +/obj/screen/storage/volumetric_box/proc/on_item_mouse_exit() + makeItemInactive() + +/obj/screen/storage/volumetric_box/proc/makeItemInactive() + our_item.layer = VOLUMETRIC_STORAGE_ITEM_LAYER + our_item.plane = VOLUMETRIC_STORAGE_ITEM_PLANE + +/obj/screen/storage/volumetric_box/proc/makeItemActive() + our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others! + our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE + /obj/screen/storage/volumetric_box/center icon_state = "stored_continue" - var/obj/screen/storage/stored_left/left - var/obj/screen/storage/stored_right/right + var/obj/screen/storage/volumetric_edge/stored_left/left + var/obj/screen/storage/volumetric_edge/stored_right/right var/pixel_size /obj/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item) @@ -87,7 +111,7 @@ return ..() /obj/screen/storage/volumetric_box/center/proc/on_screen_objects() - return list(src, left, right) + return list(src) /** * Sets the size of this box screen object and regenerates its left/right borders. This includes the actual border's size! @@ -96,18 +120,38 @@ if(pixel_size == pixels) return pixel_size = pixels - cut_overlays() + cut_overlays(TRUE) //our icon size is 32 pixels. transform = matrix((pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE, 0, 0, 0, 1, 0) left.pixel_x = -((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) - VOLUMETRIC_STORAGE_BOX_BORDER_SIZE right.pixel_x = ((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) + VOLUMETRIC_STORAGE_BOX_BORDER_SIZE - add_overlay(left) - add_overlay(right) + add_overlay(left, TRUE) + add_overlay(right, TRUE) -/obj/screen/storage/stored_left +/obj/screen/storage/volumetric_edge + layer = VOLUMETRIC_STORAGE_BOX_LAYER + plane = VOLUMETRIC_STORAGE_BOX_PLANE + +/obj/screen/storage/volumetric_edge/Initialize(mapload, master, our_item) + src.master = master + return ..() + +/obj/screen/storage/volumetric_edge/Click(location, control, params) + return master.Click(location, control, params) + +/obj/screen/storage/volumetric_edge/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) + return master.MouseDrop(over, src_location, over_location, src_control, over_control, params) + +/obj/screen/storage/volumetric_edge/MouseExited(location, control, params) + return master.MouseExited(location, control, params) + +/obj/screen/storage/volumetric_edge/MouseEntered(location, control, params) + return master.MouseEntered(location, control, params) + +/obj/screen/storage/volumetric_edge/stored_left icon_state = "stored_start" appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM // Yes I know RESET_TRANSFORM is in APPEARANCE_UI but we're hard-asserting this incase someone changes it. -/obj/screen/storage/stored_right +/obj/screen/storage/volumetric_edge/stored_right icon_state = "stored_end" appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 33cfef03c7..3ad0219391 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -112,17 +112,17 @@ /obj/attacked_by(obj/item/I, mob/living/user) var/totitemdamage = I.force - var/bad_flag = NONE + var/bad_trait if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user)) totitemdamage *= 0.5 - bad_flag |= SKILL_COMBAT_MODE //blacklist combat skills. + bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. if(I.used_skills && user.mind) if(totitemdamage) - totitemdamage = user.mind.skill_holder.item_action_skills_mod(I, totitemdamage, I.skill_difficulty, SKILL_ATTACK_OBJ, bad_flag) + totitemdamage = user.mind.item_action_skills_mod(I, totitemdamage, I.skill_difficulty, SKILL_ATTACK_OBJ, bad_trait) for(var/skill in I.used_skills) if(!(I.used_skills[skill] & SKILL_TRAIN_ATTACK_OBJ)) continue - user.mind.skill_holder.auto_gain_experience(skill, I.skill_gain) + user.mind.auto_gain_experience(skill, I.skill_gain) if(totitemdamage) visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) //only witnesses close by and the victim see a hit message. @@ -154,20 +154,20 @@ /mob/living/proc/pre_attacked_by(obj/item/I, mob/living/user) . = I.force - var/bad_flag = NONE + var/bad_trait if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user)) . *= 0.5 - bad_flag |= SKILL_COMBAT_MODE //blacklist combat skills. + bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. if(!CHECK_MOBILITY(user, MOBILITY_STAND)) . *= 0.5 if(!user.mind || !I.used_skills) return if(.) - . = user.mind.skill_holder.item_action_skills_mod(I, ., I.skill_difficulty, SKILL_ATTACK_MOB, bad_flag) + . = user.mind.item_action_skills_mod(I, ., I.skill_difficulty, SKILL_ATTACK_MOB, bad_trait) for(var/skill in I.used_skills) if(!(I.used_skills[skill] & SKILL_TRAIN_ATTACK_MOB)) continue - user.mind.skill_holder.auto_gain_experience(skill, I.skill_gain) + user.mind.auto_gain_experience(skill, I.skill_gain) /mob/living/carbon/pre_attacked_by(obj/item/I, mob/living/user) . = ..() @@ -207,16 +207,16 @@ return 1 /// How much stamina this takes to swing this is not for realism purposes hecc off. -/obj/item/proc/getweight(mob/living/user, multiplier = 1, flags = SKILL_STAMINA_COST) +/obj/item/proc/getweight(mob/living/user, multiplier = 1, trait = SKILL_STAMINA_COST) . = (total_mass || w_class * STAM_COST_W_CLASS_MULT) * multiplier if(!user) return - var/bad_flag = NONE + var/bad_trait if(iscarbon(user) && !(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) . *= STAM_COST_NO_COMBAT_MULT - bad_flag |= SKILL_COMBAT_MODE + bad_trait = SKILL_COMBAT_MODE if(used_skills && user.mind) - . = user.mind.skill_holder.item_action_skills_mod(src, ., skill_difficulty, flags, bad_flag, FALSE) + . = user.mind.item_action_skills_mod(src, ., skill_difficulty, trait, bad_trait, FALSE) /// How long this staggers for. 0 and negatives supported. /obj/item/proc/melee_stagger_duration(force_override) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index b35f4fe0e7..79b110a78a 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -507,3 +507,13 @@ //Allows players to set a hexadecimal color of their choice as skin tone, on top of the standard ones. /datum/config_entry/flag/allow_custom_skintones + +///Initial loadout points +/datum/config_entry/number/initial_gear_points + config_entry_value = 10 + +/** + * Enables the FoV component, which hides objects and mobs behind the parent from their sight, unless they turn around, duh. + * Camera mobs, AIs, ghosts and some other are of course exempt from this. This also doesn't influence simplemob AI, for the best. + */ +/datum/config_entry/flag/use_field_of_vision diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 0970b23a16..812c0a00ca 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -6,13 +6,20 @@ SUBSYSTEM_DEF(input) priority = FIRE_PRIORITY_INPUT runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY - var/list/macro_sets - var/list/movement_keys + /// Classic mode input focused macro set. Manually set because we can't define ANY or ANY+UP for classic. + var/static/list/macroset_classic_input + /// Classic mode map focused macro set. Manually set because it needs to be clientside and go to macroset_classic_input. + var/static/list/macroset_classic_hotkey + /// New hotkey mode macro set. All input goes into map, game keeps incessently setting your focus to map, we can use ANY all we want here; we don't care about the input bar, the user has to force the input bar every time they want to type. + var/static/list/macroset_hotkey + + /// Macro set for hotkeys + var/list/hotkey_mode_macros + /// Macro set for classic. + var/list/input_mode_macros /datum/controller/subsystem/input/Initialize() - setup_default_macro_sets() - - setup_default_movement_keys() + setup_macrosets() initialized = TRUE @@ -20,90 +27,68 @@ SUBSYSTEM_DEF(input) return ..() -// This is for when macro sets are eventualy datumized -/datum/controller/subsystem/input/proc/setup_default_macro_sets() - var/list/static/default_macro_sets - - if(default_macro_sets) - macro_sets = default_macro_sets - return - - default_macro_sets = list( - "default" = list( - "Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=[COLOR_INPUT_DISABLED]:input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", - "O" = "ooc", - "Ctrl+O" = "looc", - "T" = "say", - "Ctrl+T" = "whisper", - "M" = "me", - "Ctrl+M" = "subtle", - "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs - "Any" = "\"KeyDown \[\[*\]\]\"", - "Any+UP" = "\"KeyUp \[\[*\]\]\"", - ), - "old_default" = list( - "Tab" = "\".winset \\\"mainwindow.macro=old_hotkeys map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"", - "Ctrl+T" = "say", - "Ctrl+O" = "ooc", - ), - "old_hotkeys" = list( - "Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", - "O" = "ooc", - "L" = "looc", - "T" = "say", - "M" = "me", - "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs - "Any" = "\"KeyDown \[\[*\]\]\"", - "Any+UP" = "\"KeyUp \[\[*\]\]\"", - ), - ) - - // Because i'm lazy and don't want to type all these out twice - var/list/old_default = default_macro_sets["old_default"] - - var/list/static/oldmode_keys = list( +/// Sets up the key list for classic mode for when badmins screw up vv's. +/datum/controller/subsystem/input/proc/setup_macrosets() + // First, let's do the snowflake keyset! + macroset_classic_input = list() + var/list/classic_mode_keys = list( "North", "East", "South", "West", "Northeast", "Southeast", "Northwest", "Southwest", - "Insert", "Delete", "Ctrl", "Alt", + "Insert", "Delete", "Ctrl", "Alt", "Shift", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", ) + for(var/key in classic_mode_keys) + macroset_classic_input[key] = "\"KeyDown [key]\"" + macroset_classic_input["[key]+UP"] = "\"KeyUp [key]\"" + // LET'S PLAY THE BIND EVERY KEY GAME! + // oh except for Backspace and Enter; if you want to use those you shouldn't have used oldmode! + var/list/classic_ctrl_override_keys = list( + "\[", "\]", "\\", ";", "'", ",", ".", "/", "-", "\\=", "`" + ) + // i'm lazy let's play the list iteration game of numbers + for(var/i in 0 to 9) + classic_ctrl_override_keys += "[i]" + // let's play the ascii game of A to Z (UPPERCASE) + for(var/i in 65 to 90) + classic_ctrl_override_keys += ascii2text(i) + // let's play the game of clientside bind overrides! + classic_ctrl_override_keys -= list("T", "O", "M", "L") + macroset_classic_input["Ctrl+T"] = "say" + macroset_classic_input["Ctrl+O"] = "ooc" + macroset_classic_input["Ctrl+L"] = "looc" + // let's play the list iteration game x2 + for(var/key in classic_ctrl_override_keys) + macroset_classic_input["Ctrl+[key]"] = "\"KeyDown [key]\"" + macroset_classic_input["Ctrl+[key]+UP"] = "\"KeyUp [key]\"" + // Misc + macroset_classic_input["Tab"] = "\".winset \\\"mainwindow.macro=[SKIN_MACROSET_CLASSIC_HOTKEYS] map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"" + macroset_classic_input["Escape"] = "\".winset \\\"input.text=\\\"\\\"\\\"\"" - for(var/i in 1 to oldmode_keys.len) - var/key = oldmode_keys[i] - old_default[key] = "\"KeyDown [key]\"" - old_default["[key]+UP"] = "\"KeyUp [key]\"" + // FINALLY, WE CAN DO SOMETHING MORE NORMAL FOR THE SNOWFLAKE-BUT-LESS KEYSET. + macroset_classic_hotkey = list( + "Any" = "\"KeyDown \[\[*\]\]\"", + "Any+UP" = "\"KeyUp \[\[*\]\]\"", + "Tab" = "\".winset \\\"mainwindow.macro=[SKIN_MACROSET_CLASSIC_INPUT] input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", + "Escape" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", + "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", + "O" = "ooc", + "T" = "say", + "L" = "looc", + "M" = "me" + ) - var/list/static/oldmode_ctrl_override_keys = list( - "W" = "W", "A" = "A", "S" = "S", "D" = "D", // movement - "1" = "1", "2" = "2", "3" = "3", "4" = "4", // intent - "B" = "B", // resist - "E" = "E", // quick equip - "F" = "F", // intent left - "G" = "G", // intent right - "H" = "H", // stop pulling - "Q" = "Q", // drop - "R" = "R", // throw - "X" = "X", // switch hands - "Y" = "Y", // activate item - "Z" = "Z", // activate item - ) - - for(var/i in 1 to oldmode_ctrl_override_keys.len) - var/key = oldmode_ctrl_override_keys[i] - var/override = oldmode_ctrl_override_keys[key] - old_default["Ctrl+[key]"] = "\"KeyDown [override]\"" - old_default["Ctrl+[key]+UP"] = "\"KeyUp [override]\"" - - macro_sets = default_macro_sets - -// For initially setting up or resetting to default the movement keys -/datum/controller/subsystem/input/proc/setup_default_movement_keys() - var/static/list/default_movement_keys = list( - "W" = NORTH, "A" = WEST, "S" = SOUTH, "D" = EAST, // WASD - "North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad - ) - - movement_keys = default_movement_keys.Copy() + // And finally, the modern set. + macroset_hotkey = list( + "Any" = "\"KeyDown \[\[*\]\]\"", + "Any+UP" = "\"KeyUp \[\[*\]\]\"", + "Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=[COLOR_INPUT_DISABLED]:input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", + "Escape" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", + "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", + "O" = "ooc", + "T" = "say", + "L" = "looc", + "M" = "me" + ) // Badmins just wanna have fun ♪ /datum/controller/subsystem/input/proc/refresh_client_macro_sets() @@ -111,9 +96,10 @@ SUBSYSTEM_DEF(input) for(var/i in 1 to clients.len) var/client/user = clients[i] user.set_macros() + user.update_movement_keys() /datum/controller/subsystem/input/fire() var/list/clients = GLOB.clients // Let's sing the list cache song - for(var/i in 1 to length(clients)) + for(var/i in 1 to clients.len) var/client/C = clients[i] C.keyLoop() diff --git a/code/controllers/subsystem/moods.dm b/code/controllers/subsystem/moods.dm deleted file mode 100644 index f6b6ffcb40..0000000000 --- a/code/controllers/subsystem/moods.dm +++ /dev/null @@ -1,4 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(mood) - name = "Mood" - flags = SS_NO_INIT | SS_BACKGROUND - priority = 20 diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 479e6dc21e..cd577e4ac6 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -267,6 +267,7 @@ SUBSYSTEM_DEF(persistence) CollectAntagReputation() SaveRandomizedRecipes() SavePanicBunker() + SavePaintings() /datum/controller/subsystem/persistence/proc/LoadPanicBunker() var/bunker_path = file("data/bunker_passthrough.json") diff --git a/code/datums/actions/ninja.dm b/code/datums/actions/ninja.dm index b655078349..c0314b9c48 100644 --- a/code/datums/actions/ninja.dm +++ b/code/datums/actions/ninja.dm @@ -8,11 +8,11 @@ icon_icon = 'icons/mob/actions/actions_spells.dmi' /datum/action/item_action/ninjaboost - check_flags = NONE name = "Adrenaline Boost" desc = "Inject a secret chemical that will counteract all movement-impairing effect." button_icon_state = "repulse" icon_icon = 'icons/mob/actions/actions_spells.dmi' + required_mobility_flags = NONE /datum/action/item_action/ninjapulse name = "EM Burst (25E)" diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index 80a1bd2470..279118d877 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -44,7 +44,7 @@ return if(world.time > next_check && world.time > next_scare) next_check = world.time + 50 - var/list/seen_atoms = view(7, owner) + var/list/seen_atoms = owner.fov_view(7) if(LAZYLEN(trigger_objs)) for(var/obj/O in seen_atoms) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index cbcb34ac5e..7a78e1d001 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -35,7 +35,7 @@ * * extra_classes - Extra classes to apply to the span that holds the text * * lifespan - The lifespan of the message in deciseconds */ -/datum/chatmessage/New(text, atom/target, mob/owner, list/extra_classes = null, lifespan = CHAT_MESSAGE_LIFESPAN) +/datum/chatmessage/New(text, atom/target, mob/owner, list/extra_classes = list(), lifespan = CHAT_MESSAGE_LIFESPAN) . = ..() if (!istype(target)) CRASH("Invalid target given for chatmessage") @@ -55,6 +55,12 @@ message = null return ..() +/** + * Calls qdel on the chatmessage when its parent is deleted, used to register qdel signal + */ +/datum/chatmessage/proc/on_parent_qdel() + qdel(src) + /** * Generates a chat message image representation * @@ -68,7 +74,7 @@ /datum/chatmessage/proc/generate_image(text, atom/target, mob/owner, list/extra_classes, lifespan) // Register client who owns this message owned_by = owner.client - RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/qdel, src) + RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/on_parent_qdel) // Clip message var/maxlen = owned_by.prefs.max_chat_length @@ -108,7 +114,7 @@ // BYOND Bug #2563917 // Construct text var/static/regex/html_metachars = new(@"&[A-Za-z]{1,7};", "g") - var/complete_text = "[text]" + var/complete_text = "[text]" var/mheight = WXH_TO_HEIGHT(owned_by.MeasureText(replacetext(complete_text, html_metachars, "m"), null, CHAT_MESSAGE_WIDTH)) approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) @@ -129,7 +135,7 @@ // Build message image message = image(loc = message_loc, layer = CHAT_LAYER) - message.plane = GAME_PLANE + message.plane = CHAT_PLANE message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART message.alpha = 0 message.pixel_y = owner.bound_height * 0.95 @@ -166,7 +172,7 @@ */ /mob/proc/create_chat_message(atom/movable/speaker, datum/language/message_language, raw_message, list/spans, message_mode) // Ensure the list we are using, if present, is a copy so we don't modify the list provided to us - spans = spans?.Copy() + spans = spans ? spans.Copy() : list() // Check for virtual speakers (aka hearing a message through a radio) var/atom/movable/originalSpeaker = speaker diff --git a/code/datums/components/art.dm b/code/datums/components/art.dm new file mode 100644 index 0000000000..f6d3cb6c61 --- /dev/null +++ b/code/datums/components/art.dm @@ -0,0 +1,56 @@ + +#define BAD_ART 12.5 +#define GOOD_ART 25 +#define GREAT_ART 50 + +/datum/component/art + var/impressiveness = 0 + +/datum/component/art/Initialize(impress) + impressiveness = impress + if(isobj(parent)) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine) + else + RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_other_examine) + if(isstructure(parent)) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet) + +/datum/component/art/proc/apply_moodlet(mob/M, impress) + M.visible_message("[M] stops and looks intently at [parent].", \ + "You stop to take in [parent].") + switch(impress) + if (0 to BAD_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) + if (BAD_ART to GOOD_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) + if (GOOD_ART to GREAT_ART) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) + if(GREAT_ART to INFINITY) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + + +/datum/component/art/proc/on_other_examine(datum/source, mob/M) + apply_moodlet(M, impressiveness) + +/datum/component/art/proc/on_obj_examine(datum/source, mob/M) + var/obj/O = parent + apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity)) + +/datum/component/art/proc/on_attack_hand(datum/source, mob/M) + to_chat(M, "You start examining [parent]...") + if(!do_after(M, 20, target = parent)) + return + on_obj_examine(source, M) + +/datum/component/art/rev + +/datum/component/art/rev/apply_moodlet(mob/M, impress) + M.visible_message("[M] stops to inspect [parent].", \ + "You take in [parent], inspecting the fine craftsmanship of the proletariat.") + + if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + else + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) diff --git a/code/datums/components/crafting/glassware/glassware.dm b/code/datums/components/crafting/glassware/glassware.dm index 2b57837c5d..6e1a3d47a0 100644 --- a/code/datums/components/crafting/glassware/glassware.dm +++ b/code/datums/components/crafting/glassware/glassware.dm @@ -74,7 +74,7 @@ //////////////////////Lens////////////////////////// //Six Steps // -//Sells for 1800 cr, takes 15 glass shets // +//Sells for 1600 cr, takes 15 glass shets // //Usefull for selling and later crafting // //////////////////////////////////////////////////// @@ -146,14 +146,14 @@ /obj/item/glasswork/glass_base/glass_lens_part5 name = "Unpolished glass lens" - desc = "A small unpolished glass lens. Could be polished with some silk." + desc = "A small unpolished glass lens. Could be polished with some cloth." icon = 'icons/obj/glass_ware.dmi' icon_state = "glass_optics" next_step = /obj/item/glasswork/glass_base/glass_lens_part6 /obj/item/glasswork/glass_base/glass_lens_part5/attackby(obj/item/I, mob/user, params) ..() - if(istype(I, /obj/item/stack/sheet/silk)) + if(istype(I, /obj/item/stack/sheet/cloth)) if(do_after(user,10, target = src)) new next_step(user.loc, 1) qdel(src) @@ -324,7 +324,7 @@ //////////////////////Tea Plates//////////////////// //Three Steps // -//Sells for 1200 cr, takes 5 glass shets // +//Sells for 1000 cr, takes 5 glass shets // //Usefull for selling and chemical things // //////////////////////////////////////////////////// @@ -370,20 +370,20 @@ /obj/item/glasswork/glass_base/tea_plate3 name = "Disk of glass" - desc = "A disk of glass that can be cant be used for much. Needs to be polished with some silk." + desc = "A disk of glass that can be cant be used for much. Needs to be polished with some cloth." icon_state = "glass_base_half" next_step = /obj/item/tea_plate /obj/item/glasswork/glass_base/tea_plate3/attackby(obj/item/I, mob/user, params) ..() - if(istype(I, /obj/item/stack/sheet/silk)) + if(istype(I, /obj/item/stack/sheet/cloth)) if(do_after(user,10, target = src)) new next_step(user.loc, 1) qdel(src) //////////////////////Tea Cup/////////////////////// //Four Steps // -//Sells for 1800 cr, takes 6 glass shets // +//Sells for 1600 cr, takes 6 glass shets // //Usefull for selling and chemical things // //////////////////////////////////////////////////// @@ -429,13 +429,13 @@ /obj/item/glasswork/glass_base/tea_cup3 name = "Disk of glass" - desc = "A bowl of glass that can be cant be used for much. Needs to be polished with some silk." + desc = "A bowl of glass that can be cant be used for much. Needs to be polished with some cloth." icon_state = "glass_base_half" next_step = /obj/item/glasswork/glass_base/tea_cup4 /obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params) ..() - if(istype(I, /obj/item/stack/sheet/silk)) + if(istype(I, /obj/item/stack/sheet/cloth)) if(do_after(user,10, target = src)) new next_step(user.loc, 1) qdel(src) diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm index 89868c2332..e06583ab61 100644 --- a/code/datums/components/crafting/guncrafting.dm +++ b/code/datums/components/crafting/guncrafting.dm @@ -1,21 +1,20 @@ //Gun crafting parts til they can be moved elsewhere // PARTS // +/obj/item/weaponcrafting + icon = 'icons/obj/improvised.dmi' /obj/item/weaponcrafting/receiver name = "modular receiver" desc = "A prototype modular receiver and trigger assembly for a firearm." - icon = 'icons/obj/improvised.dmi' icon_state = "receiver" /obj/item/weaponcrafting/stock name = "rifle stock" desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." - icon = 'icons/obj/improvised.dmi' icon_state = "riflestock" -/obj/item/weaponcrafting/silkstring - name = "silkstring" - desc = "A long piece of silk with some resemblance to cable coil." - icon = 'icons/obj/improvised.dmi' - icon_state = "silkstring" +/obj/item/weaponcrafting/durathread_string + name = "durathread string" + desc = "A long piece of durathread with some resemblance to cable coil." + icon_state = "durastring" diff --git a/code/datums/components/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm index 02dd3f2c05..7a7379c834 100644 --- a/code/datums/components/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -39,14 +39,14 @@ time = 10 reqs = list(/obj/item/paper = 20) category = CAT_CLOTHING - + /datum/crafting_recipe/armwraps name = "Armwraps" result = /obj/item/clothing/gloves/fingerless/pugilist time = 60 tools = list(TOOL_WIRECUTTER) reqs = list(/obj/item/stack/sheet/cloth = 4, - /obj/item/stack/sheet/silk = 2, + /obj/item/stack/sheet/durathread = 2, /obj/item/stack/sheet/leather = 2) category = CAT_CLOTHING diff --git a/code/datums/components/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm index 8ee893b2e5..1ad53aae67 100644 --- a/code/datums/components/crafting/recipes/recipes_misc.dm +++ b/code/datums/components/crafting/recipes/recipes_misc.dm @@ -157,7 +157,7 @@ /datum/crafting_recipe/goldenbox name = "Gold Plated Toolbox" result = /obj/item/storage/toolbox/gold_fake - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) reqs = list(/obj/item/stack/sheet/cardboard = 1, //so we dont null items in crafting /obj/item/stack/cable_coil = 10, /obj/item/stack/sheet/mineral/gold = 1, @@ -184,7 +184,7 @@ /datum/crafting_recipe/bronze_driver name = "Bronze Plated Screwdriver" - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) result = /obj/item/screwdriver/bronze reqs = list(/obj/item/screwdriver = 1, /obj/item/stack/cable_coil = 10, @@ -196,7 +196,7 @@ /datum/crafting_recipe/bronze_welder name = "Bronze Plated Welding Tool" - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) result = /obj/item/weldingtool/bronze reqs = list(/obj/item/weldingtool = 1, /obj/item/stack/cable_coil = 10, @@ -208,7 +208,7 @@ /datum/crafting_recipe/bronze_wirecutters name = "Bronze Plated Wirecutters" - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) result = /obj/item/wirecutters/bronze reqs = list(/obj/item/wirecutters = 1, /obj/item/stack/cable_coil = 10, @@ -220,7 +220,7 @@ /datum/crafting_recipe/bronze_crowbar name = "Bronze Plated Crowbar" - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) result = /obj/item/crowbar/bronze reqs = list(/obj/item/crowbar = 1, /obj/item/stack/cable_coil = 10, @@ -232,7 +232,7 @@ /datum/crafting_recipe/bronze_wrench name = "Bronze Plated Wrench" - tools = list(/obj/item/stock_parts/cell/upgraded/plus) + tools = list(/obj/item/stock_parts/cell/high) result = /obj/item/wrench/bronze reqs = list(/obj/item/wrench = 1, /obj/item/stack/cable_coil = 10, diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm index b037f02f80..21a160264a 100644 --- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm +++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm @@ -192,7 +192,7 @@ result = /obj/item/gun/ballistic/bow/pipe reqs = list(/obj/item/pipe = 5, /obj/item/stack/sheet/plastic = 15, - /obj/item/weaponcrafting/silkstring = 5) + /obj/item/weaponcrafting/durathread_string = 5) time = 450 category = CAT_WEAPONRY subcategory = CAT_WEAPON @@ -281,7 +281,7 @@ result = /obj/item/ammo_casing/caseless/arrow/wood time = 30 reqs = list(/obj/item/stack/sheet/mineral/wood = 1, - /obj/item/stack/sheet/silk = 1, + /obj/item/stack/sheet/durathread = 1, /obj/item/stack/rods = 1) // 1 metal sheet = 2 rods = 2 arrows category = CAT_WEAPONRY subcategory = CAT_AMMO diff --git a/code/datums/components/field_of_vision.dm b/code/datums/components/field_of_vision.dm new file mode 100644 index 0000000000..5fb7b2596c --- /dev/null +++ b/code/datums/components/field_of_vision.dm @@ -0,0 +1,354 @@ +#define CENTERED_RENDER_SOURCE(img, atom, FoV) \ + atom.render_target = atom.render_target || ref(atom);\ + img.render_source = atom.render_target;\ + if(atom.icon){\ + var/_cached_sizes = FoV.width_n_height_offsets[atom.icon];\ + if(!_cached_sizes){\ + var/icon/_I = icon(atom.icon);\ + var/list/L = list();\ + L += (_I.Width() - world.icon_size)/2;\ + L += (_I.Height() - world.icon_size)/2;\ + _cached_sizes = FoV.width_n_height_offsets[atom.icon] = L\ + }\ + img.pixel_x = _cached_sizes[1];\ + img.pixel_y = _cached_sizes[2];\ + img.loc = atom\ + } + +#define REGISTER_NESTED_LOCS(source, list, comsig, proc) \ + for(var/k in get_nested_locs(source)){\ + var/atom/_A = k;\ + RegisterSignal(_A, comsig, proc);\ + list += _A\ + } + +#define UNREGISTER_NESTED_LOCS(list, comsig, index) \ + for(var/k in index to length(list)){\ + var/atom/_A = list[k];\ + UnregisterSignal(_A, comsig);\ + list -= _A\ + } + +/** + * Field of Vision component. Does totally what you probably think it does, + * ergo preventing players from seeing what's behind them. + */ +/datum/component/field_of_vision + can_transfer = TRUE + +/** + * That special invisible, almost neigh indestructible movable + * that holds both shadow cone mask and image and follows the player around. + */ + var/atom/movable/fov_holder/fov + ///The current screen size this field of vision is meant to fit for. + var/current_fov_size = list(15, 15) + ///How much is the cone rotated clockwise, purely backend. Please use rotate_shadow_cone() if you must. + var/angle = 0 + /// Used to scale the shadow cone when rotating it to fit over the edges of the screen. + var/rot_scale = 1 + /// The inner angle of this cone, right hardset to 90, 180, or 270 degrees, until someone figures out a way to make it dynamic. + var/shadow_angle = FOV_90_DEGREES + /// The mask portion of the cone, placed on a * render target plane so while not visible it still applies the filter. + var/image/shadow_mask + /// The visual portion of the cone, placed on the highest layer of the wall plane + var/image/visual_shadow +/** + * An image whose render_source is kept up to date to prevent the mob (or the topmost movable holding it) from being hidden by the mask. + * Will make it use vis_contents instead once a few byonds bugs with images and vis contents are fixed. + */ + var/image/owner_mask +/** + * A circle image used to somewhat uncover the adjacent portion of the shadow cone, making mobs and objects behind us somewhat visible. + * The owner mask is still required for those mob going over the default 32x32 px size btw. + */ + var/image/adj_mask + /// A list of nested locations the mob is in, to ensure the above image works correctly. + var/list/nested_locs = list() +/** + * A static list of offsets based on icon width and height, because render sources are centered unlike most other visuals, + * and that gives us some problems when the icon is larger or smaller than world.icon_size + */ + var/static/list/width_n_height_offsets = list() + +/datum/component/field_of_vision/Initialize(fov_type = FOV_90_DEGREES, _angle = 0) + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + angle = _angle + shadow_angle = fov_type + +/datum/component/field_of_vision/RegisterWithParent() + . = ..() + var/mob/M = parent + if(M.client) + generate_fov_holder(M, angle) + RegisterSignal(M, COMSIG_MOB_CLIENT_LOGIN, .proc/on_mob_login) + RegisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_mob_logout) + RegisterSignal(M, COMSIG_MOB_GET_VISIBLE_MESSAGE, .proc/on_visible_message) + RegisterSignal(M, COMSIG_MOB_EXAMINATE, .proc/on_examinate) + RegisterSignal(M, COMSIG_MOB_FOV_VIEW, .proc/on_fov_view) + RegisterSignal(M, COMSIG_MOB_CLIENT_CHANGE_VIEW, .proc/on_change_view) + RegisterSignal(M, COMSIG_MOB_RESET_PERSPECTIVE, .proc/on_reset_perspective) + RegisterSignal(M, COMSIG_MOB_FOV_VIEWER, .proc/is_viewer) + +/datum/component/field_of_vision/UnregisterFromParent() + . = ..() + var/mob/M = parent + if(!QDELETED(fov)) + if(M.client) + UnregisterSignal(M, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_DEATH, COMSIG_LIVING_REVIVE)) + M.client.images -= owner_mask + M.client.images -= shadow_mask + M.client.images -= visual_shadow + M.client.images -= adj_mask + qdel(fov, TRUE) // Forced. + fov = null + QDEL_NULL(owner_mask) + QDEL_NULL(adj_mask) + if(length(nested_locs)) + UNREGISTER_NESTED_LOCS(nested_locs, COMSIG_MOVABLE_MOVED, 1) + UnregisterSignal(M, list(COMSIG_MOB_CLIENT_LOGIN, COMSIG_MOB_CLIENT_LOGOUT, + COMSIG_MOB_GET_VISIBLE_MESSAGE, COMSIG_MOB_EXAMINATE, + COMSIG_MOB_FOV_VIEW, COMSIG_MOB_RESET_PERSPECTIVE, + COMSIG_MOB_CLIENT_CHANGE_VIEW, COMSIG_MOB_FOV_VIEWER)) + +/** + * Generates the holder and images (if not generated yet) and adds them to client.images. + * Run when the component is registered to a player mob, or upon login. + */ +/datum/component/field_of_vision/proc/generate_fov_holder(mob/M, _angle = 0) + if(QDELETED(fov)) + fov = new(get_turf(M)) + fov.icon_state = "[shadow_angle]" + fov.dir = M.dir + shadow_mask = image('icons/misc/field_of_vision.dmi', fov, "[shadow_angle]", FIELD_OF_VISION_LAYER) + shadow_mask.plane = FIELD_OF_VISION_PLANE + visual_shadow = image('icons/misc/field_of_vision.dmi', fov, "[shadow_angle]_v", FIELD_OF_VISION_LAYER) + visual_shadow.plane = FIELD_OF_VISION_VISUAL_PLANE + owner_mask = new + owner_mask.appearance_flags = RESET_TRANSFORM + owner_mask.plane = FIELD_OF_VISION_BLOCKER_PLANE + adj_mask = image('icons/misc/field_of_vision.dmi', fov, "adj_mask", FIELD_OF_VISION_LAYER) + adj_mask.appearance_flags = RESET_TRANSFORM + adj_mask.plane = FIELD_OF_VISION_BLOCKER_PLANE + if(_angle) + rotate_shadow_cone(_angle) + fov.alpha = M.stat == DEAD ? 0 : 255 + RegisterSignal(M, COMSIG_MOB_DEATH, .proc/hide_fov) + RegisterSignal(M, COMSIG_LIVING_REVIVE, .proc/show_fov) + RegisterSignal(M, COMSIG_ATOM_DIR_CHANGE, .proc/on_dir_change) + RegisterSignal(M, COMSIG_MOVABLE_MOVED, .proc/on_mob_moved) + RegisterSignal(M, COMSIG_ROBOT_UPDATE_ICONS, .proc/manual_centered_render_source) + var/atom/A = M + if(M.loc && !isturf(M.loc)) + REGISTER_NESTED_LOCS(M, nested_locs, COMSIG_MOVABLE_MOVED, .proc/on_loc_moved) + A = nested_locs[nested_locs.len] + CENTERED_RENDER_SOURCE(owner_mask, A, src) + M.client.images += shadow_mask + M.client.images += visual_shadow + M.client.images += owner_mask + M.client.images += adj_mask + if(M.client.view != "[current_fov_size[1]]x[current_fov_size[2]]") + resize_fov(current_fov_size, getviewsize(M.client.view)) + +///Rotates the shadow cone to a certain degree. Backend shenanigans. +/datum/component/field_of_vision/proc/rotate_shadow_cone(new_angle) + var/simple_degrees = SIMPLIFY_DEGREES(new_angle - angle) + var/to_scale = cos(simple_degrees) * sin(simple_degrees) + if(to_scale) + var/old_rot_scale = rot_scale + rot_scale = 1 + to_scale + if(old_rot_scale != rot_scale) + visual_shadow.transform = shadow_mask.transform = shadow_mask.transform.Scale(rot_scale/old_rot_scale) + visual_shadow.transform = shadow_mask.transform = shadow_mask.transform.Turn(fov.transform, simple_degrees) + +/** + * Resizes the shadow to match the current screen size. + * Run when the client view size is changed, or if the player has a viewsize different than "15x15" on login/comp registration. + */ +/datum/component/field_of_vision/proc/resize_fov(list/old_view, list/view) + current_fov_size = view + var/old_size = max(old_view[1], old_view[2]) + var/new_size = max(view[1], view[2]) + if(old_size == new_size) //longest edges are still of the same length. + return + visual_shadow.transform = shadow_mask.transform = shadow_mask.transform.Scale(new_size/old_size) + +/datum/component/field_of_vision/proc/on_mob_login(mob/source, client/client) + generate_fov_holder(source, angle) + +/datum/component/field_of_vision/proc/on_mob_logout(mob/source, client/client) + UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_DEATH, + COMSIG_LIVING_REVIVE, COMSIG_ROBOT_UPDATE_ICONS)) + if(length(nested_locs)) + UNREGISTER_NESTED_LOCS(nested_locs, COMSIG_MOVABLE_MOVED, 1) + +/datum/component/field_of_vision/proc/on_dir_change(mob/source, old_dir, new_dir) + fov.dir = new_dir + +///Hides the shadow, other visibility comsig procs will take it into account. Called when the mob dies. +/datum/component/field_of_vision/proc/hide_fov(mob/source) + fov.alpha = 0 + +/// Shows the shadow. Called when the mob is revived. +/datum/component/field_of_vision/proc/show_fov(mob/source) + fov.alpha = 255 + +/// Hides the shadow when looking through other items, shows it otherwise. +/datum/component/field_of_vision/proc/on_reset_perspective(mob/source, atom/target) + if(source.client.eye == source || source.client.eye == source.loc) + fov.alpha = 255 + else + fov.alpha = 0 + +/// Called when the client view size is changed. +/datum/component/field_of_vision/proc/on_change_view(mob/source, client, list/old_view, list/view) + resize_fov(old_view, view) + +/** + * Called when the owner mob moves around. Used to keep shadow located right behind us, + * As well as modify the owner mask to match the topmost item. + */ +/datum/component/field_of_vision/proc/on_mob_moved(mob/source, atom/oldloc, dir, forced) + var/turf/T + if(!isturf(source.loc)) //Recalculate all nested locations. + UNREGISTER_NESTED_LOCS( nested_locs, COMSIG_MOVABLE_MOVED, 1) + REGISTER_NESTED_LOCS(source, nested_locs, COMSIG_MOVABLE_MOVED, .proc/on_loc_moved) + var/atom/movable/topmost = nested_locs[nested_locs.len] + T = topmost.loc + CENTERED_RENDER_SOURCE(owner_mask, topmost, src) + else + T = source.loc + if(length(nested_locs)) + UNREGISTER_NESTED_LOCS(nested_locs, COMSIG_MOVABLE_MOVED, 1) + CENTERED_RENDER_SOURCE(owner_mask, source, src) + if(T) + fov.forceMove(T, harderforce = TRUE) + +/// Pretty much like the above, but meant for other movables the mob is stored in (bodybags, boxes, mechs etc). +/datum/component/field_of_vision/proc/on_loc_moved(atom/movable/source, atom/oldloc, dir, forced) + if(isturf(source.loc) && isturf(oldloc)) //This is the case of the topmost movable loc moving around the world, skip. + fov.forceMove(source.loc, harderforce = TRUE) + return + var/atom/movable/prev_topmost = nested_locs[nested_locs.len] + if(prev_topmost != source) + UNREGISTER_NESTED_LOCS(nested_locs, COMSIG_MOVABLE_MOVED, nested_locs.Find(source) + 1) + REGISTER_NESTED_LOCS(source, nested_locs, COMSIG_MOVABLE_MOVED, .proc/on_loc_moved) + var/atom/movable/topmost = nested_locs[nested_locs.len] + if(topmost != prev_topmost) + CENTERED_RENDER_SOURCE(owner_mask, topmost, src) + if(topmost.loc) + fov.forceMove(topmost.loc, harderforce = TRUE) + +/// A hacky comsig proc for things that somehow decide to change icon on the go. may make a change_icon_file() proc later but... +/datum/component/field_of_vision/proc/manual_centered_render_source(mob/source, old_icon) + if(!isturf(source.loc)) + return + CENTERED_RENDER_SOURCE(owner_mask, source, src) + +#undef CENTERED_RENDER_SOURCE +#undef REGISTER_NESTED_LOCS +#undef UNREGISTER_NESTED_LOCS + +/** + * Byond doc is not entirely correct on the integrated arctan() proc. + * When both x and y are negative, the output is also negative, cycling clockwise instead of counter-clockwise. + * That's also why I am extensively using the SIMPLIFY_DEGREES macro here. + * + * Overall this is the main macro that calculates wheter a target is within the shadow cone angle or not. + */ +#define FOV_ANGLE_CHECK(mob, target, zero_x_y_statement, success_statement) \ + var/turf/T1 = get_turf(target);\ + var/turf/T2 = get_turf(mob);\ + if(!T1 || !T2){\ + zero_x_y_statement\ + }\ + var/_x = (T1.x - T2.x);\ + var/_y = (T1.y - T2.y);\ + if(ISINRANGE(_x, -1, 1) && ISINRANGE(_y, -1, 1)){\ + zero_x_y_statement\ + }\ + var/dir = (mob.dir & (EAST|WEST)) || mob.dir;\ + var/_degree = -angle;\ + var/_half = shadow_angle/2;\ + switch(dir){\ + if(EAST){\ + _degree += 180;\ + }\ + if(NORTH){\ + _degree += 270;\ + }\ + if(SOUTH){\ + _degree += 90;\ + }\ + }\ + var/_min = SIMPLIFY_DEGREES(_degree - _half);\ + var/_max = SIMPLIFY_DEGREES(_degree + _half);\ + if((_min > _max) ? !ISINRANGE(SIMPLIFY_DEGREES(arctan(_x, _y)), _max, _min) : ISINRANGE(SIMPLIFY_DEGREES(arctan(_x, _y)), _min, _max)){\ + success_statement;\ + } + +/datum/component/field_of_vision/proc/on_examinate(mob/source, atom/target) + if(fov.alpha) + FOV_ANGLE_CHECK(source, target, return, return COMPONENT_DENY_EXAMINATE|COMPONENT_EXAMINATE_BLIND) + +/datum/component/field_of_vision/proc/on_visible_message(mob/source, atom/target, message, range, list/ignored_mobs) + if(fov.alpha) + FOV_ANGLE_CHECK(source, target, return, return COMPONENT_NO_VISIBLE_MESSAGE) + +/datum/component/field_of_vision/proc/on_fov_view(mob/source, list/atoms) + if(!fov.alpha) + return + for(var/k in atoms) + var/atom/A = k + FOV_ANGLE_CHECK(source, A, continue, atoms -= A) + +/datum/component/field_of_vision/proc/is_viewer(mob/source, atom/center, depth, list/viewers_list) + if(fov.alpha) + FOV_ANGLE_CHECK(source, center, return, viewers_list -= source) + +#undef FOV_ANGLE_CHECK + +/** + * The shadow cone's mask and visual images holder which can't locate inside the mob, + * lest they inherit the mob opacity and cause a lot of hindrance + */ +/atom/movable/fov_holder + name = "field of vision holder" + pixel_x = -224 //the image is about 480x480 px, ergo 15 tiles (480/32) big, and we gotta center it. + pixel_y = -224 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = FIELD_OF_VISION_PLANE + anchored = TRUE + +/atom/movable/fov_holder/ConveyorMove() + return + +/atom/movable/fov_holder/has_gravity(turf/T) + return FALSE + +/atom/movable/fov_holder/ex_act(severity) + return FALSE + +/atom/movable/fov_holder/singularity_act() + return + +/atom/movable/fov_holder/singularity_pull() + return + +/atom/movable/fov_holder/blob_act() + return + +/atom/movable/fov_holder/onTransitZ() + return + +/// Prevents people from moving these after creation, because they shouldn't be. +/atom/movable/fov_holder/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE) + if(harderforce) + return ..() + +/// Last but not least, these shouldn't be deleted by anything but the component itself +/atom/movable/fov_holder/Destroy(force = FALSE) + if(!force) + return QDEL_HINT_LETMELIVE + return ..() diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm index fbf559fe35..f767c607a5 100644 --- a/code/datums/components/footstep.dm +++ b/code/datums/components/footstep.dm @@ -1,26 +1,52 @@ +///Footstep component. Plays footsteps at parents location when it is appropriate. /datum/component/footstep + ///How many steps the parent has taken since the last time a footstep was played var/steps = 0 + ///volume determines the extra volume of the footstep. This is multiplied by the base volume, should there be one. var/volume + ///e_range stands for extra range - aka how far the sound can be heard. This is added to the base value and ignored if there isn't a base value. var/e_range + ///footstep_type is a define which determines what kind of sounds should get chosen. + var/footstep_type + ///This can be a list OR a soundfile OR null. Determines whatever sound gets played. + var/footstep_sounds -/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1) +/datum/component/footstep/Initialize(footstep_type_ = FOOTSTEP_MOB_BAREFOOT, volume_ = 0.5, e_range_ = -1) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE volume = volume_ e_range = e_range_ - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep) + footstep_type = footstep_type_ + switch(footstep_type) + if(FOOTSTEP_MOB_HUMAN) + if(!ishuman(parent)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/play_humanstep) + return + if(FOOTSTEP_MOB_CLAW) + footstep_sounds = GLOB.clawfootstep + if(FOOTSTEP_MOB_BAREFOOT) + footstep_sounds = GLOB.barefootstep + if(FOOTSTEP_MOB_HEAVY) + footstep_sounds = GLOB.heavyfootstep + if(FOOTSTEP_MOB_SHOE) + footstep_sounds = GLOB.footstep + if(FOOTSTEP_MOB_SLIME) + footstep_sounds = 'sound/effects/footstep/slime1.ogg' + if(FOOTSTEP_MOB_CRAWL) + footstep_sounds = 'sound/effects/footstep/crawl1.ogg' + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/play_simplestep) //Note that this doesn't get called for humans. -/datum/component/footstep/proc/play_footstep() +///Prepares a footstep. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/open +/datum/component/footstep/proc/prepare_step() var/turf/open/T = get_turf(parent) if(!istype(T)) return var/mob/living/LM = parent - var/v = volume - var/e = e_range if(!T.footstep || LM.buckled || !CHECK_MOBILITY(LM, MOBILITY_STAND) || LM.buckled || LM.throwing || (LM.movement_type & (VENTCRAWLING | FLYING))) if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying - playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) + playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * volume) return if(HAS_TRAIT(LM, TRAIT_SILENT_STEP)) @@ -30,79 +56,83 @@ var/mob/living/carbon/C = LM if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG)) return - if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK) - v /= 2 - e -= 5 + if(C.m_intent == MOVE_INTENT_WALK) + return steps++ - if(steps >= 3) + if(steps >= 6) steps = 0 - else + if(steps % 2) return - if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around + if(steps != 0 && !LM.has_gravity(T)) // don't need to step as often when you hop around return + return T - //begin playsound shenanigans// - - //for barefooted non-clawed mobs like monkeys - if(isbarefoot(LM)) - playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), - GLOB.barefootstep[T.barefootstep][2] * v, - TRUE, - GLOB.barefootstep[T.barefootstep][3] + e) +/datum/component/footstep/proc/play_simplestep() + var/turf/open/T = prepare_step() + if(!T) return - - //for xenomorphs, dogs, and other clawed mobs - if(isclawfoot(LM)) - if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps - v /= 3 - e -= 5 - - playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]), - GLOB.clawfootstep[T.clawfootstep][2] * v, - TRUE, - GLOB.clawfootstep[T.clawfootstep][3] + e) + if(isfile(footstep_sounds) || istext(footstep_sounds)) + playsound(T, footstep_sounds, volume) return - - //for megafauna and other large and imtimidating mobs such as the bloodminer - if(isheavyfoot(LM)) - playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]), - GLOB.heavyfootstep[T.heavyfootstep][2] * v, - TRUE, - GLOB.heavyfootstep[T.heavyfootstep][3] + e) + var/turf_footstep + switch(footstep_type) + if(FOOTSTEP_MOB_CLAW) + turf_footstep = T.clawfootstep + if(FOOTSTEP_MOB_BAREFOOT) + turf_footstep = T.barefootstep + if(FOOTSTEP_MOB_HEAVY) + turf_footstep = T.heavyfootstep + if(FOOTSTEP_MOB_SHOE) + turf_footstep = T.footstep + if(!turf_footstep) return + playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range) - //for slimes - if(isslime(LM)) - playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v) +/datum/component/footstep/proc/play_humanstep() + var/turf/open/T = prepare_step() + if(!T) return - - //for (simple) humanoid mobs (clowns, russians, pirates, etc.) - if(isshoefoot(LM)) - if(!ishuman(LM)) - playsound(T, pick(GLOB.footstep[T.footstep][1]), - GLOB.footstep[T.footstep][2] * v, - TRUE, - GLOB.footstep[T.footstep][3] + e) - return - if(ishuman(LM)) //for proper humans, they're special - var/mob/living/carbon/human/H = LM - var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET))) - - if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature - playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v) + var/mob/living/carbon/human/H = parent + var/list/L = GLOB.barefootstep + var/turf_footstep = T.barefootstep + var/special = FALSE + if(H.physiology.footstep_type) + switch(H.physiology.footstep_type) + if(FOOTSTEP_MOB_CLAW) + turf_footstep = T.clawfootstep + L = GLOB.clawfootstep + if(FOOTSTEP_MOB_BAREFOOT) + turf_footstep = T.barefootstep + L = GLOB.barefootstep + if(FOOTSTEP_MOB_HEAVY) + turf_footstep = T.heavyfootstep + L = GLOB.heavyfootstep + if(FOOTSTEP_MOB_SHOE) + turf_footstep = T.footstep + L = GLOB.footstep + if(FOOTSTEP_MOB_SLIME) + playsound(T, 'sound/effects/footstep/slime1.ogg', 50 * volume) return + if(FOOTSTEP_MOB_CRAWL) + playsound(T, 'sound/effects/footstep/crawl1.ogg', 50 * volume) + return + special = TRUE + else + var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET))) + if(feetCover) //are we wearing shoes + playsound(T, pick(GLOB.footstep[T.footstep][1]), + GLOB.footstep[T.footstep][2] * volume, + TRUE, + GLOB.footstep[T.footstep][3] + e_range) + return - if(feetCover) //are we wearing shoes - playsound(T, pick(GLOB.footstep[T.footstep][1]), - GLOB.footstep[T.footstep][2] * v, - TRUE, - GLOB.footstep[T.footstep][3] + e) - - if(!feetCover) //are we NOT wearing shoes - playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), - GLOB.barefootstep[T.barefootstep][2] * v, - TRUE, - GLOB.barefootstep[T.barefootstep][3] + e) \ No newline at end of file + if(!special && H.dna.species.special_step_sounds) + playsound(T, pick(H.dna.species.special_step_sounds), 50, TRUE) + else + playsound(T, pick(L[turf_footstep][1]), + L[turf_footstep][2] * volume, + TRUE, + L[turf_footstep][3] + e_range) diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 23a81716b8..37d77a45bc 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -1,41 +1,52 @@ +#define ECSTATIC_SANITY_PEN -1 #define SLIGHT_INSANITY_PEN 1 #define MINOR_INSANITY_PEN 5 #define MAJOR_INSANITY_PEN 10 -#define MOOD_INSANITY_MALUS 0.0054 // per point of sanity below SANITY_DISTURBED, a 40% debuff to skills at rock bottom depression. +#define MOOD_INSANITY_MALUS 0.13 // 13% debuff per sanity_level above the default of 4 (higher is worser), overall a 39% debuff to skills at rock bottom depression. /datum/component/mood var/mood //Real happiness var/sanity = 100 //Current sanity var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy. var/mood_level = 5 //To track what stage of moodies they're on - var/sanity_level = 5 //To track what stage of sanity they're on + var/sanity_level = 3 //To track what stage of sanity they're on var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets var/list/datum/mood_event/mood_events = list() var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much? var/obj/screen/mood/screen_obj + var/datum/skill_modifier/bad_mood/malus + var/datum/skill_modifier/great_mood/bonus + var/static/malus_id = 0 + var/static/list/free_maluses = list() /datum/component/mood/Initialize() if(!isliving(parent)) return COMPONENT_INCOMPATIBLE - START_PROCESSING(SSmood, src) + var/mob/living/owner = parent + if(owner.stat != DEAD) + START_PROCESSING(SSdcs, src) RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event) RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event) RegisterSignal(parent, COMSIG_MODIFY_SANITY, .proc/modify_sanity) RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/on_revive) RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud) - var/mob/living/owner = parent + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/stop_processing) + if(owner.hud_used) modify_hud() var/datum/hud/hud = owner.hud_used hud.show_hud(hud.hud_version) /datum/component/mood/Destroy() - STOP_PROCESSING(SSmood, src) + STOP_PROCESSING(SSdcs, src) unmodify_hud() return ..() +/datum/component/mood/proc/stop_processing() + STOP_PROCESSING(SSdcs, src) + /datum/component/mood/proc/print_mood(mob/user) var/msg = "*---------*\nYour current mood\n" msg += "My mental status: " //Long term @@ -127,7 +138,7 @@ else screen_obj.icon_state = "mood[mood_level]" -/datum/component/mood/process() //Called on SSmood process +/datum/component/mood/process() //Called on SSdcs process if(QDELETED(parent)) // workaround to an obnoxious sneaky periodical runtime. qdel(src) return @@ -167,13 +178,13 @@ else if(sanity > maximum && amount > sanity - 0.5) amount = sanity - 0.5 - var/old_sanity = sanity // Disturbed stops you from getting any more sane if(HAS_TRAIT(master, TRAIT_UNSTABLE)) sanity = min(amount,sanity) else sanity = amount + var/old_sanity_level = sanity_level switch(sanity) if(-INFINITY to SANITY_CRAZY) setInsanityEffect(MAJOR_INSANITY_PEN) @@ -196,27 +207,43 @@ master.remove_movespeed_modifier(MOVESPEED_ID_SANITY) sanity_level = 2 if(SANITY_GREAT+1 to INFINITY) - setInsanityEffect(0) + setInsanityEffect(ECSTATIC_SANITY_PEN) //It's not a penalty but w/e master.remove_movespeed_modifier(MOVESPEED_ID_SANITY) sanity_level = 1 - if(old_sanity > 1 && sanity == 1) - RegisterSignal(master, COMSIG_MOB_SKILL_GET_AFFINITY, .proc/on_get_skill_affinity) - else if(old_sanity == 1 && sanity > 1) - UnregisterSignal(master, COMSIG_MOB_SKILL_GET_AFFINITY) + if(sanity_level != old_sanity_level) + if(sanity_level >= 4) + if(!malus) + if(!length(free_maluses)) + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/bad_mood, malus_id++, master, malus) + else + malus = pick_n_take(free_maluses) + if(master.mind) + master.mind.add_skill_modifier(malus.identifier) + else + malus.RegisterSignal(master, COMSIG_MOB_ON_NEW_MIND, /datum/skill_modifier.proc/on_mob_new_mind, TRUE) + malus.value_mod = malus.level_mod = 1 - (sanity_level - 3) * MOOD_INSANITY_MALUS + else if(malus) + if(master.mind) + master.mind.remove_skill_modifier(malus.identifier) + else + malus.UnregisterSignal(master, COMSIG_MOB_ON_NEW_MIND) + free_maluses += malus + malus = null //update_mood_icon() /datum/component/mood/proc/setInsanityEffect(newval)//More code so that the previous proc works if(newval == insanity_effect) return - //var/mob/living/master = parent - //master.crit_threshold = (master.crit_threshold - insanity_effect) + newval - if(!insanity_effect && newval) - RegisterSignal(parent, COMSIG_MOB_ACTION_SKILL_MOD, .proc/on_mob_action_skill_mod) - RegisterSignal(parent, COMSIG_MOB_ITEM_ACTION_SKILLS_MOD, .proc/on_item_action_skills_mod) - else if(insanity_effect && !newval) - UnregisterSignal(parent, list(COMSIG_MOB_ACTION_SKILL_MOD, COMSIG_MOB_ITEM_ACTION_SKILLS_MOD)) + + var/mob/living/L = parent + if(newval == ECSTATIC_SANITY_PEN && !bonus) + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/great_mood, null, L, bonus) + else if(bonus) + REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/great_mood, null, L) + bonus = null + insanity_effect = newval /datum/component/mood/proc/modify_sanity(datum/source, amount, minimum = SANITY_INSANE, maximum = SANITY_AMAZING) @@ -294,46 +321,15 @@ if(0 to NUTRITION_LEVEL_STARVING) add_event(null, "nutrition", /datum/mood_event/starving) -///Called when parent is ahealed. +///Called when parent is revived. /datum/component/mood/proc/on_revive(datum/source, full_heal) + START_PROCESSING(SSdcs, src) if(!full_heal) return remove_temp_moods() setSanity(initial(sanity)) -/datum/component/mood/proc/on_mob_action_skill_mod(mob/source, list/skill_args, list/mod_values) - var/datum/skill/S = GLOB.skill_datums[skill_args[ACTION_SKILL_MOD_SKILL]] - if(!(S.skill_flags & SKILL_USE_MOOD)) - return - var/debuff = 1 - (SANITY_DISTURBED - sanity) * MOOD_INSANITY_MALUS - mod_values[MOD_VALUES_SKILL_MOD] *= skill_args[ACTION_SKILL_MOD_IS_MULTI] ? debuff : 1/debuff - -/datum/component/mood/proc/on_item_action_skills_mod(mob/source, list/skill_args, list/mod_values) - if(skill_args[ITEM_SKILLS_MOD_BAD_FLAGS] & SKILL_USE_MOOD) - return - var/divisor = mod_values[MOD_VALUES_ITEM_SKILLS_DIV] - if(!divisor) - return - var/obj/item/I = skill_args[ITEM_SKILLS_MOD_ITEM] - var/list/L = mod_values[MOD_VALUES_ITEM_SKILLS_CHECKED] - var/skills_len = length(L) - var/affected_skills = skills_len - for(var/k in L) - var/datum/skill/S = k - var/our_flags = I.used_skills[S.type]|S.skill_flags - if(!(our_flags & SKILL_USE_MOOD)) - affected_skills-- - if(!affected_skills) - return - var/debuff = 1 - (SANITY_DISTURBED - sanity) * MOOD_INSANITY_MALUS * (affected_skills/skills_len) - mod_values[MOD_VALUES_ITEM_SKILLS_SUM] *= skill_args[ITEM_SKILLS_MOD_IS_MULTI] ? debuff : 1/debuff - -/datum/component/mood/proc/on_get_skill_affinity(mob/source, skill_path, list/return_value) - var/datum/skill/S = GLOB.skill_datums[skill_path] - if(!S || !(S.skill_flags & SKILL_TRAIN_MOOD)) - return - return_value[1] *= SKILL_AFFINITY_MOOD_BONUS - +#undef ECSTATIC_SANITY_PEN #undef SLIGHT_INSANITY_PEN #undef MINOR_INSANITY_PEN #undef MAJOR_INSANITY_PEN diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index aad6e8289f..44ac865aa2 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -353,8 +353,12 @@ /datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing) _removal_reset(thing) if(LAZYACCESS(ui_item_blocks, thing)) - qdel(ui_item_blocks[thing]) + var/obj/screen/storage/volumetric_box/center/C = ui_item_blocks[thing] + for(var/i in can_see_contents()) //runtimes result if mobs can access post deletion. + var/mob/M = i + M.client?.screen -= C.on_screen_objects() ui_item_blocks -= thing + qdel(C) refresh_mob_views() //Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted @@ -567,10 +571,9 @@ return if(rustle_sound) playsound(parent, "rustle", 50, 1, -5) - for(var/mob/viewing in viewers(user, null)) - if(M == viewing) - to_chat(usr, "You put [I] [insert_preposition]to [parent].") - else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is... + to_chat(user, "You put [I] [insert_preposition]to [parent].") + for(var/mob/viewing in fov_viewers(world.view, user)-M) + if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is... viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance... viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm index f37f574002..c7ac0d3549 100644 --- a/code/datums/components/storage/ui.dm +++ b/code/datums/components/storage/ui.dm @@ -92,6 +92,8 @@ var/list/volume_by_item = list() var/list/percentage_by_item = list() for(var/obj/item/I in contents) + if(QDELETED(I)) + continue volume = I.get_w_volume() used += volume volume_by_item[I] = volume @@ -123,6 +125,7 @@ var/obj/item/I // start at this pixel from screen_start_x. var/current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING + var/first = TRUE var/row = 1 LAZYINITLIST(ui_item_blocks) @@ -140,10 +143,10 @@ addrow = TRUE // now that we have pixels_to_use, place our thing and add it to the returned list. - - B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + VOLUMETRIC_STORAGE_ITEM_PADDING, 1)],[screen_start_y+row-1]:[screen_pixel_y]" + B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]" // add the used pixels to pixel after we place the object - current_pixel += pixels_to_use + VOLUMETRIC_STORAGE_ITEM_PADDING + current_pixel += pixels_to_use + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING) + first = FALSE //apply padding to everything after this // set various things B.set_pixel_size(pixels_to_use) @@ -163,6 +166,7 @@ // go up a row if needed if(addrow) row++ + first = TRUE //first in the row, don't apply between-item padding. current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING // Then, continuous section. @@ -233,7 +237,7 @@ if(!M.client) return TRUE UnregisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT) - M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide() + M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide(M) if(M.active_storage == src) M.active_storage = null LAZYREMOVE(is_using, M) @@ -249,8 +253,8 @@ /** * Gets the ui item objects to ui_hide. */ -/datum/component/storage/proc/get_ui_item_objects_hide() - if(!volumetric_ui()) +/datum/component/storage/proc/get_ui_item_objects_hide(mob/M) + if(!volumetric_ui() || M.client?.prefs?.no_tetris_storage) var/atom/real_location = real_location() return real_location.contents else diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index a7a61802d3..216d82b4c8 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -145,4 +145,10 @@ return !is_mouth_covered() /mob/living/carbon/CanSpreadAirborneDisease() - return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25))) \ No newline at end of file + return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25))) + +/mob/living/proc/set_shocked() + flags_1 |= SHOCKED_1 + +/mob/living/proc/reset_shocked() + flags_1 &= ~ SHOCKED_1 \ No newline at end of file diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 68998ca1c6..ae0c540ef0 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -48,8 +48,8 @@ destination.dna.uni_identity = uni_identity destination.dna.blood_type = blood_type destination.dna.skin_tone_override = skin_tone_override - destination.set_species(species.type, icon_update=0) destination.dna.features = features.Copy() + destination.set_species(species.type, icon_update=0) destination.dna.real_name = real_name destination.dna.nameless = nameless destination.dna.custom_species = custom_species @@ -252,6 +252,17 @@ construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) if(DNA_TAUR_BLOCK) construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + if(species.mutant_bodyparts["taur"] && ishuman(holder)) + var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] + switch(T?.taur_mode) + if(STYLE_HOOF_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_SHOE + if(STYLE_PAW_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_CLAW + if(STYLE_SNEK_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL + else + H.physiology.footstep_type = null //Please use add_mutation or activate_mutation instead /datum/dna/proc/force_give(datum/mutation/human/HM) diff --git a/code/datums/elements/dwarfism.dm b/code/datums/elements/dwarfism.dm new file mode 100644 index 0000000000..fefbe4fbe7 --- /dev/null +++ b/code/datums/elements/dwarfism.dm @@ -0,0 +1,42 @@ +#define SHORT 4/5 +#define TALL 5/4 + +///Very similar to squish, but for dwarves and shorties +/datum/element/dwarfism + element_flags = ELEMENT_DETACH|ELEMENT_BESPOKE + id_arg_index = 2 + var/comsig + var/list/attached_targets = list() + +/datum/element/dwarfism/Attach(datum/target, comsig, comsig_target) + . = ..() + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.comsig = comsig + + var/mob/living/L = target + if(L.lying != 0) + L.transform = L.transform.Scale(SHORT, 1) + else + L.transform = L.transform.Scale(1, SHORT) + attached_targets[target] = comsig_target + RegisterSignal(target, comsig, .proc/check_loss) //Second arg of the signal will be checked against the comsig_target. + +/datum/element/dwarfism/proc/check_loss(mob/living/L, comsig_target) + if(attached_targets[L] == comsig_target) + Detach(L) + +/datum/element/dwarfism/Detach(mob/living/L) + . = ..() + if(QDELETED(L)) + return + if(L.lying != 0) + L.transform = L.transform.Scale(TALL, 1) + else + L.transform = L.transform.Scale(1, TALL) + UnregisterSignal(L, comsig) + attached_targets -= L + +#undef SHORT +#undef TALL diff --git a/code/datums/elements/wuv.dm b/code/datums/elements/wuv.dm index fffb90c681..6476a204cf 100644 --- a/code/datums/elements/wuv.dm +++ b/code/datums/elements/wuv.dm @@ -41,7 +41,7 @@ return //we want to delay the effect to be displayed after the mob is petted, not before. switch(user.a_intent) - if(INTENT_HARM, INTENT_DISARM) + if(INTENT_HARM) addtimer(CALLBACK(src, .proc/kick_the_dog, source, user), 1) if(INTENT_HELP) addtimer(CALLBACK(src, .proc/pet_the_dog, source, user), 1) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 0b0fed407c..91b8e32566 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -5,16 +5,18 @@ var/list/testmerge = list() /datum/getrev/New() + commit = rustg_git_revparse("HEAD") + if(commit) + date = rustg_git_commit_date(commit) + originmastercommit = rustg_git_revparse("origin/master") + +/datum/getrev/proc/load_tgs_info() testmerge = world.TgsTestMerges() var/datum/tgs_revision_information/revinfo = world.TgsRevision() if(revinfo) commit = revinfo.commit originmastercommit = revinfo.origin_commit - else - commit = rustg_git_revparse("HEAD") - if(commit) - date = rustg_git_commit_date(commit) - originmastercommit = rustg_git_revparse("origin/master") + date = rustg_git_commit_date(commit) // goes to DD log and config_error.txt log_world(get_log_message()) @@ -77,7 +79,9 @@ msg += "No commit information" if(world.TgsAvailable()) var/datum/tgs_version/version = world.TgsVersion() - msg += "Server tools version: [version.raw_parameter]" + msg += "TGS version: [version.raw_parameter]" + var/datum/tgs_version/api_version = world.TgsApiVersion() + msg += "DMAPI version: [api_version.raw_parameter]" // Game mode odds msg += "
Current Informational Settings:" @@ -121,4 +125,4 @@ if(probabilities[ctag] > 0) var/percentage = round(probabilities[ctag] / sum * 100, 0.1) msg += "[ctag] [percentage]%" - to_chat(src, msg.Join("
")) \ No newline at end of file + to_chat(src, msg.Join("
")) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index a9438fa80b..b7eac62e83 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -67,7 +67,7 @@ var/datum/skill_holder/skill_holder /datum/mind/New(var/key) - skill_holder = new(src) + skill_holder = new() src.key = key soulOwner = src martial_art = default_martial_art diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 1464927c3a..c56425b074 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -248,7 +248,7 @@ description = "Something I recently ate was horrifyingly disgusting.\n" mood_change = -5 timeout = 5 MINUTES - + /datum/mood_event/nanite_sadness description = "+++++++HAPPINESS SUPPRESSION+++++++\n" mood_change = -7 @@ -256,3 +256,7 @@ /datum/mood_event/nanite_sadness/add_effects(message) description = "+++++++[message]+++++++\n" +/datum/mood_event/artbad + description = "I've produced better art than that from my ass.\n" + mood_change = -2 + timeout = 1200 diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 1e9a53cf57..95177f6869 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -182,3 +182,17 @@ description = "What a peculiar emblem. It makes me feel hopeful for my future.\n" mood_change = 5 +/datum/mood_event/artok + description = "It's nice to see people are making art around here.\n" + mood_change = 2 + timeout = 2 MINUTES + +/datum/mood_event/artgood + description = "What a thought-provoking piece of art. I'll remember that for a while.\n" + mood_change = 3 + timeout = 3 MINUTES + +/datum/mood_event/artgreat + description = "That work of art was so great it made me believe in the goodness of humanity. Says a lot in a place like this.\n" + mood_change = 4 + timeout = 4 MINUTES diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 1077dbf2b3..36fbe449b8 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -117,7 +117,8 @@ owner.apply_overlay(layer_used) if(power) owner.RemoveSpell(power) - qdel(src) + qdel(power) + SEND_SIGNAL(owner, COMSIG_HUMAN_MUTATION_LOSS, src) return 0 return 1 diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 9f8c74e2db..7b438f44db 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -82,7 +82,7 @@ if(..()) return ADD_TRAIT(owner, TRAIT_DWARF, GENETIC_MUTATION) - owner.transform = owner.transform.Scale(1, 0.8) + AddElement(/datum/element/dwarfism, COMSIG_HUMAN_MUTATION_LOSS, src) passtable_on(owner, GENETIC_MUTATION) owner.visible_message("[owner] suddenly shrinks!", "Everything around you seems to grow..") diff --git a/code/datums/skills/_check_skills.dm b/code/datums/skills/_check_skills.dm index d9dc6dad3d..a94c7c95ba 100644 --- a/code/datums/skills/_check_skills.dm +++ b/code/datums/skills/_check_skills.dm @@ -12,5 +12,5 @@ to_chat(usr, "How do you check the skills of [(usr == src)? "yourself when you are" : "something"] without the capability for skills? (PROBABLY A BUG, PRESS F1.)") return var/datum/browser/B = new(usr, "skilldisplay_[REF(src)]", "Skills of [src]") - B.set_content(mind.skill_holder.html_readout()) + B.set_content(mind.skill_html_readout()) B.open() diff --git a/code/datums/skills/_skill.dm b/code/datums/skills/_skill.dm index f52945536f..571a8274d8 100644 --- a/code/datums/skills/_skill.dm +++ b/code/datums/skills/_skill.dm @@ -9,19 +9,10 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) S = new path .[S.type] = S -/proc/sanitize_skill_value(path, value) - var/datum/skill/S = GLOB.skill_datums[path] - // don't check, if we runtime let it happen. - return S.sanitize_value(value) - -/proc/is_skill_value_greater(path, existing, new_value) - var/datum/skill/S = GLOB.skill_datums[path] - // don't check, if we runtime let it happen. - return S.is_value_greater(existing, new_value) - /** * Skill datums */ + /datum/skill /// Our name var/name @@ -29,16 +20,20 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) var/desc /// Color of the name as shown in the html readout var/name_color = "#F0F0F0" // White on dark surface. - /// Our progression type + /// Our progression type. These are mostly used to skip typechecks overhead, don't go around messing with these. var/progression_type /// Abstract type var/abstract_type = /datum/skill - /// skill threshold used in generic skill modifiers calculations. - var/list/competency_thresholds = list(0, 0, 0) - /// Multiplier of the difference of the holder skill value and the selected threshold. - var/list/competency_mults = list(0, 0, 0) - /// In which way this skil can affect or be affected through actions. - var/skill_flags = SKILL_USE_MOOD|SKILL_TRAIN_MOOD + /// List of max levels. Only used in level skills, but present here for helper macros. + var/max_levels = INFINITY + /// skill threshold used in generic skill competency operations. + var/list/competency_thresholds + /// Base multiplier used in skill competency operations. + var/base_multiplier = 1 + /// Value added to the base multiplier depending on overall competency compared to maximum value/level. + var/competency_multiplier = 1 + /// A list of ways this skill can affect or be affected through actions and skill modifiers. + var/list/skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE) /** * Ensures what someone's setting as a value for this skill is valid. @@ -73,8 +68,7 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) /datum/skill/binary abstract_type = /datum/skill/binary progression_type = SKILL_PROGRESSION_BINARY - competency_thresholds = list(FALSE, TRUE, TRUE) - competency_mults = list(0.5, 0.5, 0.5) + competency_thresholds = list(THRESHOLD_COMPETENT = FALSE, THRESHOLD_EXPERT = TRUE, THRESHOLD_MASTER = TRUE) /datum/skill/binary/sanitize_value(new_value) return new_value? TRUE : FALSE @@ -85,6 +79,7 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) /datum/skill/numerical abstract_type = /datum/skill/numerical progression_type = SKILL_PROGRESSION_NUMERICAL + competency_thresholds = list(THRESHOLD_COMPETENT = 25, THRESHOLD_EXPERT = 50, THRESHOLD_MASTER = 75) /// Max value of this skill var/max_value = 100 /// Min value of this skill @@ -114,9 +109,9 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) /datum/skill/level abstract_type = /datum/skill/level progression_type = SKILL_PROGRESSION_LEVEL + max_levels = STD_MAX_LVL var/standard_xp_lvl_up = STD_XP_LVL_UP //the standard required to level up. def: 100 var/xp_lvl_multiplier = STD_XP_LVL_MULTI //standard required level up exp multiplier. def: 2 (100, 200, 400, 800 etc.) - var/max_levels = STD_MAX_LVL var/level_up_method = STANDARD_LEVEL_UP //how levels are calculated. var/list/levels = list() //level thresholds, if associative, these will be preceded by tiers such as "novice" or "trained" var/associative = FALSE //See above. @@ -177,18 +172,17 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) var/current_lvl_xp_sum = 0 if(level) current_lvl_xp_sum = associative ? levels[levels[level]] : levels[level] - var/next_index = max(max_levels, level+1) + var/next_index = min(max_levels, level+1) var/next_lvl_xp = associative ? levels[levels[next_index]] : levels[next_index] if(next_lvl_xp > current_lvl_xp_sum) next_lvl_xp -= current_lvl_xp_sum - return "[associative ? current_lvl : "Lvl. [current_lvl]"] ([value - current_lvl_xp_sum]/[next_lvl_xp])[level == max_levels ? " \[MAX!\]" : ""]" /datum/skill/level/job + abstract_type = /datum/skill/level/job levels = list("Basic", "Trained", "Experienced", "Master") - competency_thresholds = list(JOB_SKILL_TRAINED, JOB_SKILL_EXPERT, JOB_SKILL_MASTER) - competency_mults = list(0.15, 0.1, 0.1) + competency_thresholds = list(THRESHOLD_COMPETENT = JOB_SKILL_TRAINED, THRESHOLD_EXPERT = JOB_SKILL_EXPERT, THRESHOLD_MASTER = JOB_SKILL_MASTER) associative = TRUE //quite the reference, no? @@ -202,7 +196,6 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) "Proficient", "Talented", "Adept", "Expert", "Professional", "Accomplished", "Great", "Master", "High Master", "Grand Master", "Legendary") - competency_thresholds = list(DORF_SKILL_COMPETENT, DORF_SKILL_EXPERT, DORF_SKILL_MASTER) - competency_mults = list(0.15, 0.1, 0.08) + competency_thresholds = list(THRESHOLD_COMPETENT = DORF_SKILL_COMPETENT, THRESHOLD_EXPERT = DORF_SKILL_EXPERT, THRESHOLD_MASTER = DORF_SKILL_MASTER) associative = TRUE unskilled_tier = "Dabbling" diff --git a/code/datums/skills/_skill_holder.dm b/code/datums/skills/_skill_holder.dm index e252b4c9c6..554269091a 100644 --- a/code/datums/skills/_skill_holder.dm +++ b/code/datums/skills/_skill_holder.dm @@ -1,8 +1,8 @@ /** * Skill holder datums + * All procs are tied to the mind, since they are always expected to have a skill holder anyway. */ /datum/skill_holder - var/datum/mind/owner /// Our list of skills and values. Lazylist. Associative. Keys are datum typepaths to the skill. var/list/skills /// Same as [skills] but affinities, which are multiplied to increase amount when gaining skills. @@ -10,66 +10,87 @@ /// Let's say we want to get a specific skill "level" without looping through a proc everytime. /// Only supported by skills with tiers or levels. var/list/skill_levels - -/datum/skill_holder/New(datum/mind/M) - . = ..() - owner = M + /// current skill modifiers lists, per value, affinity, level. + var/list/skill_value_mods + var/list/skill_affinity_mods + var/list/skill_level_mods + /// List of all current skill modifiers, so we don't add the same ones twice. + var/list/all_current_skill_modifiers + /// List of original values stored at the time a modifier with the MODIFIER_SKILL_ORIGIN_DIFF enabled was added. + var/list/original_values + var/list/original_affinities + var/list/original_levels /** * Grabs the value of a skill. */ -/datum/skill_holder/proc/get_skill_value(skill) +/datum/mind/proc/get_skill_value(skill, apply_modifiers = TRUE) if(!ispath(skill)) CRASH("Invalid get_skill_value call. Use typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this. - if(!skills) - return null - return skills[skill] + if(!skill_holder.skills) + . = 0 + else + . = skill_holder.skills[skill] || 0 + if(apply_modifiers && skill_holder.skill_value_mods) + var/L = LAZYACCESS(skill_holder.skill_value_mods, skill) + for(var/k in L) + var/datum/skill_modifier/M = GLOB.skill_modifiers[k] + . = M.apply_modifier(., skill, skill_holder, MODIFIER_TARGET_VALUE) /** * Grabs the level of a skill. Only supported by skills with tiers or levels. */ -/datum/skill_holder/proc/get_skill_level(skill) +/datum/mind/proc/get_skill_level(skill, apply_modifiers = TRUE, round = FALSE) if(!ispath(skill, /datum/skill)) CRASH("Invalid get_skill_value call. Use skill typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this. - if(!skill_levels) - return 0 - return skill_levels[skill] + if(!skill_holder.skill_levels) + . = 0 + else + . = skill_holder.skill_levels[skill] || 0 + if(apply_modifiers && skill_holder.skill_level_mods) + var/L = LAZYACCESS(skill_holder.skill_level_mods, skill) + for(var/k in L) + var/datum/skill_modifier/M = GLOB.skill_modifiers[k] + . = M.apply_modifier(., skill, skill_holder, MODIFIER_TARGET_LEVEL) + . = SANITIZE_SKILL_LEVEL(skill, round ? round(., 1) : .) /** * Grabs our affinity for a skill. !!This is a multiplier!! */ -/datum/skill_holder/proc/get_skill_affinity(skill) +/datum/mind/proc/get_skill_affinity(skill, apply_modifiers = TRUE) . = 1 if(!ispath(skill, /datum/skill)) CRASH("Invalid get_skill_affinity call. Use skill typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this. - var/affinity = LAZYACCESS(skill_affinities, skill) + var/affinity = LAZYACCESS(skill_holder.skill_affinities, skill) if(!isnull(affinity)) . = affinity - var/list/wrapped = list(.) - SEND_SIGNAL(owner.current, COMSIG_MOB_SKILL_GET_AFFINITY, skill, wrapped) - . = wrapped[1] + if(apply_modifiers && skill_holder.skill_affinity_mods) + var/L = LAZYACCESS(skill_holder.skill_affinity_mods, skill) + for(var/k in L) + var/datum/skill_modifier/M = GLOB.skill_modifiers[k] + . = M.apply_modifier(., skill, skill_holder, MODIFIER_TARGET_AFFINITY) /** * Sets the value of a skill. */ -/datum/skill_holder/proc/set_skill_value(skill, value, silent = FALSE) +/datum/mind/proc/set_skill_value(skill, value, silent = FALSE) if(!ispath(skill, /datum/skill)) CRASH("Invalid set_skill_value call. Use skill typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this. var/datum/skill/S = GLOB.skill_datums[skill] value = S.sanitize_value(value) if(!isnull(value)) - LAZYINITLIST(skills) - S.set_skill_value(src, value, owner, silent) + LAZYINITLIST(skill_holder.skills) + S.set_skill_value(skill_holder, value, src, silent) return TRUE return FALSE /** * Boosts a skill to a value if not aobve */ -/datum/skill_holder/proc/boost_skill_value_to(skill, value, silent = FALSE) - var/current = get_skill_value(skill) - if(!is_skill_value_greater(skill, current, value)) +/datum/mind/proc/boost_skill_value_to(skill, value, silent = FALSE, current) + current = current || get_skill_value(skill, FALSE) + if(!IS_SKILL_VALUE_GREATER(skill, current, value)) return FALSE set_skill_value(skill, value, silent) return TRUE @@ -78,20 +99,20 @@ * Automatic skill increase, multiplied by skill affinity if existing. * Only works if skill is numerical. */ -/datum/skill_holder/proc/auto_gain_experience(skill, value, maximum, silent = FALSE) +/datum/mind/proc/auto_gain_experience(skill, value, maximum, silent = FALSE) if(!ispath(skill, /datum/skill)) CRASH("Invalid set_skill_value call. Use skill typepaths.") var/datum/skill/S = GLOB.skill_datums[skill] if(S.progression_type != SKILL_PROGRESSION_NUMERICAL && S.progression_type != SKILL_PROGRESSION_LEVEL) CRASH("You cannot auto increment a non numerical(experience skill!") - var/current = get_skill_value(skill) + var/current = get_skill_value(skill, FALSE) var/affinity = get_skill_affinity(skill) var/target_value = current + (value * affinity) if(maximum) - target_value = max(target_value, maximum) + target_value = min(target_value, maximum) if(target_value == maximum) //no more experience to gain, early return. return - boost_skill_value_to(skill, target_value, silent) + boost_skill_value_to(skill, target_value, silent, current) /** * Generic value modifier proc that uses one skill. @@ -100,22 +121,23 @@ * * threshold : The difficulty of the action, in short. Refer to __DEFINES/skills/defines.dm for the defines. * * modifier_is_multiplier : wheter the modifier is a multiplier or a divisor. */ -/datum/skill_holder/proc/action_skills_mod(skill, value, threshold, modifier_is_multiplier = TRUE) - var/mod +/datum/mind/proc/action_skill_mod(skill, value, threshold, modifier_is_multiplier = TRUE) var/datum/skill/S = GLOB.skill_datums[skill] if(!S) - return + return value + var/mod = S.base_multiplier switch(S.progression_type) if(SKILL_PROGRESSION_LEVEL) - mod = LAZYACCESS(skill_levels, S.type) + var/datum/skill/level/L = S + var/skill_lvl = get_skill_level(L.type) + mod += skill_lvl/(L.max_levels+max(L.competency_thresholds[threshold]-skill_lvl, 0))*L.competency_multiplier + if(SKILL_PROGRESSION_NUMERICAL) + var/datum/skill/numerical/N = S + var/skill_val = get_skill_value(N.type) + mod += skill_val/(N.max_value+max(N.competency_thresholds[threshold]-skill_val, 0))*N.competency_multiplier else - mod = LAZYACCESS(skills, S.type) - mod = (1+(mod-S.competency_thresholds[threshold])*S.competency_mults[threshold]) - - var/list/comsig_values = list(mod) - SEND_SIGNAL(owner.current, COMSIG_MOB_ACTION_SKILL_MOD, args, comsig_values) - mod = comsig_values[MOD_VALUES_SKILL_MOD] - + var/comp_threshold = S.competency_thresholds[threshold] + mod += (comp_threshold ? (get_skill_value(S.type) / comp_threshold) : get_skill_value(S.type))*S.competency_multiplier . = modifier_is_multiplier ? value*mod : value/mod /** @@ -123,37 +145,40 @@ * Args: * * item/I : the item used in this action. its used_skills list variable contains the skills exercised with it. * * value : the value to modify, may be a delay, damage, probability. - * * flags : the required flags that each skill (either in I.used_skills or the skill datum skill_flags) must have to influence + * * traits : the required traits each skill (either in I.used_skills or the skill datum skill_traits) must have to influence * * the value. - * * bad_flags : the opposite of the above, skills that must not be present to impact the value. + * * bad_traits : the opposite of the above. * * modifier_is_multiplier : wheter the modifier is a multiplier or a divisor. */ -/datum/skill_holder/proc/item_action_skills_mod(obj/item/I, value, flags = NONE, bad_flags = NONE, modifier_is_multiplier = TRUE) +/datum/mind/proc/item_action_skills_mod(obj/item/I, value, traits, bad_traits, modifier_is_multiplier = TRUE) . = value var/sum = 0 var/divisor = 0 - var/list/checked_skills for(var/k in I.used_skills) var/datum/skill/S = GLOB.skill_datums[k] if(!S) continue - var/our_flags = (I.used_skills[k]|S.skill_flags) - if((flags && !(our_flags & flags)) || (bad_flags && our_flags & bad_flags)) + var/our_traits = S.skill_traits + var/item_traits = I.used_skills[k] + if(item_traits) + our_traits |= item_traits + if((traits && !(our_traits[traits] || length(our_traits & traits))) || (bad_traits && (our_traits[bad_traits] || length(our_traits & bad_traits)))) continue - var/mod + var/mod = S.base_multiplier switch(S.progression_type) if(SKILL_PROGRESSION_LEVEL) - mod = LAZYACCESS(skill_levels, S.type) + var/datum/skill/level/L = S + var/skill_lvl = get_skill_level(L.type) + mod += skill_lvl/(L.max_levels+max(L.competency_thresholds[I.skill_difficulty]-skill_lvl, 0))*L.competency_multiplier + if(SKILL_PROGRESSION_NUMERICAL) + var/datum/skill/numerical/N = S + var/skill_val = get_skill_value(N.type) + mod += skill_val/(N.max_value+max(N.competency_thresholds[I.skill_difficulty]-skill_val, 0))*N.competency_multiplier else - mod = LAZYACCESS(skills, S.type) - sum += 1+(mod - S.competency_thresholds[I.skill_difficulty])*S.competency_mults[I.skill_difficulty] - LAZYADD(checked_skills, S) - - var/list/comsig_values = list(sum, divisor, checked_skills) - SEND_SIGNAL(owner.current, COMSIG_MOB_ITEM_ACTION_SKILLS_MOD, args, comsig_values) - sum = comsig_values[MOD_VALUES_ITEM_SKILLS_SUM] - divisor = comsig_values[MOD_VALUES_ITEM_SKILLS_DIV] - + var/comp_threshold = S.competency_thresholds[I.skill_difficulty] + mod += (comp_threshold ? (get_skill_value(S.type) / comp_threshold) : get_skill_value(S.type))*S.competency_multiplier + sum += mod + divisor++ if(divisor) . = modifier_is_multiplier ? value*(sum/divisor) : value/(sum/divisor) @@ -161,11 +186,13 @@ * Generates a HTML readout of our skills. * Port to tgui-next when? */ -/datum/skill_holder/proc/html_readout() +/datum/mind/proc/skill_html_readout() var/list/out = list("

Skills


") out += "" - for(var/path in skills) + for(var/path in skill_holder.skills|skill_holder.skill_value_mods|skill_holder.skill_level_mods) var/datum/skill/S = GLOB.skill_datums[path] - out += "" + var/skill_value = get_skill_value(path) + var/skill_level = get_skill_level(path, round = TRUE) + out += "" out += "
SkillValue
[S.name][S.standard_render_value(skills[path], LAZYACCESS(skill_levels, path) || 0)]
[S.name][S.standard_render_value(skill_value, skill_level)]
" return out.Join("") diff --git a/code/datums/skills/_skill_modifier.dm b/code/datums/skills/_skill_modifier.dm new file mode 100644 index 0000000000..a28cf3aebd --- /dev/null +++ b/code/datums/skills/_skill_modifier.dm @@ -0,0 +1,204 @@ +GLOBAL_LIST_EMPTY_TYPED(skill_modifiers, /datum/skill_modifier) +GLOBAL_LIST_EMPTY(potential_skills_per_mod) +GLOBAL_LIST_EMPTY(potential_mods_per_skill) + +/** + * Base skill modifier datum, used to modify a player skills without directly touching their values, levels and affinity + * and cause lots of edge cases. These are fairly simple overall... make a subtype though, don't use this one. + */ +/datum/skill_modifier + /// flags for this skill modifier. + var/modifier_flags = NONE + /// target skills, can be a specific skill typepath or a list of skill traits. + var/target_skills = /datum/skill + /// the GLOB.potential_skills_per_mod key generated on runtime. You shouldn't be var-editing it. + var/target_skills_key + /// The identifier key this skill modifier is associated with. + var/identifier + /// skill affinity modifier, can be a multiplier or addendum, depending on the modifier_flags. + var/affinity_mod = 1 + /// skill value modifier, see above. + var/value_mod = 1 + /// skill level modifier, see above. + var/level_mod = 1 + /// Priority of this skill modifier compared to other ones. + var/priority = MODIFIER_SKILL_PRIORITY_DEF + +/datum/skill_modifier/New(id, register = FALSE) + identifier = GET_SKILL_MOD_ID(type, id) + if(id) + var/former_id = identifier + var/dupe = 0 + while(GLOB.skill_modifiers[identifier]) + identifier = "[former_id][++dupe]" + + if(register) + register() + +/datum/skill_modifier/proc/register() + if(GLOB.skill_modifiers[identifier]) + CRASH("Skill modifier identifier \"[identifier]\" already taken.") + GLOB.skill_modifiers[identifier] = src + if(ispath(target_skills)) + target_skills_key = target_skills + var/list/mod_L = GLOB.potential_mods_per_skill[target_skills] + if(!mod_L) + mod_L = GLOB.potential_mods_per_skill[target_skills] = list() + else + BINARY_INSERT(identifier, mod_L, datum/skill_modifier, src, priority, COMPARE_VALUE) + mod_L[identifier] = src + GLOB.potential_skills_per_mod[target_skills_key] = list(target_skills) + else //Should be a list. + var/list/T = target_skills + T = sortTim(target_skills, /proc/cmp_text_asc) //Sort the list contents alphabetically. + target_skills_key = T.Join("-") + var/list/L = GLOB.potential_skills_per_mod[target_skills_key] + if(!L) + L = list() + for(var/path in GLOB.skill_datums) + if(GLOB.skill_datums[path].skill_traits & target_skills) + L += path + GLOB.potential_skills_per_mod[target_skills_key] = L + for(var/path in L) + var/list/mod_L = GLOB.potential_mods_per_skill[path] + if(!mod_L) + mod_L = GLOB.potential_mods_per_skill[path] = list() + else + BINARY_INSERT(identifier, mod_L, datum/skill_modifier, src, priority, COMPARE_VALUE) + mod_L[identifier] = src + +/datum/skill_modifier/Destroy() + for(var/path in GLOB.potential_skills_per_mod[target_skills_key]) + var/mod_L = GLOB.potential_mods_per_skill[path] + mod_L -= identifier + if(!length(mod_L)) + GLOB.potential_mods_per_skill -= path + GLOB.skill_modifiers -= identifier + return ..() + +#define ADD_MOD_STEP(L, P, O, G) \ + var/__L = L[P];\ + if(!__L){\ + L[P] = list(id)\ + } else {\ + L[P] = GLOB.potential_mods_per_skill[P] & (__L + id)\ + }\ + if(M.modifier_flags & MODIFIER_SKILL_ORIGIN_DIFF){\ + LAZYADDASSOC(O, id, "[P]" = G)\ + } + +/datum/mind/proc/add_skill_modifier(id) + if(LAZYACCESS(skill_holder.all_current_skill_modifiers, id)) + return + var/datum/skill_modifier/M = GLOB.skill_modifiers[id] + if(!M) + CRASH("Invalid add_skill_modifier id: [id].") + if(M.modifier_flags & MODIFIER_SKILL_BODYBOUND && !current) + CRASH("Body-bound skill modifier [M] was tried to be added to a mob-less mind.") + + if(M.modifier_flags & MODIFIER_SKILL_VALUE) + LAZYINITLIST(skill_holder.skill_value_mods) + if(M.modifier_flags & MODIFIER_SKILL_AFFINITY) + LAZYINITLIST(skill_holder.skill_affinity_mods) + if(M.modifier_flags & MODIFIER_SKILL_LEVEL) + LAZYINITLIST(skill_holder.skill_level_mods) + for(var/path in GLOB.potential_skills_per_mod[M.target_skills_key]) + if(M.modifier_flags & MODIFIER_SKILL_VALUE) + ADD_MOD_STEP(skill_holder.skill_value_mods, path, skill_holder.original_values, get_skill_value(path, FALSE)) + if(M.modifier_flags & MODIFIER_SKILL_AFFINITY) + ADD_MOD_STEP(skill_holder.skill_affinity_mods, path, skill_holder.original_affinities, get_skill_affinity(path, FALSE)) + if(M.modifier_flags & MODIFIER_SKILL_LEVEL) + ADD_MOD_STEP(skill_holder.skill_level_mods, path, skill_holder.original_levels, get_skill_level(path, FALSE)) + LAZYSET(skill_holder.all_current_skill_modifiers, id, TRUE) + + if(M.modifier_flags & MODIFIER_SKILL_BODYBOUND) + M.RegisterSignal(src, COMSIG_MIND_TRANSFER, /datum/skill_modifier.proc/on_mind_transfer) + M.RegisterSignal(current, COMSIG_MOB_ON_NEW_MIND, /datum/skill_modifier.proc/on_mob_new_mind, TRUE) + RegisterSignal(M, COMSIG_PARENT_PREQDELETED, .proc/on_skill_modifier_deletion) + +#undef ADD_MOD_STEP + +#define REMOVE_MOD_STEP(L, P, O)\ + LAZYREMOVEASSOC(L, P, id);\ + if(M.modifier_flags & MODIFIER_SKILL_ORIGIN_DIFF){\ + LAZYREMOVEASSOC(O, id, "[P]")\ + } + +/datum/mind/proc/remove_skill_modifier(id, mind_transfer = FALSE) + if(!LAZYACCESS(skill_holder.all_current_skill_modifiers, id)) + return + var/datum/skill_modifier/M = GLOB.skill_modifiers[id] + if(!M) + CRASH("Invalid remove_skill_modifier id: [id].") + + if(!skill_holder.skill_value_mods && !skill_holder.skill_affinity_mods && !skill_holder.skill_level_mods) + return + for(var/path in GLOB.potential_skills_per_mod[M.target_skills_key]) + if(M.modifier_flags & MODIFIER_SKILL_VALUE && skill_holder.skill_value_mods) + REMOVE_MOD_STEP(skill_holder.skill_value_mods, path, skill_holder.original_values) + if(M.modifier_flags & MODIFIER_SKILL_AFFINITY && skill_holder.skill_affinity_mods) + REMOVE_MOD_STEP(skill_holder.skill_affinity_mods, path, skill_holder.original_affinities) + if(M.modifier_flags & MODIFIER_SKILL_LEVEL && skill_holder.skill_level_mods) + REMOVE_MOD_STEP(skill_holder.skill_level_mods, path, skill_holder.original_levels) + LAZYREMOVE(skill_holder.all_current_skill_modifiers, id) + + if(!mind_transfer && M.modifier_flags & MODIFIER_SKILL_BODYBOUND) + M.UnregisterSignal(src, COMSIG_MIND_TRANSFER) + M.UnregisterSignal(current, list(COMSIG_MOB_ON_NEW_MIND)) + UnregisterSignal(M, COMSIG_PARENT_PREQDELETED) + +#undef REMOVE_MOD_STEP + +/datum/mind/proc/on_skill_modifier_deletion(datum/skill_modifier/source) + remove_skill_modifier(source.identifier) + +/datum/skill_modifier/proc/apply_modifier(value, skillpath, datum/skill_holder/H, method = MODIFIER_TARGET_VALUE) + . = value + var/mod = value_mod + switch(method) + if(MODIFIER_TARGET_LEVEL) + mod = level_mod + if(MODIFIER_TARGET_AFFINITY) + mod = affinity_mod + + if(modifier_flags & MODIFIER_USE_THRESHOLDS && istext(mod)) + var/datum/skill/S = GLOB.skill_datums[skillpath] + if(method == MODIFIER_TARGET_VALUE && S.progression_type == SKILL_PROGRESSION_LEVEL) + var/datum/skill/level/L = S + switch(L.level_up_method) + if(STANDARD_LEVEL_UP) + mod = XP_LEVEL(L.standard_xp_lvl_up, L.xp_lvl_multiplier, S.competency_thresholds[mod]) + if(DWARFY_LEVEL_UP) + mod = DORF_XP_LEVEL(L.standard_xp_lvl_up, L.xp_lvl_multiplier, S.competency_thresholds[mod]) + else + mod = S.competency_thresholds[mod] + + var/diff = 0 + if(modifier_flags & (MODIFIER_SKILL_VIRTUE|MODIFIER_SKILL_HANDICAP)) + if(modifier_flags & MODIFIER_SKILL_VIRTUE) + . = max(., mod) + if(modifier_flags & MODIFIER_SKILL_HANDICAP) + . = min(., mod) + diff = . - mod + else if(modifier_flags & MODIFIER_SKILL_MULT) + . *= mod + else + . += mod + + if(modifier_flags & MODIFIER_SKILL_ORIGIN_DIFF) + var/list/to_access = H.original_values + switch(method) + if(MODIFIER_TARGET_LEVEL) + to_access = H.original_levels + if(MODIFIER_TARGET_AFFINITY) + to_access = H.original_affinities + . += value - diff - LAZYACCESS(to_access[identifier], "[skillpath]") + +///Body bound modifier signal procs. +/datum/skill_modifier/proc/on_mind_transfer(datum/mind/source, mob/new_character, mob/old_character) + source.remove_skill_modifier(identifier, TRUE) + UnregisterSignal(source, COMSIG_MIND_TRANSFER) + +/datum/skill_modifier/proc/on_mob_new_mind(mob/source) + source.mind.add_skill_modifier(identifier) + RegisterSignal(source.mind, COMSIG_MIND_TRANSFER, /datum/skill_modifier.proc/on_mind_transfer) diff --git a/code/datums/skills/engineering.dm b/code/datums/skills/engineering.dm index 59c9436e46..db7b33450c 100644 --- a/code/datums/skills/engineering.dm +++ b/code/datums/skills/engineering.dm @@ -2,5 +2,4 @@ name = "Wiring" desc = "How proficient and knowledged you are at wiring beyond laying cables on the floor." name_color = COLOR_PALE_ORANGE - competency_thresholds = list(JOB_SKILL_BASIC, JOB_SKILL_EXPERT, JOB_SKILL_MASTER) - skill_flags = SKILL_USE_MOOD|SKILL_TRAIN_MOOD|SKILL_USE_TOOL|SKILL_TRAINING_TOOL + skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE, SKILL_USE_TOOL, SKILL_TRAINING_TOOL) diff --git a/code/datums/skills/medical.dm b/code/datums/skills/medical.dm index aaae1236a6..404c141157 100644 --- a/code/datums/skills/medical.dm +++ b/code/datums/skills/medical.dm @@ -2,4 +2,4 @@ name = "Surgery" desc = "How proficient you are at doing surgery." name_color = COLOR_PALE_BLUE_GRAY - competency_mults = list(0.025, 0.025, 0.025) // 60% surgery speed up at max value of 100. + competency_multiplier = 1.5 // 60% surgery speed up at max value of 100, considering the base multiplier. diff --git a/code/datums/skills/modifiers/job.dm b/code/datums/skills/modifiers/job.dm new file mode 100644 index 0000000000..7d79ae89b3 --- /dev/null +++ b/code/datums/skills/modifiers/job.dm @@ -0,0 +1,35 @@ +/// Jobbie skill modifiers. + +/datum/skill_modifier/job + modifier_flags = MODIFIER_SKILL_VALUE|MODIFIER_SKILL_VIRTUE|MODIFIER_SKILL_ORIGIN_DIFF + priority = MODIFIER_SKILL_PRIORITY_MAX + +/datum/skill_modifier/job/surgery + target_skills = /datum/skill/numerical/surgery + value_mod = STARTING_SKILL_SURGERY_MEDICAL + +/datum/skill_modifier/job/affinity + modifier_flags = MODIFIER_SKILL_AFFINITY|MODIFIER_SKILL_VIRTUE + affinity_mod = STARTING_SKILL_AFFINITY_DEF_JOB + +/datum/skill_modifier/job/affinity/surgery + target_skills = /datum/skill/numerical/surgery + +/datum/skill_modifier/job/affinity/wiring + target_skills = /datum/skill/level/job/wiring + +/// Level skill modifiers below. +/datum/skill_modifier/job/level + modifier_flags = MODIFIER_SKILL_VALUE|MODIFIER_SKILL_LEVEL|MODIFIER_SKILL_VIRTUE|MODIFIER_SKILL_ORIGIN_DIFF + level_mod = JOB_SKILL_TRAINED + +/datum/skill_modifier/job/level/New(id) + if(level_mod) + value_mod = GET_STANDARD_LVL(level_mod) + ..() + +/datum/skill_modifier/job/level/wiring + target_skills = /datum/skill/level/job/wiring + +/datum/skill_modifier/job/level/wiring/basic + level_mod = JOB_SKILL_BASIC diff --git a/code/datums/skills/modifiers/mood.dm b/code/datums/skills/modifiers/mood.dm new file mode 100644 index 0000000000..30f24afcc4 --- /dev/null +++ b/code/datums/skills/modifiers/mood.dm @@ -0,0 +1,8 @@ +/datum/skill_modifier/bad_mood + modifier_flags = MODIFIER_SKILL_VALUE|MODIFIER_SKILL_LEVEL|MODIFIER_SKILL_MULT|MODIFIER_SKILL_BODYBOUND + target_skills = list(SKILL_SANITY) + +/datum/skill_modifier/great_mood + modifier_flags = MODIFIER_SKILL_AFFINITY|MODIFIER_SKILL_MULT|MODIFIER_SKILL_BODYBOUND + target_skills = list(SKILL_SANITY) + affinity_mod = 1.2 diff --git a/code/datums/skills/modifiers/organs.dm b/code/datums/skills/modifiers/organs.dm new file mode 100644 index 0000000000..13ebaf0658 --- /dev/null +++ b/code/datums/skills/modifiers/organs.dm @@ -0,0 +1,13 @@ +/datum/skill_modifier/brain_damage + target_skills = list(SKILL_INTELLIGENCE) + modifier_flags = MODIFIER_SKILL_VALUE|MODIFIER_SKILL_AFFINITY|MODIFIER_SKILL_LEVEL|MODIFIER_SKILL_MULT|MODIFIER_SKILL_BODYBOUND + value_mod = 0.85 + level_mod = 0.85 + affinity_mod = 0.85 + +/datum/skill_modifier/heavy_brain_damage + target_skills = list(SKILL_INTELLIGENCE) + modifier_flags = MODIFIER_SKILL_VALUE|MODIFIER_SKILL_AFFINITY|MODIFIER_SKILL_LEVEL|MODIFIER_SKILL_BODYBOUND|MODIFIER_SKILL_HANDICAP|MODIFIER_USE_THRESHOLDS + priority = MODIFIER_SKILL_PRIORITY_LOW + value_mod = THRESHOLD_COMPETENT + level_mod = THRESHOLD_COMPETENT diff --git a/code/datums/tgs_event_handler.dm b/code/datums/tgs_event_handler.dm new file mode 100644 index 0000000000..a3324121bf --- /dev/null +++ b/code/datums/tgs_event_handler.dm @@ -0,0 +1,20 @@ +/datum/tgs_event_handler/impl/HandleEvent(event_code, ...) + switch(event_code) + if(TGS_EVENT_REBOOT_MODE_CHANGE) + var/list/reboot_mode_lookup = list ("[TGS_REBOOT_MODE_NORMAL]" = "be normal", "[TGS_REBOOT_MODE_SHUTDOWN]" = "shutdown the server", "[TGS_REBOOT_MODE_RESTART]" = "hard restart the server") + var old_reboot_mode = args[2] + var new_reboot_mode = args[3] + message_admins("TGS: Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]") + if(TGS_EVENT_PORT_SWAP) + message_admins("TGS: Changing port from [world.port] to [args[2]]") + if(TGS_EVENT_INSTANCE_RENAMED) + message_admins("TGS: Instance renamed to from [world.TgsInstanceName()] to [args[2]]") + if(TGS_EVENT_COMPILE_START) + message_admins("TGS: Deployment started, new game version incoming...") + if(TGS_EVENT_COMPILE_CANCELLED) + message_admins("TGS: Deployment cancelled!") + if(TGS_EVENT_COMPILE_FAILURE) + message_admins("TGS: Deployment failed!") + if(TGS_EVENT_DEPLOYMENT_COMPLETE) + message_admins("TGS: Deployment complete!") + to_chat(world, "Server updated, changes will be applied on the next round...") diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index feb41cef0c..ce9513609a 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -138,7 +138,7 @@ if(current_users[user]) return FALSE if(req_skill && user?.mind) - var/level_diff = req_skill - user.mind.skill_holder.get_skill_level(/datum/skill/level/job/wiring) + var/level_diff = req_skill - user.mind.get_skill_level(/datum/skill/level/job/wiring, round = TRUE) if(level_diff > 0) LAZYSET(current_users, user, TRUE) to_chat(user, "You begin cutting [holder]'s [color] wire...") @@ -167,7 +167,7 @@ if(current_users[user]) return FALSE if(req_skill && user?.mind) - var/level_diff = req_skill - user.mind.skill_holder.get_skill_level(/datum/skill/level/job/wiring) + var/level_diff = req_skill - user.mind.get_skill_level(/datum/skill/level/job/wiring, round = TRUE) if(level_diff > 0) LAZYSET(current_users, user, TRUE) to_chat(user, "You begin pulsing [holder]'s [color] wire...") @@ -255,7 +255,7 @@ var/reveal_wires = FALSE // Admin ghost can see a purpose of each wire. - if(IsAdminGhost(user) || user.mind.skill_holder.get_skill_level(/datum/skill/level/job/wiring) >= req_knowledge) + if(IsAdminGhost(user) || user.mind.get_skill_level(/datum/skill/level/job/wiring) >= req_knowledge) reveal_wires = TRUE // Same for anyone with an abductor multitool. diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm index 59c195ded1..a9f48af64e 100644 --- a/code/game/area/areas/ruins/space.dm +++ b/code/game/area/areas/ruins/space.dm @@ -129,7 +129,26 @@ icon_state = "crew_quarters" +//Ruin of Space Diner +/area/ruin/space/diner + name = "Space Diner" + +/area/ruin/space/diner/interior + name = "Space Diner" + icon_state = "maintbar" + has_gravity = STANDARD_GRAVITY + blob_allowed = FALSE //Nope, no winning in the diner as a blob. Gotta eat the main station. + +/area/ruin/space/diner/solars + requires_power = FALSE + dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT + valid_territory = FALSE + blob_allowed = FALSE + flags_1 = NONE + ambientsounds = ENGINEERING + name = "Space Diner Solar Array" + icon_state = "yellow" //Ruin of Derelict Oupost diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 484a0d8e0e..1a0507f9df 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -581,6 +581,14 @@ SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode) return FALSE +/** + * Respond to a electric bolt action on our item + * + * Default behaviour is to return, we define here to allow for cleaner code later on + */ +/atom/proc/zap_act(power, zap_flags, shocked_targets) + return + /atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user) if(GetComponent(/datum/component/storage)) return component_storage_contents_dump_act(src_object, user) @@ -932,14 +940,14 @@ Proc for attack log creation, because really why not target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) // Filter stuff -/atom/movable/proc/add_filter(name,priority,list/params) +/atom/proc/add_filter(name,priority,list/params) LAZYINITLIST(filter_data) var/list/p = params.Copy() p["priority"] = priority filter_data[name] = p update_filters() -/atom/movable/proc/update_filters() +/atom/proc/update_filters() filters = null filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE) for(var/f in filter_data) @@ -948,11 +956,11 @@ Proc for attack log creation, because really why not arguments -= "priority" filters += filter(arglist(arguments)) -/atom/movable/proc/get_filter(name) +/atom/proc/get_filter(name) if(filter_data && filter_data[name]) return filters[filter_data.Find(name)] -/atom/movable/proc/remove_filter(name) +/atom/proc/remove_filter(name) if(filter_data && filter_data[name]) filter_data -= name update_filters() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index fe617ddb0f..9736f473e8 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -37,6 +37,8 @@ var/throwforce = 0 var/datum/component/orbiter/orbiting var/can_be_z_moved = TRUE + ///If we were without gravity and another animation happened, the bouncing will stop, and we need to restart it in next life(). + var/floating_need_update = FALSE var/zfalling = FALSE @@ -56,10 +58,6 @@ em_block = new(src, render_target) vis_contents += em_block -/atom/movable/Destroy() - QDEL_NULL(em_block) - return ..() - /atom/movable/proc/update_emissive_block() if(blocks_emissive != EMISSIVE_BLOCK_GENERIC) return @@ -183,14 +181,15 @@ return TRUE /atom/movable/proc/stop_pulling() - if(pulling) - pulling.pulledby = null - var/mob/living/ex_pulled = pulling - pulling = null - setGrabState(0) - if(isliving(ex_pulled)) - var/mob/living/L = ex_pulled - L.update_mobility()// mob gets up if it was lyng down in a chokehold + if(!pulling) + return + pulling.pulledby = null + var/mob/living/ex_pulled = pulling + pulling = null + setGrabState(0) + if(isliving(ex_pulled)) + var/mob/living/L = ex_pulled + L.update_mobility()// mob gets up if it was lyng down in a chokehold /atom/movable/proc/Move_Pulled(atom/A) if(!pulling) @@ -232,10 +231,12 @@ /atom/movable/Destroy(force) QDEL_NULL(proximity_monitor) QDEL_NULL(language_holder) + QDEL_NULL(em_block) unbuckle_all_mobs(force=1) . = ..() + if(loc) //Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary) if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc)) @@ -493,15 +494,16 @@ /atom/movable/proc/float(on) if(throwing) return - if(on && !(movement_type & FLOATING)) + if(on && (!(movement_type & FLOATING) || floating_need_update)) animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) sleep(10) animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) - setMovetype(movement_type | FLOATING) - else if (!on && (movement_type & FLOATING)) + if(!(movement_type & FLOATING)) + setMovetype(movement_type | FLOATING) + else if (!on && movement_type & FLOATING) animate(src, pixel_y = initial(pixel_y), time = 10) setMovetype(movement_type & ~FLOATING) - + floating_need_update = FALSE /* Language procs * Unless you are doing something very specific, these are the ones you want to use. diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index dca50be5b9..af75315ded 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -48,9 +48,6 @@ /obj/machinery/dominator/hulk_damage() return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED -/obj/machinery/dominator/tesla_act() - qdel(src) - /obj/machinery/dominator/update_icon() cut_overlays() if(stat & BROKEN) diff --git a/code/game/gamemodes/gangs/gang_decals.dm b/code/game/gamemodes/gangs/gang_decals.dm index 7aaed769d9..a37b4cb63b 100644 --- a/code/game/gamemodes/gangs/gang_decals.dm +++ b/code/game/gamemodes/gangs/gang_decals.dm @@ -10,7 +10,7 @@ /obj/effect/decal/cleanable/crayon/gang icon = 'icons/effects/crayondecal.dmi' layer = ABOVE_NORMAL_TURF_LAYER //Harder to hide - plane = GAME_PLANE + plane = ABOVE_WALL_PLANE do_icon_rotate = FALSE //These are designed to always face south, so no rotation please. var/datum/team/gang/gang diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index fad27aaa25..02d3ccab46 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -37,6 +37,11 @@ reset_chem_buttons() RefreshParts() add_inital_chems() + new_occupant_dir = dir + +/obj/machinery/sleeper/setDir(newdir) + . = ..() + new_occupant_dir = dir /obj/machinery/sleeper/on_deconstruction() var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 93121a0753..e2f26d6617 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -110,7 +110,8 @@ Class Procs: var/state_open = FALSE var/critical_machine = FALSE //If this machine is critical to station operation and should have the area be excempted from power failures. var/list/occupant_typecache //if set, turned into typecache in Initialize, other wise, defaults to mob/living typecache - var/atom/movable/occupant = null + var/atom/movable/occupant + var/new_occupant_dir = SOUTH //The direction the occupant will be set to look at when entering the machine. var/speed_process = FALSE // Process as fast as possible? var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created // For storing and overriding ui id and dimensions @@ -217,6 +218,7 @@ Class Procs: if(target && !target.has_buckled_mobs() && (!isliving(target) || !mobtarget.buckled)) occupant = target target.forceMove(src) + target.setDir(new_occupant_dir) updateUsrDialog() update_icon() @@ -520,11 +522,11 @@ Class Procs: /obj/machinery/proc/can_be_overridden() . = 1 -/obj/machinery/tesla_act(power, tesla_flags, shocked_objects) - ..() - if(prob(85) && (tesla_flags & TESLA_MACHINE_EXPLOSIVE)) +/obj/machinery/zap_act(power, zap_flags, shocked_objects) + . = ..() + if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE)) explosion(src, 1, 2, 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) - if(tesla_flags & TESLA_OBJ_DAMAGE) + else if(zap_flags & ZAP_OBJ_DAMAGE) take_damage(power/2000, BURN, "energy") if(prob(40)) emp_act(EMP_LIGHT) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 669f810c06..00d62aa251 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -3,6 +3,7 @@ desc = "A remote control switch." icon = 'icons/obj/stationobjs.dmi' icon_state = "doorctrl" + plane = ABOVE_WALL_PLANE var/skin = "doorctrl" power_channel = ENVIRON var/obj/item/assembly/device @@ -17,7 +18,7 @@ /obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) if(istext(id) && mapload) - if(copytext(id, 1, 2) == "!") + if(id[1] == "!") id = SSmapping.get_obfuscated_id(id) . = ..() if(built) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 9c1177cb90..1066261f85 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -225,7 +225,7 @@ desc = "Used for watching an empty arena." icon = 'icons/obj/stationobjs.dmi' icon_state = "telescreen" - layer = SIGN_LAYER + plane = ABOVE_WALL_PLANE network = list("thunder") density = FALSE circuit = null diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 07f95c17ff..9330a30555 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -242,6 +242,7 @@ if((isnull(user) || istype(user)) && state_open && !panel_open) ..(user) var/mob/living/mob_occupant = occupant + investigate_log("Cryogenics machine closed with occupant [key_name(occupant)] by user [key_name(user)].", INVESTIGATE_CRYOGENICS) if(mob_occupant && mob_occupant.stat != DEAD) to_chat(occupant, "You feel cool air surround you. You go numb as your senses turn inward.") if(mob_occupant.client)//if they're logged in @@ -251,12 +252,15 @@ icon_state = "cryopod" /obj/machinery/cryopod/open_machine() + if(occupant) + investigate_log("Cryogenics machine opened with occupant [key_name(occupant)] inside.", INVESTIGATE_CRYOGENICS) ..() icon_state = "cryopod-open" density = TRUE name = initial(name) /obj/machinery/cryopod/container_resist(mob/living/user) + investigate_log("Cryogenics machine container resisted by [key_name(user)] with occupant [key_name(occupant)].", INVESTIGATE_CRYOGENICS) visible_message("[occupant] emerges from [src]!", "You climb out of [src]!") open_machine() @@ -304,6 +308,8 @@ var/mob/living/mob_occupant = occupant var/list/obj/item/cryo_items = list() + + investigate_log("Despawning [key_name(mob_occupant)].", INVESTIGATE_CRYOGENICS) //Handle Borg stuff first if(iscyborg(mob_occupant)) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index cb53ea16e0..d511ff0c95 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -474,15 +474,15 @@ if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(lights && hasPower()) if(locked) - lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) else if(emergency) - lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(note) note_overlay = get_airlock_overlay(notetype, note_overlay_file) @@ -500,18 +500,18 @@ else panel_overlay = get_airlock_overlay("panel_closed", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) - lights_overlay = get_airlock_overlay("lights_denied", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + lights_overlay = get_airlock_overlay("lights_denied", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(note) note_overlay = get_airlock_overlay(notetype, note_overlay_file) if(AIRLOCK_EMAG) frame_overlay = get_airlock_overlay("closed", icon) - sparks_overlay = get_airlock_overlay("sparks", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + sparks_overlay = get_airlock_overlay("sparks", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(airlock_material) filling_overlay = get_airlock_overlay("[airlock_material]_closed", overlays_file) else @@ -522,9 +522,9 @@ else panel_overlay = get_airlock_overlay("panel_closed", overlays_file) if(obj_integrity < integrity_failure * max_integrity) - damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) else if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(welded) weld_overlay = get_airlock_overlay("welded", overlays_file) if(note) @@ -537,7 +537,7 @@ else filling_overlay = get_airlock_overlay("fill_closing", icon) if(lights && hasPower()) - lights_overlay = get_airlock_overlay("lights_closing", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + lights_overlay = get_airlock_overlay("lights_closing", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(panel_open) if(security_level) panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file) @@ -558,7 +558,7 @@ else panel_overlay = get_airlock_overlay("panel_open", overlays_file) if(obj_integrity < (0.75 * max_integrity)) - damag_overlay = get_airlock_overlay("sparks_open", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + damag_overlay = get_airlock_overlay("sparks_open", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(note) note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file) @@ -569,7 +569,7 @@ else filling_overlay = get_airlock_overlay("fill_opening", icon) if(lights && hasPower()) - lights_overlay = get_airlock_overlay("lights_opening", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + lights_overlay = get_airlock_overlay("lights_opening", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE) if(panel_open) if(security_level) panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index fe01438998..5a1ed7dd19 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -21,6 +21,7 @@ icon = 'icons/obj/status_display.dmi' icon_state = "frame" desc = "A remote control for a door." + plane = ABOVE_WALL_PLANE req_access = list(ACCESS_SECURITY) density = FALSE var/id // id of linked machinery/lockers diff --git a/code/game/machinery/embedded_controller/simple_vent_controller.dm b/code/game/machinery/embedded_controller/simple_vent_controller.dm index 6c8467dbd3..6416de70f1 100644 --- a/code/game/machinery/embedded_controller/simple_vent_controller.dm +++ b/code/game/machinery/embedded_controller/simple_vent_controller.dm @@ -34,7 +34,7 @@ /obj/machinery/embedded_controller/radio/simple_vent_controller icon = 'icons/obj/airlock_machines.dmi' icon_state = "airlock_control_standby" - + plane = ABOVE_WALL_PLANE name = "vent controller" density = FALSE diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 6501a5b45e..8869ea396e 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -17,6 +17,7 @@ desc = "\"Pull this in case of emergency\". Thus, keep pulling it forever." icon = 'icons/obj/monitors.dmi' icon_state = "fire0" + plane = ABOVE_WALL_PLANE max_integrity = 250 integrity_failure = 0.4 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 1d159e2633..c0e1122140 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -5,6 +5,7 @@ desc = "A wall-mounted flashbulb device." icon = 'icons/obj/stationobjs.dmi' icon_state = "mflash1" + plane = ABOVE_WALL_PLANE max_integrity = 250 integrity_failure = 0.4 light_color = LIGHT_COLOR_WHITE @@ -20,6 +21,7 @@ name = "portable flasher" desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements." icon_state = "pflash1-p" + plane = GAME_PLANE strength = 80 anchored = FALSE base_state = "pflash" diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 244c300905..141f261688 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -20,6 +20,11 @@ . = ..() if(prob(1)) name = "auto-autopsy" + new_occupant_dir = dir + +/obj/machinery/harvester/setDir(newdir) + . = ..() + new_occupant_dir = dir /obj/machinery/harvester/RefreshParts() interval = 0 diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 3a79ff3c82..621e486e90 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -34,7 +34,7 @@ GLOBAL_LIST_EMPTY(network_holopads) desc = "It's a floor-mounted device for projecting holographic images." icon_state = "holopad0" layer = LOW_OBJ_LAYER - plane = FLOOR_PLANE + plane = ABOVE_WALL_PLANE flags_1 = HEAR_1 use_power = IDLE_POWER_USE idle_power_usage = 5 diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index b2a35dcf41..421e3433ca 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -5,6 +5,7 @@ name = "light switch" icon = 'icons/obj/power.dmi' icon_state = "light1" + plane = ABOVE_WALL_PLANE desc = "Make dark." var/on = TRUE var/area/area = null diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 000585a4be..d55faf2343 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_EMPTY(allConsoles) desc = "A console intended to send requests to different departments on the station." icon = 'icons/obj/terminals.dmi' icon_state = "req_comp0" + plane = ABOVE_WALL_PLANE var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department var/list/messages = list() //List of all messages var/departmentType = 0 diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 60d9a7376c..e516f6b02d 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -115,8 +115,8 @@ return PROCESS_KILL /obj/machinery/space_heater/RefreshParts() - var/laser = 0 - var/cap = 0 + var/laser = 2 + var/cap = 1 for(var/obj/item/stock_parts/micro_laser/M in component_parts) laser += M.rating for(var/obj/item/stock_parts/capacitor/M in component_parts) @@ -166,6 +166,11 @@ else return ..() +/obj/machinery/space_heater/wrench_act(mob/living/user, obj/item/I) + ..() + default_unfasten_wrench(user, I, 5) + return TRUE + /obj/machinery/space_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index abdafd8f6e..3bb67e2a1c 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -21,6 +21,7 @@ desc = null icon = 'icons/obj/status_display.dmi' icon_state = "frame" + plane = ABOVE_WALL_PLANE density = FALSE use_power = IDLE_POWER_USE idle_power_usage = 10 diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index f618888d98..ee28f118fa 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -11,9 +11,6 @@ var/insisting = 0 /obj/machinery/wish_granter/attack_hand(mob/living/carbon/user) - . = ..() - if(.) - return if(charges <= 0) to_chat(user, "The Wish Granter lies silent.") return @@ -22,22 +19,116 @@ to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.") return - else if(is_special_character(user)) - to_chat(user, "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.") - else if (!insisting) to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?") insisting++ else - to_chat(user, "You speak. [pick("I want the station to disappear","Humanity is corrupt, mankind must be destroyed","I want to be rich", "I want to rule the world","I want immortality.")]. The Wish Granter answers.") - to_chat(user, "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.") + if(is_special_character(user)) + to_chat(user, "You speak. [pick("I want power","Humanity is corrupt, mankind must be destroyed", "I want to rule the world","I want immortality")]. The Wish Granter answers.") + to_chat(user, "Your head pounds for a moment, before your vision clears. The Wish Granter, sensing the darkness in your heart, has given you limitless power, and it's all yours!") + user.dna.add_mutation(HULK) + user.dna.add_mutation(XRAY) + user.dna.add_mutation(SPACEMUT) + user.dna.add_mutation(TK) + user.next_move_modifier *= 0.5 //half the delay between attacks! + to_chat(user, "Things around you feel slower!") + charges-- + insisting = FALSE + to_chat(user, "You have a very great feeling about this!") + else + to_chat(user, "The Wish Granter awaits your wish.") + var/wish = input("You want...","Wish") as null|anything in list("Power","Wealth","The Station To Disappear","To Kill","Nothing") + switch(wish) + if("Power") //Gives infinite power in exchange for infinite power going off in your face! + if(charges <= 0) + return + to_chat(user, "Your wish is granted, but at a terrible cost...") + to_chat(user, "The Wish Granter punishes you for your selfishness, warping itself into a delaminating supermatter shard!") + var/obj/item/stock_parts/cell/infinite/powah = new /obj/item/stock_parts/cell/infinite(get_turf(user)) + if(user.put_in_hands(powah)) + to_chat(user, "[powah] materializes into your hands!") + else + to_chat(user, "[powah] materializes onto the floor.") + var/obj/machinery/power/supermatter_crystal/powerwish = new /obj/machinery/power/supermatter_crystal(loc) + powerwish.damage = 700 //right at the emergency threshold + powerwish.produces_gas = FALSE + charges-- + insisting = FALSE + if(!charges) + qdel(src) + if("Wealth") //Gives 1 million space bucks in exchange for being turned into gold! + if(charges <= 0) + return + to_chat(user, "Your wish is granted, but at a cost...") + to_chat(user, "The Wish Granter punishes you for your selfishness, warping your body to match the greed in your heart.") + new /obj/structure/closet/crate/trashcart/moneywish(loc) + new /obj/structure/closet/crate/trashcart/moneywish(loc) + user.set_species(/datum/species/golem/gold) + charges-- + insisting = FALSE + if(!charges) + qdel(src) + if("The Station To Disappear") //teleports you to the station and makes you blind, making the station disappear for you! + if(charges <= 0) + return + to_chat(user, "Your wish is 'granted', but at a terrible cost...") + to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your eyes to match the darkness in your heart.") + user.dna.add_mutation(BLINDMUT) + var/obj/item/organ/eyes/eyes = user.getorganslot(ORGAN_SLOT_EYES) + if(eyes) + eyes.applyOrganDamage(eyes.maxHealth) + var/list/destinations = list() + for(var/obj/item/beacon/B in GLOB.teleportbeacons) + var/turf/T = get_turf(B) + if(is_station_level(T.z)) + destinations += B + var/chosen_beacon = pick(destinations) + var/obj/effect/portal/jaunt_tunnel/J = new (get_turf(src), src, 100, null, FALSE, get_turf(chosen_beacon)) + try_move_adjacent(J) + playsound(src,'sound/effects/sparks4.ogg',50,1) + charges-- + insisting = FALSE + if(!charges) + qdel(src) + if("To Kill") //Makes you kill things in exchange for rewards! + if(charges <= 0) + return + to_chat(user, "Your wish is granted, but at a terrible cost...") + to_chat(user, "The Wish Granter punishes you for your wickedness, warping itself into a dastardly creature for you to kill! ...but it almost seems to reward you for this.") + var/obj/item/melee/transforming/energy/sword/cx/killreward = new /obj/item/melee/transforming/energy/sword/cx(get_turf(user)) + if(user.put_in_hands(killreward)) + to_chat(user, "[killreward] materializes into your hands!") + else + to_chat(user, "[killreward] materializes onto the floor.") + user.next_move_modifier *= 0.8 //20% less delay between attacks! + to_chat(user, "Things around you feel slightly slower!") + var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc) + killwish.maxHealth = 1500 + killwish.health = killwish.maxHealth + killwish.vine_grab_distance = 6 + killwish.melee_damage_upper = 30 + killwish.loot = list(/obj/item/twohanded/dualsaber/hypereutactic) + charges-- + insisting = FALSE + if(!charges) + qdel(src) + if("Nothing") //Makes the wish granter disappear + if(charges <= 0) + return + to_chat(user, "The Wish Granter vanishes from sight!") + to_chat(user, "You feel as if you just narrowly avoided a terrible fate...") + charges-- + insisting = FALSE + qdel(src) - charges-- - insisting = 0 +//ITEMS THAT IT USES - user.mind.add_antag_datum(/datum/antagonist/wishgranter) +/obj/structure/closet/crate/trashcart/moneywish + desc = "A heavy, metal trashcart with wheels. Filled with cash." + name = "loaded trash cart" - to_chat(user, "You have a very bad feeling about this.") - - return +/obj/structure/closet/crate/trashcart/moneywish/PopulateContents() //25*20*1000=500,000 + for(var/i in 1 to 25) + var/obj/item/stack/spacecash/c1000/lodsamoney = new /obj/item/stack/spacecash/c1000(src) + lodsamoney.amount = lodsamoney.max_amount diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm index c678912a21..fdcc4df151 100644 --- a/code/game/mecha/combat/neovgre.dm +++ b/code/game/mecha/combat/neovgre.dm @@ -62,18 +62,21 @@ /obj/mecha/combat/neovgre/process() ..() - if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hople to stop the superweapon + if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hope to stop the superweapon cell.charge = INFINITY max_integrity = INFINITY obj_integrity = max_integrity CHECK_TICK //Just to be on the safe side lag wise - else if(cell.charge < cell.maxcharge) - for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src)) - var/delta = min(recharge_rate, cell.maxcharge - cell.charge) - if (get_clockwork_power() <= delta) - cell.charge += delta - adjust_clockwork_power(-delta) - CHECK_TICK + else + if(cell.charge < cell.maxcharge) + for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src)) + var/delta = min(recharge_rate, cell.maxcharge - cell.charge) + if (get_clockwork_power() >= delta) + cell.charge += delta + adjust_clockwork_power(-delta) + if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork)) + obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200) + CHECK_TICK /obj/mecha/combat/neovgre/Initialize() .=..() @@ -90,7 +93,7 @@ energy_drain = 30 name = "Aribter Laser Cannon" desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere" - fire_sound = "sound/weapons/neovgre_laser.ogg" + fire_sound = 'sound/weapons/neovgre_laser.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M) if(istype(M)) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 02115d3e30..32be825489 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -23,11 +23,11 @@ layer = BELOW_MOB_LAYER//icon draw layer infra_luminosity = 15 //byond implementation is bugged. force = 5 - flags_1 = HEAR_1 + flags_1 = HEAR_1|BLOCK_FACE_ATOM_1 var/can_move = 0 //time of next allowed movement - var/mob/living/carbon/occupant = null + var/mob/living/occupant = null var/step_in = 10 //make a step in step_in/10 sec. - var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. + var/dir_in = SOUTH //What direction will the mech face when entered/powered on? Defaults to South. var/normal_step_energy_drain = 10 //How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. var/step_energy_drain = 10 var/melee_energy_drain = 15 @@ -495,6 +495,10 @@ occupant_message("Air port connection teared off!") mecha_log_message("Lost connection to gas port.") +/obj/mecha/setDir(newdir) + . = ..() + occupant?.setDir(newdir) + /obj/mecha/Process_Spacemove(var/movement_dir = 0) . = ..() if(.) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 53768fe9a9..1fe7f74dec 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -77,7 +77,7 @@ /obj/mecha/attack_animal(mob/living/simple_animal/user) mecha_log_message("Attack by simple animal. Attacker - [user].", color="red") if(!user.melee_damage_upper && !user.obj_damage) - user.emote("custom", message = "[user.friendly] [src].") + user.emote("custom", message = "[user.friendly_verb_continuous] [src].") return 0 else var/play_soundeffect = 1 diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index 8d6328cf08..b1ab944b49 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -333,10 +333,13 @@ send_byjax(occupant,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port") if(href_list["dna_lock"]) - if(occupant && !iscarbon(occupant)) - to_chat(occupant, " You do not have any DNA!") + if(!occupant) return - dna_lock = occupant.dna.unique_enzymes + var/mob/living/carbon/C = occupant + if(!istype(C) || !C.dna) + to_chat(C, " You do not have any DNA!") + return + dna_lock = C.dna.unique_enzymes occupant_message("You feel a prick as the needle takes your DNA sample.") if(href_list["reset_dna"]) diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index 6b61eb2ebd..69aa3fb654 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -49,6 +49,7 @@ var/original_name desc = "A large piece of space-resistant printed paper." icon = 'icons/obj/contraband.dmi' + plane = ABOVE_WALL_PLANE anchored = TRUE var/ruined = FALSE var/random_basetype diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 955b9935dd..8cfdad0432 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -3,7 +3,7 @@ desc = "Graffiti. Damn kids." icon = 'icons/effects/crayondecal.dmi' icon_state = "rune1" - plane = GAME_PLANE //makes the graffiti visible over a wall. + plane = ABOVE_WALL_PLANE //makes the graffiti visible over a wall. gender = NEUTER mergeable_decal = FALSE var/do_icon_rotate = TRUE diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm index 3e7706282a..5dbd18aa0c 100644 --- a/code/game/objects/effects/decals/decal.dm +++ b/code/game/objects/effects/decals/decal.dm @@ -35,6 +35,7 @@ icon = 'icons/turf/decals.dmi' icon_state = "warningline" layer = TURF_DECAL_LAYER + plane = ABOVE_WALL_PLANE /obj/effect/turf_decal/Initialize() ..() diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 992e9c84a7..6910bb1db0 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -469,6 +469,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/stationroom var/list/templates = list() layer = BULLET_HOLE_LAYER + plane = ABOVE_WALL_PLANE /obj/effect/landmark/stationroom/New() ..() diff --git a/code/game/objects/effects/spawners/structure.dm b/code/game/objects/effects/spawners/structure.dm index cdf3f3e6b4..7a151c4312 100644 --- a/code/game/objects/effects/spawners/structure.dm +++ b/code/game/objects/effects/spawners/structure.dm @@ -24,6 +24,23 @@ again. name = "window spawner" spawn_list = list(/obj/structure/grille, /obj/structure/window/fulltile) dir = SOUTH + var/electrochromatic + var/electrochromatic_id + +/obj/effect/spawner/structure/window/Initialize() + . = ..() + if(!electrochromatic) + return + if(!electrochromatic_id) + stack_trace("Electrochromatic window spawner set without electromatic id.") + return + if(electrochromatic_id[1] == "!") + electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id) + for(var/obj/structure/window/W in get_turf(src)) + W.electrochromatic_id = electrochromatic_id + W.make_electrochromatic() + if(electrochromatic == ELECTROCHROMATIC_DIMMED) + W.electrochromatic_dim() /obj/effect/spawner/structure/window/hollow name = "hollow window spawner" @@ -140,13 +157,16 @@ again. spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/spawner/north, /obj/structure/window/reinforced/spawner/west) . = ..() -//tinted +//tinted and electrochromatic /obj/effect/spawner/structure/window/reinforced/tinted name = "tinted reinforced window spawner" icon_state = "twindow_spawner" spawn_list = list(/obj/structure/grille, /obj/structure/window/reinforced/tinted/fulltile) +/obj/effect/spawner/structure/window/reinforced/tinted/electrochromatic + name = "electrochromatic reinforced window spawner" + electrochromatic = ELECTROCHROMATIC_DIMMED //shuttle window diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 949ed050f5..2a4b6d7df5 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -135,7 +135,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) ///Skills vars //list of skill PATHS exercised when using this item. An associated bitfield can be set to indicate additional ways the skill is used by this specific item. var/list/datum/skill/used_skills - var/skill_difficulty = THRESHOLD_COMPETENT //how difficult it's to use this item in general. + var/skill_difficulty = THRESHOLD_UNTRAINED //how difficult it's to use this item in general. var/skill_gain = DEF_SKILL_GAIN //base skill value gain from using this item. /obj/item/Initialize() @@ -782,10 +782,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/user = usr tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it. -/obj/item/MouseExited() +/obj/item/MouseExited(location,control,params) + SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params) deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes closeToolTip(usr) +/obj/item/MouseEntered(location,control,params) + SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params) // Called when a mob tries to use the item as a tool. // Handles most checks. @@ -802,7 +805,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(delay) if(user.mind && used_skills) - delay = user.mind.skill_holder.item_action_skills_mod(src, delay, skill_difficulty, SKILL_USE_TOOL, NONE, FALSE) + delay = user.mind.item_action_skills_mod(src, delay, skill_difficulty, SKILL_USE_TOOL, null, FALSE) // Create a callback with checks that would be called every tick by do_after. var/datum/callback/tool_check = CALLBACK(src, .proc/tool_check_callback, user, amount, extra_checks) @@ -828,11 +831,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(delay >= MIN_TOOL_SOUND_DELAY) play_tool_sound(target, volume) + if(user.mind && used_skills && skill_gain_mult) + var/gain = skill_gain + delay/SKILL_GAIN_DELAY_DIVISOR for(var/skill in used_skills) - if(!(used_skills[skill] & SKILL_TRAINING_TOOL)) + if(!(SKILL_TRAINING_TOOL in used_skills[skill])) continue - user.mind.skill_holder.auto_gain_experience(skill, skill_gain*skill_gain_mult, GET_STANDARD_LVL(max_level)) + user.mind.auto_gain_experience(skill, gain*skill_gain_mult, GET_STANDARD_LVL(max_level)) return TRUE diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 7f6e561f55..cb44b82ad2 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -143,8 +143,8 @@ RLD //if user can't be seen from A (only checks surroundings' opaqueness) and can't see A. //jarring, but it should stop people from targetting atoms they can't see... //excluding darkness, to allow RLD to be used to light pitch black dark areas. - if(!((user in view(view_range, A)) || (user in viewers(view_range, A)))) - to_chat(user, "You focus, pointing \the [src] at whatever outside your field of vision in the given direction... to no avail.") + if(!((user in view(view_range, A)) || (user in fov_viewers(view_range, A)))) + to_chat(user, "You focus, pointing \the [src] at whatever outside your field of vision in that direction... to no avail.") return FALSE return TRUE diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 8a5723e894..7036a78bc4 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -311,20 +311,19 @@ registered_account.bank_card_talk("ERROR: UNABLE TO LOGIN DUE TO SCHEDULED MAINTENANCE. MAINTENANCE IS SCHEDULED TO COMPLETE IN [(registered_account.withdrawDelay - world.time)/10] SECONDS.", TRUE) return - var/amount_to_remove = FLOOR(input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null, 1) + var/amount_to_remove = input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null if(!amount_to_remove || amount_to_remove < 0) return if(!alt_click_can_use_id(user)) return - if(registered_account.adjust_money(-amount_to_remove)) + amount_to_remove = FLOOR(min(amount_to_remove, registered_account.account_balance), 1) + if(amount_to_remove && registered_account.adjust_money(-amount_to_remove)) var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove) user.put_in_hands(holochip) to_chat(user, "You withdraw [amount_to_remove] credits into a holochip.") return - else - var/difference = amount_to_remove - registered_account.account_balance - registered_account.bank_card_talk("ERROR: The linked account requires [difference] more credit\s to perform that withdrawal.", TRUE) + registered_account.bank_card_talk("ERROR: The linked account has no sufficient credits to perform that withdrawal.", TRUE) /obj/item/card/id/examine(mob/user) . = ..() diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 3fb2b820c3..bd3ded5bbf 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -91,6 +91,11 @@ refill() +/obj/item/toy/crayon/examine(mob/user) + . = ..() + if(can_change_colour) + . += "Ctrl-click [src] while it's on your person to quickly recolour it." + /obj/item/toy/crayon/proc/refill() if(charges == -1) charges_left = 100 @@ -160,6 +165,12 @@ update_icon() return TRUE +/obj/item/toy/crayon/CtrlClick(mob/user) + if(can_change_colour && !isturf(loc) && user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + select_colour(user) + else + return ..() + /obj/item/toy/crayon/proc/staticDrawables() . = list() @@ -237,14 +248,7 @@ else paint_mode = PAINT_NORMAL if("select_colour") - if(can_change_colour) - var/chosen_colour = input(usr,"","Choose Color",paint_color) as color|null - - if (!isnull(chosen_colour)) - paint_color = chosen_colour - . = TRUE - else - . = FALSE + . = can_change_colour && select_colour(usr) if("enter_text") var/txt = stripped_input(usr,"Choose what to write.", "Scribbles",default = text_buffer) @@ -254,6 +258,13 @@ drawtype = "a" update_icon() +/obj/item/toy/crayon/proc/select_colour(mob/user) + var/chosen_colour = input(user, "", "Choose Color", paint_color) as color|null + if (!isnull(chosen_colour) && user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + paint_color = chosen_colour + return TRUE + return FALSE + /obj/item/toy/crayon/proc/crayon_text_strip(text) var/static/regex/crayon_r = new /regex(@"[^\w!?,.=%#&+\/\-]") return replacetext(lowertext(text), crayon_r, "") diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 3ac3347222..7cc76da312 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -433,7 +433,7 @@ H.visible_message("The defibrillator safely discharges the excessive charge into the floor!") return var/mob/living/M = H.pulledby - if(M.electrocute_act(30, src)) + if(M.electrocute_act(30, H)) M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!") M.emote("scream") diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 9c94348fc2..c931d92379 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -135,7 +135,8 @@ outmsg = "You miss the lens of [C] with [src]!" //catpeople - for(var/mob/living/carbon/human/H in view(1,targloc)) + var/list/viewers = fov_viewers(1,targloc) + for(var/mob/living/carbon/human/H in viewers) if(!iscatperson(H) || H.incapacitated() || H.eye_blind ) continue if(!H.lying) @@ -150,7 +151,7 @@ H.visible_message("[H] stares at the light"," You stare at the light... ") //cats! - for(var/mob/living/simple_animal/pet/cat/C in view(1,targloc)) + for(var/mob/living/simple_animal/pet/cat/C in viewers) if(prob(50)) C.visible_message("[C] pounces on the light!","LIGHT!") C.Move(targloc) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index ada598866b..f4c317c8ba 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -2,6 +2,7 @@ name = "station intercom" desc = "Talk through this." icon_state = "intercom" + plane = ABOVE_WALL_PLANE anchored = TRUE w_class = WEIGHT_CLASS_BULKY canhear_range = 2 diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index e2140bd0fd..c785c22813 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -196,9 +196,8 @@ sleep(1) previousturf = T operating = FALSE - for(var/mob/M in viewers(1, loc)) - if((M.client && M.machine == src)) - attack_self(M) + if(usr.machine == src) + attack_self(usr) /obj/item/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05) diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm index 7c863017a1..4766e534c9 100644 --- a/code/game/objects/items/implants/implantpad.dm +++ b/code/game/objects/items/implants/implantpad.dm @@ -66,7 +66,7 @@ if(ismob(loc)) attack_self(loc) else - for(var/mob/M in viewers(1, src)) + for(var/mob/M in fov_viewers(1, src)) if(M.client) attack_self(M) add_fingerprint(usr) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index fc7b196bd2..1459afeb2d 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -197,10 +197,10 @@ if(obj_integrity >= max_integrity) to_chat(user, "[src] is already in perfect condition.") else - var/obj/item/stack/sheet/mineral/titanium/T = W - T.use(1) + var/obj/item/stack/S = W + S.use(1) obj_integrity = max_integrity - to_chat(user, "You repair [src] with [T].") + to_chat(user, "You repair [src] with [S].") else return ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 835dd8b548..66f8ecc7e4 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -5,7 +5,6 @@ * Wood * Bamboo * Cloth - * Silk * Durathread * Cardboard * Runed Metal (cult) @@ -269,6 +268,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\ null, \ new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\ + new/datum/stack_recipe("painting frame", /obj/item/wallframe/painting, 1, time = 10),\ new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \ new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\ )) @@ -389,6 +389,9 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ null, \ new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 2), \ null, \ + new/datum/stack_recipe("19x19 canvas", /obj/item/canvas/nineteenXnineteen, 3), \ + new/datum/stack_recipe("23x19 canvas", /obj/item/canvas/twentythreeXnineteen, 4), \ + new/datum/stack_recipe("23x23 canvas", /obj/item/canvas/twentythreeXtwentythree, 5), \ )) /obj/item/stack/sheet/cloth @@ -402,7 +405,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ throwforce = 0 pull_effort = 90 is_fabric = TRUE - loom_result = /obj/item/stack/sheet/silk merge_type = /obj/item/stack/sheet/cloth /obj/item/stack/sheet/cloth/get_main_recipes() @@ -415,30 +417,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /obj/item/stack/sheet/cloth/thirty amount = 30 -/* - * Silk - */ - - GLOBAL_LIST_INIT(silk_recipes, list ( \ - new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 4, time = 40), \ - new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 2, time = 40), \ - null, \ - new/datum/stack_recipe("silk string", /obj/item/weaponcrafting/silkstring, 1, time = 40), \ - )) - -/obj/item/stack/sheet/silk - name = "silk" - desc = "A long, soft material. Made out of refined cotton, instead of relying on the habits of spiders or silkworms." - singular_name = "silk sheet" - icon_state = "sheet-silk" - item_state = "sheet-cloth" - novariants = TRUE - merge_type = /obj/item/stack/sheet/silk - -/obj/item/stack/sheet/silk/get_main_recipes() - . = ..() - . += GLOB.silk_recipes - /* * Durathread */ @@ -447,6 +425,7 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \ new/datum/stack_recipe("durathread bandana", /obj/item/clothing/mask/bandana/durathread, 1, time = 25), \ + new/datum/stack_recipe("durathread string", /obj/item/weaponcrafting/durathread_string, 1, time = 40) \ )) /obj/item/stack/sheet/durathread diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/_storage.dm similarity index 100% rename from code/game/objects/items/storage/storage.dm rename to code/game/objects/items/storage/_storage.dm diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index a4d9636414..3d5f0dc924 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -24,9 +24,9 @@ /obj/item/storage/backpack/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_combined_w_class = 21 - STR.max_w_class = WEIGHT_CLASS_NORMAL - STR.max_items = 21 + STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT + STR.max_volume = STORAGE_VOLUME_BACKPACK + STR.max_w_class = MAX_WEIGHT_CLASS_BACKPACK /* * Backpack Types @@ -64,9 +64,9 @@ /obj/item/storage/backpack/holding/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.allow_big_nesting = TRUE - STR.max_w_class = WEIGHT_CLASS_BULKY - STR.max_combined_w_class = 35 + STR.max_w_class = MAX_WEIGHT_CLASS_BAG_OF_HOLDING + STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT + STR.max_volume = STORAGE_VOLUME_BAG_OF_HOLDING /obj/item/storage/backpack/holding/suicide_act(mob/living/user) user.visible_message("[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide.") @@ -344,7 +344,7 @@ /obj/item/storage/backpack/duffelbag/ComponentInitialize() . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_combined_w_class = 30 + STR.max_volume = STORAGE_VOLUME_DUFFLEBAG /obj/item/storage/backpack/duffelbag/captain name = "captain's duffel bag" diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm index e177a9f9fd..ef70bd201d 100644 --- a/code/game/objects/items/storage/secure.dm +++ b/code/game/objects/items/storage/secure.dm @@ -105,10 +105,7 @@ if (length(code) > 5) code = "ERROR" add_fingerprint(usr) - for(var/mob/M in viewers(1, loc)) - if ((M.client && M.machine == src)) - attack_self(M) - return + attack_self(usr) return @@ -158,6 +155,7 @@ /obj/item/storage/secure/safe name = "secure safe" icon = 'icons/obj/storage.dmi' + plane = ABOVE_WALL_PLANE icon_state = "safe" icon_opened = "safe0" icon_locking = "safeb" diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 64e0a6b492..7e89ddbd8d 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -16,12 +16,17 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' custom_materials = list(/datum/material/iron = 500) - material_flags = MATERIAL_COLOR var/latches = "single_latch" var/has_latches = TRUE var/can_rubberify = TRUE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too +/obj/item/storage/toolbox/greyscale + icon_state = "toolbox_default" + item_state = "toolbox_default" + can_rubberify = FALSE + material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS + /obj/item/storage/toolbox/Initialize(mapload) if(has_latches) if(prob(10)) @@ -48,7 +53,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) name = "emergency toolbox" icon_state = "red" item_state = "toolbox_red" - material_flags = NONE /obj/item/storage/toolbox/emergency/PopulateContents() new /obj/item/crowbar/red(src) @@ -73,7 +77,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) name = "mechanical toolbox" icon_state = "blue" item_state = "toolbox_blue" - material_flags = NONE /obj/item/storage/toolbox/mechanical/PopulateContents() new /obj/item/screwdriver(src) @@ -102,7 +105,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) name = "electrical toolbox" icon_state = "yellow" item_state = "toolbox_yellow" - material_flags = NONE /obj/item/storage/toolbox/electrical/PopulateContents() var/pickedcolor = pick("red","yellow","green","blue","pink","orange","cyan","white") @@ -124,7 +126,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) desc = "A toolbox painted black with a red stripe. It looks more heavier than normal toolboxes." force = 15 throwforce = 18 - material_flags = NONE /obj/item/storage/toolbox/syndicate/ComponentInitialize() . = ..() @@ -144,7 +145,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) name = "mechanical toolbox" icon_state = "blue" item_state = "toolbox_blue" - material_flags = NONE /obj/item/storage/toolbox/drone/PopulateContents() var/pickedcolor = pick("red","yellow","green","blue","pink","orange","cyan","white") @@ -166,7 +166,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) w_class = WEIGHT_CLASS_HUGE attack_verb = list("robusted", "crushed", "smashed") can_rubberify = FALSE - material_flags = NONE var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab /obj/item/storage/toolbox/brass/ComponentInitialize() @@ -209,7 +208,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) w_class = WEIGHT_CLASS_HUGE //heyo no bohing this! force = 18 //spear damage can_rubberify = FALSE - material_flags = NONE /obj/item/storage/toolbox/plastitanium/afterattack(atom/A, mob/user, proximity) . = ..() @@ -225,7 +223,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) icon_state = "green" item_state = "toolbox_green" w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox! - material_flags = NONE /obj/item/storage/toolbox/artistic/ComponentInitialize() . = ..() @@ -302,7 +299,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) icon_state = "gold" item_state = "toolbox_gold" has_latches = FALSE - material_flags = NONE /obj/item/storage/toolbox/gold_real/PopulateContents() new /obj/item/screwdriver/nuke(src) @@ -328,7 +324,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) force = 0 throwforce = 0 can_rubberify = FALSE - material_flags = NONE /obj/item/storage/toolbox/proc/rubberify() name = "rubber [name]" @@ -364,7 +359,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) throwforce = 15 attack_verb = list("robusted", "bounced") can_rubberify = FALSE //we are already the future. - material_flags = NONE /obj/item/storage/toolbox/rubber/Initialize() icon_state = pick("blue", "red", "yellow", "green") diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 57e9ea9aaa..de5f332f43 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -210,6 +210,7 @@ power = 8 force = 10 precision = 1 + total_mass = 0.2 cooling_power = 5 w_class = WEIGHT_CLASS_HUGE item_flags = ABSTRACT // don't put in storage diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index b5edb27704..881e4d5f1a 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -104,7 +104,7 @@ if (ismob(src.loc)) attack_self(src.loc) else - for(var/mob/M in viewers(1, src)) + for(var/mob/M in fov_viewers(1, src)) if (M.client) src.attack_self(M) return diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index d34daf5c75..aa0aa70e03 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -478,6 +478,20 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 throw_range = 2 attack_verb = list("busted") +/obj/item/statuebust/attack_self(mob/living/user) + add_fingerprint(user) + user.examinate(src) + +/obj/item/statuebust/examine(mob/living/user) + . = ..() + if(.) + return + if (!isliving(user)) + return + user.visible_message("[user] stops to admire [src].", \ + "You take in [src], admiring its fine craftsmanship.") + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) + /obj/item/tailclub name = "tail club" desc = "For the beating to death of lizards with their own tails." diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 8dac972d04..e64b7d8f8d 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -112,7 +112,7 @@ /obj/attack_animal(mob/living/simple_animal/M) if(!M.melee_damage_upper && !M.obj_damage) - M.emote("custom", message = "[M.friendly] [src].") + M.emote("custom", message = "[M.friendly_verb_continuous] [src].") return 0 else var/play_soundeffect = 1 @@ -232,15 +232,16 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e cut_overlay(GLOB.fire_overlay, TRUE) SSfire_burning.processing -= src -/obj/proc/tesla_act(power, tesla_flags, shocked_targets) +/obj/zap_act(power, zap_flags, shocked_targets) + if(QDELETED(src)) + return 0 obj_flags |= BEING_SHOCKED - var/power_bounced = power / 2 - tesla_zap(src, 3, power_bounced, tesla_flags, shocked_targets) addtimer(CALLBACK(src, .proc/reset_shocked), 10) + return power / 2 //The surgeon general warns that being buckled to certain objects receiving powerful shocks is greatly hazardous to your health -//Only tesla coils and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later. -/obj/proc/tesla_buckle_check(var/strength) +//Only tesla coils, vehicles, and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later. +/obj/proc/zap_buckle_check(var/strength) if(has_buckled_mobs()) for(var/m in buckled_mobs) var/mob/living/buckled_mob = m diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 199f0c51e2..0b2fe5ac2a 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -123,7 +123,7 @@ /obj/proc/updateUsrDialog() if((obj_flags & IN_USE) && !(obj_flags & USES_TGUI)) var/is_in_use = FALSE - var/list/nearby = viewers(1, src) + var/list/nearby = fov_viewers(1, src) for(var/mob/M in nearby) if ((M.client && M.machine == src)) is_in_use = TRUE @@ -152,7 +152,7 @@ if(obj_flags & IN_USE) var/is_in_use = FALSE if(update_viewers) - for(var/mob/M in viewers(1, src)) + for(var/mob/M in fov_viewers(1, src)) if ((M.client && M.machine == src)) is_in_use = TRUE src.interact(M) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 1b627a19bf..98f772a116 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -80,7 +80,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "Canvas", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "canvas", name, ui_x, ui_y, master_ui, state) ui.set_autoupdate(FALSE) ui.open() @@ -240,6 +240,7 @@ /obj/structure/sign/painting/Initialize(mapload, dir, building) . = ..() SSpersistence.painting_frames += src + AddComponent(/datum/component/art, 20) if(dir) setDir(dir) if(building) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index d3e8ecf0a6..2225c4c0c2 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -108,7 +108,9 @@ if(!istype(poordude)) return TRUE user.visible_message("[user] pulls [src] out from under [poordude].", "You pull [src] out from under [poordude].") - var/C = new item_chair(loc) + var/obj/item/chair/C = new item_chair(loc) + C.set_custom_materials(custom_materials) + TransferComponents(C) user.put_in_hands(C) poordude.DefaultCombatKnockdown(20)//rip in peace user.adjustStaminaLoss(5) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index ae2e1a070a..500b8d6a49 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -24,6 +24,7 @@ move_delay = TRUE var/oldloc = loc step(src, direction) + user.setDir(direction) if(oldloc != loc) addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier) else @@ -42,7 +43,7 @@ Snake = L break if(Snake) - alerted = viewers(7,src) + alerted = fov_viewers(world.view,src) ..() if(LAZYLEN(alerted)) egged = world.time + SNAKE_SPAM_TICKS diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 9b736517be..3bc84deb4d 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -3,6 +3,7 @@ desc = "A small wall mounted cabinet designed to hold a fire extinguisher." icon = 'icons/obj/wallmounts.dmi' icon_state = "extinguisher_closed" + plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE max_integrity = 200 diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index e44698f96e..679a755321 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -7,6 +7,7 @@ anchored = TRUE icon = 'icons/turf/walls/wall.dmi' icon_state = "wall" + plane = WALL_PLANE layer = LOW_OBJ_LAYER density = TRUE opacity = 1 diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 0f3a23dd0f..f4c1dd5ab9 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -3,6 +3,7 @@ desc = "There is a small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if." icon = 'icons/obj/wallmounts.dmi' icon_state = "fireaxe" + plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 54e08db210..20151a0bdb 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -267,7 +267,7 @@ var/obj/structure/cable/C = T.get_cable_node() if(C) playsound(src, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 3, C.newavail() * 0.01, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot. + tesla_zap(src, 3, C.newavail() * 0.01, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN | ZAP_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot. C.add_delayedload(C.newavail() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock. return ..() diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 611a6d024d..0a5ba6a68c 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -130,7 +130,7 @@ // The crowd is pleased // The delay is to making large crowds have a longer laster applause var/delay_offset = 0 - for(var/mob/M in viewers(src, 7)) + for(var/mob/M in fov_viewers(world.view, src)) var/mob/living/carbon/human/C = M if (ishuman(M)) addtimer(CALLBACK(C, /mob/.proc/emote, "clap"), delay_offset * 0.3) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index e32def727a..65e1b7dd9a 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -4,6 +4,7 @@ desc = "Mirror mirror on the wall, who's the most robust of them all?" icon = 'icons/obj/watercloset.dmi' icon_state = "mirror" + plane = ABOVE_WALL_PLANE density = FALSE anchored = TRUE max_integrity = 200 diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index f4bca1f900..68da53aa6c 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -3,6 +3,7 @@ desc = "A board for pinning important notices upon." icon = 'icons/obj/stationobjs.dmi' icon_state = "nboard00" + plane = ABOVE_WALL_PLANE density = FALSE anchored = TRUE max_integrity = 150 diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index 84add2f65f..a1de5fe6a3 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -3,6 +3,7 @@ anchored = TRUE opacity = 0 density = FALSE + plane = ABOVE_WALL_PLANE layer = SIGN_LAYER max_integrity = 100 armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 9a6b24b472..1f9491f4cf 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -8,12 +8,11 @@ max_integrity = 100 var/oreAmount = 5 var/material_drop_type = /obj/item/stack/sheet/metal + var/impressiveness = 15 CanAtmosPass = ATMOS_PASS_DENSITY - /obj/structure/statue/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) - user.changeNext_move(CLICK_CD_MELEE) if(!(flags_1 & NODECONSTRUCT_1)) if(default_unfasten_wrench(user, W)) return @@ -36,8 +35,22 @@ return user.changeNext_move(CLICK_CD_MELEE) add_fingerprint(user) - user.visible_message("[user] rubs some dust off from the [name]'s surface.", \ - "You rub some dust off from the [name]'s surface.") + if(!do_after(user, 20, target = src)) + return + user.visible_message("[user] rubs some dust off [src].", \ + "You take in [src], rubbing some dust off its surface.") + if(!ishuman(user)) // only humans have the capacity to appreciate art + return + var/totalimpressiveness = (impressiveness *(obj_integrity/max_integrity)) + switch(totalimpressiveness) + if(GREAT_ART to 100) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) + if (GOOD_ART to GREAT_ART) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) + if (BAD_ART to GOOD_ART) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) + if (0 to BAD_ART) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) /obj/structure/statue/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) @@ -58,6 +71,7 @@ material_drop_type = /obj/item/stack/sheet/mineral/uranium var/last_event = 0 var/active = null + impressiveness = 25 // radiation makes an impression /obj/structure/statue/uranium/nuke name = "statue of a nuclear fission explosive" @@ -101,6 +115,7 @@ max_integrity = 200 material_drop_type = /obj/item/stack/sheet/mineral/plasma desc = "This statue is suitably made from plasma." + impressiveness = 20 /obj/structure/statue/plasma/scientist name = "statue of a scientist" @@ -151,6 +166,7 @@ max_integrity = 300 material_drop_type = /obj/item/stack/sheet/mineral/gold desc = "This is a highly valuable statue made from gold." + impressiveness = 30 /obj/structure/statue/gold/hos name = "statue of the head of security" @@ -178,6 +194,7 @@ max_integrity = 300 material_drop_type = /obj/item/stack/sheet/mineral/silver desc = "This is a valuable statue made from silver." + impressiveness = 25 /obj/structure/statue/silver/md name = "statue of a medical officer" @@ -205,6 +222,7 @@ max_integrity = 1000 material_drop_type = /obj/item/stack/sheet/mineral/diamond desc = "This is a very expensive diamond statue." + impressiveness = 60 /obj/structure/statue/diamond/captain name = "statue of THE captain." @@ -225,6 +243,7 @@ material_drop_type = /obj/item/stack/sheet/mineral/bananium desc = "A bananium statue with a small engraving:'HOOOOOOONK'." var/spam_flag = 0 + impressiveness = 65 /obj/structure/statue/bananium/clown name = "statue of a clown" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 30e451aa14..3d552fa236 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -183,7 +183,7 @@ /obj/structure/table/alt_attack_hand(mob/user) if(user && Adjacent(user) && !user.incapacitated()) - user.setClickCooldown(4) + user.changeNext_move(CLICK_CD_MELEE*0.5) if(istype(user) && user.a_intent == INTENT_HARM) user.visible_message("[user] slams [user.p_their()] palms down on [src].", "You slam your palms down on [src].") playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index e4d93ea8de..ba7c0d2fbe 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -1,7 +1,3 @@ -#define NOT_ELECTROCHROMATIC 0 -#define ELECTROCHROMATIC_OFF 1 -#define ELECTROCHROMATIC_DIMMED 2 - GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) /proc/do_electrochromatic_toggle(new_status, id) @@ -74,9 +70,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) if(reinf && anchored) state = WINDOW_SCREWED_TO_FRAME - if(mapload && electrochromatic_id) - if(copytext(electrochromatic_id, 1, 2) == "!") - electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id) + if(mapload && electrochromatic_id && electrochromatic_id[1] == "!") + electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id) ini_dir = dir air_update_turf(1) @@ -885,7 +880,3 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) return ..() update_icon() - -#undef NOT_ELECTROCHROMATIC -#undef ELECTROCHROMATIC_OFF -#undef ELECTROCHROMATIC_DIMMED diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 99c7ed8231..c7aefbe0a6 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -1,5 +1,6 @@ /turf/closed layer = CLOSED_TURF_LAYER + plane = WALL_PLANE opacity = 1 density = TRUE blocks_air = 1 diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 268e8e9109..5243341ac1 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -290,7 +290,7 @@ if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS) return - var/mutable_appearance/decal = mutable_appearance('icons/effects/effects.dmi', "", BULLET_HOLE_LAYER) + var/mutable_appearance/decal = mutable_appearance('icons/effects/effects.dmi', "", BULLET_HOLE_LAYER, ABOVE_WALL_PLANE) switch(denttype) if(WALL_DENT_SHOT) decal.icon_state = "bullet_hole" diff --git a/code/game/world.dm b/code/game/world.dm index 4ffa3292ee..904954e49e 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,6 +1,7 @@ #define RESTART_COUNTER_PATH "data/round_counter.txt" GLOBAL_VAR(restart_counter) +GLOBAL_VAR_INIT(tgs_initialized, FALSE) GLOBAL_VAR(topic_status_lastcache) GLOBAL_LIST(topic_status_cache) @@ -23,10 +24,11 @@ GLOBAL_LIST(topic_status_cache) make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - TgsNew(minimum_required_security_level = TGS_SECURITY_TRUSTED) GLOB.revdata = new + InitTgs() + config.Load(params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER]) //SetupLogs depends on the RoundID, so lets check @@ -62,6 +64,15 @@ GLOBAL_LIST(topic_status_cache) if(TEST_RUN_PARAMETER in params) HandleTestRun() +/world/proc/InitTgs() + TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED) + GLOB.revdata.load_tgs_info() +#ifdef USE_CUSTOM_ERROR_HANDLER + if (TgsAvailable()) + world.log = file("[GLOB.log_directory]/dd.log") //not all runtimes trigger world/Error, so this is the only way to ensure we can see all of them. +#endif + GLOB.tgs_initialized = TRUE + /world/proc/HandleTestRun() //trigger things to run the whole process Master.sleep_offline_after_initializations = FALSE @@ -224,16 +235,17 @@ GLOBAL_LIST(topic_status_cache) qdel(src) //shut it down /world/Reboot(reason = 0, fast_track = FALSE) - TgsReboot() if (reason || fast_track) //special reboot, do none of the normal stuff if (usr) log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools") message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools") - to_chat(world, "Rebooting World immediately due to host request") + to_chat(world, "Rebooting World immediately due to host request.") else to_chat(world, "Rebooting world...") Master.Shutdown() //run SS shutdowns + TgsReboot() + if(TEST_RUN_PARAMETER in params) FinishTestRun() return diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index e79784290b..26ae200990 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -22,6 +22,11 @@ sparks.set_up(2,0) sparks.attach(src) update_icon() + new_occupant_dir = dir + +/obj/machinery/vr_sleeper/setDir(newdir) + . = ..() + new_occupant_dir = dir /obj/machinery/vr_sleeper/attackby(obj/item/I, mob/user, params) if(!state_open && !occupant) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 55c55c42de..99bb988be6 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -4,7 +4,7 @@ var/F = file("[GLOB.log_directory]/[subject].html") WRITE_FILE(F, "[TIME_STAMP("hh:mm:ss", FALSE)] [REF(src)] ([x],[y],[z]) || [src] [message]
") -/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) ) +/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES, INVESTIGATE_CRYOGENICS) ) set name = "Investigate" set category = "Admin" if(!holder) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 15c45c9b3e..718f9d4246 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -106,6 +106,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /client/proc/show_tip, /client/proc/smite, /client/proc/admin_away, + /client/proc/cmd_admin_toggle_fov, /client/proc/roll_dices //CIT CHANGE - Adds dice verb )) GLOBAL_PROTECT(admin_verbs_fun) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index a06b674e42..41662c1cad 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -69,11 +69,6 @@ The floor is lava! (DANGEROUS: extremely lame)
Spawn a custom portal storm

- Flip client movement directions
- Randomize client movement directions
- Set each movement direction manually
- Reset movement directions to default
-
Change bomb cap
Mass Purrbation
Mass Remove Purrbation
@@ -603,60 +598,6 @@ purrbation.") log_admin("[key_name(usr)] has removed everyone from purrbation.") - if("flipmovement") - if(!check_rights(R_FUN)) - return - if(alert("Flip all movement controls?","Confirm","Yes","Cancel") == "Cancel") - return - var/list/movement_keys = SSinput.movement_keys - for(var/i in 1 to movement_keys.len) - var/key = movement_keys[i] - movement_keys[key] = turn(movement_keys[key], 180) - message_admins("[key_name_admin(usr)] has flipped all movement directions.") - log_admin("[key_name(usr)] has flipped all movement directions.") - - if("randommovement") - if(!check_rights(R_FUN)) - return - if(alert("Randomize all movement controls?","Confirm","Yes","Cancel") == "Cancel") - return - var/list/movement_keys = SSinput.movement_keys - for(var/i in 1 to movement_keys.len) - var/key = movement_keys[i] - movement_keys[key] = turn(movement_keys[key], 45 * rand(1, 8)) - message_admins("[key_name_admin(usr)] has randomized all movement directions.") - log_admin("[key_name(usr)] has randomized all movement directions.") - - if("custommovement") - if(!check_rights(R_FUN)) - return - if(alert("Are you sure you want to change every movement key?","Confirm","Yes","Cancel") == "Cancel") - return - var/list/movement_keys = SSinput.movement_keys - var/list/new_movement = list() - for(var/i in 1 to movement_keys.len) - var/key = movement_keys[i] - - var/msg = "Please input the new movement direction when the user presses [key]. Ex. northeast" - var/title = "New direction for [key]" - var/new_direction = text2dir(input(usr, msg, title) as text|null) - if(!new_direction) - new_direction = movement_keys[key] - - new_movement[key] = new_direction - SSinput.movement_keys = new_movement - message_admins("[key_name_admin(usr)] has configured all movement directions.") - log_admin("[key_name(usr)] has configured all movement directions.") - - if("resetmovement") - if(!check_rights(R_FUN)) - return - if(alert("Are you sure you want to reset movement keys to default?","Confirm","Yes","Cancel") == "Cancel") - return - SSinput.setup_default_movement_keys() - message_admins("[key_name_admin(usr)] has reset all movement keys.") - log_admin("[key_name(usr)] has reset all movement keys.") - if("customportal") if(!check_rights(R_FUN)) return diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 26736ddff1..df54df5c7d 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -1025,8 +1025,6 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null v = SSnpcpool if("SSmobs") v = SSmobs - if("SSmood") - v = SSmood if("SSquirks") v = SSquirks if("SSwet_floors") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 9d27658074..93c1b9386b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1211,6 +1211,58 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/cmd_admin_toggle_fov() + set category = "Fun" + set name = "Enable/Disable Field of Vision" + + var/static/busy_toggling_fov = FALSE + if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) + return + + var/on_off = CONFIG_GET(flag/use_field_of_vision) + + if(busy_toggling_fov) + to_chat(usr, "A previous call of this function is still busy toggling FoV [on_off ? "on" : "off"]. Have some patiece.") + return + busy_toggling_fov = TRUE + + log_admin("[key_name(usr)] has [on_off ? "disabled" : "enabled"] the Field of Vision configuration.") + CONFIG_SET(flag/use_field_of_vision, !on_off) + + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Field of Vision", "[on_off ? "Enabled" : "Disabled"]")) + + if(on_off) + for(var/k in GLOB.mob_list) + if(!k) + continue + var/mob/M = k + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!(H.dna?.species.has_field_of_vision)) + continue + else if(!M.has_field_of_vision) + continue + var/datum/component/field_of_vision/FoV = M.GetComponent(/datum/component/field_of_vision) + if(FoV) + qdel(FoV) + CHECK_TICK + else + for(var/k in GLOB.clients) + if(!k) + continue + var/client/C = k + var/mob/M = C.mob + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!(H.dna?.species.has_field_of_vision)) + continue + else if(!M.has_field_of_vision) + continue + M.LoadComponent(/datum/component/field_of_vision, M.field_of_vision_type) + CHECK_TICK + + busy_toggling_fov = FALSE + /client/proc/smite(mob/living/carbon/human/target as mob) set name = "Smite" set category = "Fun" diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 4a7abda53c..3184a169fc 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -24,6 +24,8 @@ GLOBAL_LIST_EMPTY(antagonists) var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) // Quirks that will be removed upon gaining this antag. Pacifist and mute are default. var/threat = 0 // Amount of threat this antag poses, for dynamic mode + var/list/skill_modifiers + /datum/antagonist/New() GLOB.antagonists += src typecache_datum_blacklist = typecacheof(typecache_datum_blacklist) @@ -68,15 +70,19 @@ GLOBAL_LIST_EMPTY(antagonists) //Proc called when the datum is given to a mind. /datum/antagonist/proc/on_gain() - if(owner && owner.current) - if(!silent) - greet() - apply_innate_effects() - give_antag_moodies() - remove_blacklisted_quirks() - if(is_banned(owner.current) && replace_banned) - replace_banned_player() - SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src) + if(!(owner?.current)) + return + if(!silent) + greet() + apply_innate_effects() + give_antag_moodies() + remove_blacklisted_quirks() + if(is_banned(owner.current) && replace_banned) + replace_banned_player() + if(skill_modifiers) + for(var/A in skill_modifiers) + ADD_SINGLETON_SKILL_MODIFIER(owner, A, type) + SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src) /datum/antagonist/proc/is_banned(mob/M) if(!M) @@ -99,6 +105,8 @@ GLOBAL_LIST_EMPTY(antagonists) clear_antag_moodies() if(owner) LAZYREMOVE(owner.antag_datums, src) + for(var/A in skill_modifiers) + owner.remove_skill_modifier(GET_SKILL_MOD_ID(A, type)) if(!silent && owner.current) farewell() var/datum/team/team = get_team() diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 44116dbe36..9132288415 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -21,6 +21,7 @@ landmark_type = /obj/effect/landmark/abductor/agent greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve." show_in_antagpanel = TRUE + skill_modifiers = list(/datum/skill_modifier/job/level/wiring) /datum/antagonist/abductor/scientist name = "Abductor Scientist" @@ -29,6 +30,7 @@ landmark_type = /obj/effect/landmark/abductor/scientist greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans." show_in_antagpanel = TRUE + skill_modifiers = list(/datum/skill_modifier/job/affinity/surgery) /datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team) if(!new_team) diff --git a/code/modules/antagonists/abductor/equipment/glands/electric.dm b/code/modules/antagonists/abductor/equipment/glands/electric.dm index 82ee77d192..7e52f6fcb6 100644 --- a/code/modules/antagonists/abductor/equipment/glands/electric.dm +++ b/code/modules/antagonists/abductor/equipment/glands/electric.dm @@ -23,5 +23,5 @@ addtimer(CALLBACK(src, .proc/zap), rand(30, 100)) /obj/item/organ/heart/gland/electric/proc/zap() - tesla_zap(owner, 4, 8000, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN) + tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN) playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE) \ No newline at end of file diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm index fbdeea6b84..91fb538ca3 100644 --- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm @@ -86,7 +86,8 @@ melee_damage_upper = 4 obj_damage = 20 environment_smash = ENVIRONMENT_SMASH_STRUCTURES - attacktext = "hits" + attack_verb_continuous = "hits" + attack_verb_simple = "hit" attack_sound = 'sound/weapons/genhit1.ogg' movement_type = FLYING del_on_death = 1 @@ -205,7 +206,8 @@ melee_damage_lower = 20 melee_damage_upper = 20 obj_damage = 60 - attacktext = "slams" + attack_verb_continuous = "slams" + attack_verb_simple = "slam" attack_sound = 'sound/effects/blobattack.ogg' verb_say = "gurgles" verb_ask = "demands" @@ -284,11 +286,11 @@ if(overmind) //if we have an overmind, we're doing chemical reactions instead of pure damage melee_damage_lower = 4 melee_damage_upper = 4 - attacktext = overmind.blobstrain.blobbernaut_message + attack_verb_continuous = overmind.blobstrain.blobbernaut_message else melee_damage_lower = initial(melee_damage_lower) melee_damage_upper = initial(melee_damage_upper) - attacktext = initial(attacktext) + attack_verb_continuous = initial(attack_verb_continuous) /mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed) ..(gibbed) diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm index 5717dc557d..6a73dc579b 100644 --- a/code/modules/antagonists/blob/blob/theblob.dm +++ b/code/modules/antagonists/blob/blob/theblob.dm @@ -207,8 +207,8 @@ if(prob(100 - severity * 30)) new /obj/effect/temp_visual/emp(get_turf(src)) -/obj/structure/blob/tesla_act(power) - ..() +/obj/structure/blob/zap_act(power) + . = ..() if(overmind) if(overmind.blobstrain.tesla_reaction(src, power)) take_damage(power/400, BURN, "energy") diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm b/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm index 98fb69e52c..330116a207 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm @@ -113,3 +113,5 @@ /mob/living/proc/StartFrenzy(inTime = 120) set waitfor = FALSE + + diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm index 8425309b6c..4e4b270c12 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm @@ -216,8 +216,8 @@ // for (var/datum/action/bloodsucker/masquerade/P in powers) // P.Deactivate() // TEMP DEATH - var/total_brute = owner.current.getBruteLoss() - var/total_burn = owner.current.getFireLoss() + var/total_brute = owner.current.getBruteLoss_nonProsthetic() + var/total_burn = owner.current.getFireLoss_nonProsthetic() var/total_toxloss = owner.current.getToxLoss() //This is neater than just putting it in total_damage var/total_damage = total_brute + total_burn + total_toxloss // Died? Convert to Torpor (fake death) diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm index 7998a33c7b..090ef45d89 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm @@ -328,8 +328,8 @@ // to_chat(user, "The ritual has been interrupted!") // useLock = FALSE // return - user.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE) - target.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE) + user.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE) + target.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE) target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) target.Jitter(25) target.emote("laugh") @@ -490,13 +490,14 @@ update_icon() /obj/structure/bloodsucker/candelabrum/process() - if(lit) - for(var/mob/living/carbon/human/H in viewers(7, src)) - var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL) - if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this - return - H.hallucination = 20 - SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle) + if(!lit) + return + for(var/mob/living/carbon/human/H in fov_viewers(7, src)) + var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL) + if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this + return + H.hallucination = 20 + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // OTHER THINGS TO USE: HUMAN BLOOD. /obj/effect/decal/cleanable/blood diff --git a/code/modules/antagonists/bloodsucker/powers/cloak.dm b/code/modules/antagonists/bloodsucker/powers/cloak.dm index 347700ca9a..5383e8c1ac 100644 --- a/code/modules/antagonists/bloodsucker/powers/cloak.dm +++ b/code/modules/antagonists/bloodsucker/powers/cloak.dm @@ -19,10 +19,9 @@ if(!.) return // must have nobody around to see the cloak - for(var/mob/living/M in viewers(9, owner)) - if(M != owner) - to_chat(owner, "You may only vanish into the shadows unseen.") - return FALSE + for(var/mob/living/M in fov_viewers(9, owner) - owner) + to_chat(owner, "You may only vanish into the shadows unseen.") + return FALSE return TRUE /datum/action/bloodsucker/cloak/ActivatePower() @@ -35,7 +34,7 @@ // Pay Blood Toll (if awake) owner.alpha = max(35, owner.alpha - min(75, 10 + 5 * level_current)) bloodsuckerdatum.AddBloodVolume(-0.2) - + runintent = (user.m_intent == MOVE_INTENT_RUN) var/turf/T = get_turf(user) lum = T.get_lumcount() @@ -50,7 +49,7 @@ if(!runintent) user.toggle_move_intent() REMOVE_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness") - + sleep(5) // Check every few ticks /datum/action/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target) diff --git a/code/modules/antagonists/bloodsucker/powers/feed.dm b/code/modules/antagonists/bloodsucker/powers/feed.dm index 8ac4fcebc1..cbb9693fba 100644 --- a/code/modules/antagonists/bloodsucker/powers/feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/feed.dm @@ -169,8 +169,8 @@ vision_distance = notice_range, ignored_mobs = target) // Only people who AREN'T the target will notice this action. // Warn Feeder about Witnesses... var/was_unnoticed = TRUE - for(var/mob/living/M in viewers(notice_range, owner)) - if(M != owner && M != target && iscarbon(M) && M.mind && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) + for(var/mob/living/M in fov_viewers(notice_range, owner) - owner - target) + if(M.client && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) was_unnoticed = FALSE break if(was_unnoticed) diff --git a/code/modules/antagonists/bloodsucker/powers/go_home.dm b/code/modules/antagonists/bloodsucker/powers/go_home.dm index 4788d7639e..c46a7fce6c 100644 --- a/code/modules/antagonists/bloodsucker/powers/go_home.dm +++ b/code/modules/antagonists/bloodsucker/powers/go_home.dm @@ -64,8 +64,8 @@ var/turf/T = get_turf(user) if(T && T.lighting_object && T.get_lumcount()>= 0.1) // B) Check for Viewers - for(var/mob/living/M in viewers(get_turf(owner))) - if(M != owner && isliving(M) && M.mind && !M.silicon_privileges && !M.eye_blind) // M.client <--- add this in after testing! + for(var/mob/living/M in fov_viewers(world.view, get_turf(owner)) - owner) + if(M.client && !M.silicon_privileges && !M.eye_blind) am_seen = TRUE if (!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) drop_item = TRUE diff --git a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm index 814ad2abd7..0a7e87029a 100644 --- a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm +++ b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm @@ -64,7 +64,7 @@ to_chat(owner, "Your victim's eyes are glazed over. They cannot perceive you.") return FALSE // Check: Target See Me? (behind wall) - if(!(target in viewers(target_range, get_turf(owner)))) + if(!(owner in target.fov_view())) // Sub-Check: GET CLOSER //if (!(owner in range(target_range, get_turf(target))) // if (display_error) @@ -137,7 +137,7 @@ if(istype(target) && success) target.notransform = FALSE REMOVE_TRAIT(target, TRAIT_COMBAT_MODE_LOCKED, src) - if(istype(L) && target.stat == CONSCIOUS && (target in view(10, get_turf(L)))) // They Woke Up! (Notice if within view) + if(istype(L) && target.stat == CONSCIOUS && (target in L.fov_view(10))) // They Woke Up! (Notice if within view) to_chat(L, "[target] has snapped out of their trance.") diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 431416ede0..036ea37ada 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -5,6 +5,7 @@ clockwork_desc = "A sigil of some purpose." icon_state = "sigil" layer = LOW_OBJ_LAYER + plane = ABOVE_WALL_PLANE alpha = 50 resistance_flags = NONE var/affects_servants = FALSE diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm new file mode 100644 index 0000000000..a681e9b38b --- /dev/null +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm @@ -0,0 +1,82 @@ +//Subtype of (riot) shield because of already implemented shieldbash stuff aswell as integrity and simillar things +//ratvarian shield: A shield that absorbs energy from attacks and uses it to empower its bashes with remendous force. It is also quite resistant to damage, though less so against lasers and energy weaponry. + +/obj/item/shield/riot/ratvarian + name = "ratvarian shield" + icon_state = "ratvarian_shield" //Its icons are in the same place the normal shields are in + item_state = "ratvarian_shield" + desc = "A resilient shield made out of brass.. It feels warm to the touch." + var/clockwork_desc = "A powerful shield of ratvarian making. It absorbs blocked attacks to charge devastating bashes." + armor = list("melee" = 80, "bullet" = 70, "laser" = -10, "energy" = -20, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + shield_flags = SHIELD_FLAGS_DEFAULT + max_integrity = 300 //High integrity, extremely strong against melee / bullets, but still quite easy to destroy with lasers and energy + repair_material = /obj/item/stack/tile/brass + var/dam_absorbed = 0 + var/bash_mult_steps = 30 + var/max_bash_mult = 4 + +/obj/item/shield/riot/ratvarian/examine(mob/user) + if((is_servant_of_ratvar(user) || isobserver(user))) + desc = clockwork_desc + desc +="\n The shield has absorbed [dam_absorbed] damage, multiplying the effectiveness of its bashes by [calc_bash_mult()]" + . = ..() + desc = initial(desc) + +obj/item/shield/riot/ratvarian/proc/calc_bash_mult() + var/bash_mult = 0 + if(!dam_absorbed) + return 1 + else + bash_mult += round(clamp(1 + (dam_absorbed / bash_mult_steps), 1, max_bash_mult), 0.1) //Multiplies the effect of bashes by up to [max_bash_mult], though never less than one + return bash_mult + +/obj/item/shield/riot/ratvarian/proc/calc_bash_absorb_use() + var/absorb_use = 0 + absorb_use = max(0, round(dam_absorbed * (calc_bash_mult() / round(1 + (dam_absorbed / bash_mult_steps), 0.1)), 1)) //Calculates how much of the absorbed damage the bash would actually use, so its not wasted + return absorb_use + +/obj/item/shield/riot/ratvarian/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) + if(!damage) + return ..() + + if(!is_servant_of_ratvar(owner)) + owner.visible_message("As [owner] blocks the attack with [src], [owner.p_they()] suddenly drops it, whincing in pain! ", "As you block the attack with [src], it heats up tremendously, forcing you to drop it from the pain alone! ") + owner.emote("scream") + playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50) + if(iscarbon(owner)) //Type safety for if a drone somehow got a shield (ratvar protect us) + var/mob/living/carbon/C = owner + var/obj/item/bodypart/part = C.get_holding_bodypart_of_item(src) + C.apply_damage((iscultist(C) ? damage * 2 : damage), BURN, (istype(part, /obj/item/bodypart/l_arm) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM)) //Deals the damage to the holder instead of absorbing it instead + forcedrops. Doubled if a cultist of Nar'Sie. + else + owner.adjustFireLoss(iscultist(owner) ? damage * 2 : damage) + addtimer(CALLBACK(owner, /mob/living.proc/dropItemToGround, src, TRUE), 1) + else if(!is_servant_of_ratvar(attacker)) //No exploiting my snowflake mechanics + dam_absorbed += damage + playsound(owner, 'sound/machines/clockcult/steam_whoosh.ogg', 30) + + if(damage <= 10) //The shield itself is hard to break, this DOES NOT modify the actual blocking-mechanic + damage = 0 + else + damage -= 5 + return ..() + +/obj/item/shield/riot/ratvarian/shatter(mob/living/carbon/human/owner) + playsound(owner, 'sound/magic/clockwork/anima_fragment_death.ogg', 50) + new /obj/item/clockwork/alloy_shards/large(get_turf(src)) + +/obj/item/shield/riot/ratvarian/user_shieldbash(mob/living/user, atom/target, harmful) + if(!harmful || !is_servant_of_ratvar(user)) // No fun for non-clockies, but you can keep the normal bashes. Until you try to block with it. + shieldbash_knockback = initial(shieldbash_knockback) + shieldbash_brutedamage = initial(shieldbash_brutedamage) //Prevention for funky stuff that might happen otherwise + shieldbash_stamdmg = initial(shieldbash_stamdmg) + return ..() + var/actual_bash_mult = calc_bash_mult() + shieldbash_knockback = round(initial(shieldbash_knockback) * actual_bash_mult, 1) //Modifying the strength of the bash, done with initial() to prevent magic-number issues if the original shieldbash values are changed + shieldbash_brutedamage = round(initial(shieldbash_brutedamage) * actual_bash_mult, 1) //Where I think of it, better round this stuff because we don't need even more things that deal like 3.25 damage + shieldbash_stamdmg = round(initial(shieldbash_stamdmg) * actual_bash_mult, 1) //Like 20 brute and 60 stam + a fuckton of knockback at the moment (at maximum charge), seems mostly fine? I think? + . = ..() + if(.) //If this bash actually hit someone + if(actual_bash_mult > 1) + playsound(user, 'sound/magic/fireball.ogg', 50, TRUE, frequency = 1.25) + dam_absorbed -= calc_bash_absorb_use() + return diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index f43f2814d8..dd37f3727c 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -17,7 +17,8 @@ obj_damage = 40 melee_damage_lower = 12 melee_damage_upper = 12 - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' weather_immunities = list("lava") movement_type = FLYING @@ -68,14 +69,16 @@ maxHealth = 300 melee_damage_upper = 25 melee_damage_lower = 25 - attacktext = "devastates" + attack_verb_continuous = "devastates" + attack_verb_simple = "devastate" speed = -1 obj_damage = 100 max_shield_health = INFINITY else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase melee_damage_upper = 15 melee_damage_lower = 15 - attacktext = "carves" + attack_verb_continuous = "carves" + attack_verb_simple = "carve" obj_damage = 50 max_shield_health = 4 diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm index 130fc24583..c40168a986 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm @@ -100,6 +100,24 @@ quickbind = TRUE quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning." +//Nezbere's shield: Creates a ratvarian shield which absorbs attacks, see ratvarian_shield.dm for details. +/datum/clockwork_scripture/create_object/nezberes_shield + descname = "Shield with empowerable bashes" + name = "Nezbere's shield" + desc = "Creates a shield which generates charge from blocking damage, using it to empower its bashes tremendously. It is repaired with brass, and while very durable, extremely weak to lasers and, even more so, to energy weaponry." + invocations = list("Shield me...", "... from the coming dark!") + channel_time = 20 + power_cost = 600 //Shouldn't be too spammable but not too hard to get either + whispered = TRUE + creator_message = "You form a ratvarian shield, which is capable of absorbing blocked attacks to empower its bashes." + object_path = /obj/item/shield/riot/ratvarian + usage_tip = "Bashes will only use charge when performed with intent to harm." + tier = SCRIPTURE_SCRIPT + space_allowed = TRUE + primary_component = VANGUARD_COGWHEEL + sort_priority = 5 + quickbind = TRUE + quickbind_desc = "Creates a Ratvarian shield, which can absorb energy from attacks for use in powerful bashes." //Clockwork Armaments: Grants the invoker the ability to call forth a Ratvarian spear and clockwork armor. /datum/clockwork_scripture/clockwork_armaments @@ -113,7 +131,7 @@ usage_tip = "Throwing the spear at a mob will do massive damage and knock them down, but break the spear. You will need to wait for 30 seconds before resummoning it." tier = SCRIPTURE_SCRIPT primary_component = VANGUARD_COGWHEEL - sort_priority = 5 + sort_priority = 6 important = TRUE quickbind = TRUE quickbind_desc = "Permanently binds clockwork armor and a Ratvarian spear to you." @@ -213,7 +231,7 @@ usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." tier = SCRIPTURE_SCRIPT primary_component = GEIS_CAPACITOR - sort_priority = 6 + sort_priority = 7 quickbind = TRUE quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk." diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index a730b52cc1..b6ed7dfe65 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -5,6 +5,7 @@ antagpanel_category = "Clockcult" job_rank = ROLE_SERVANT_OF_RATVAR antag_moodlet = /datum/mood_event/cult + skill_modifiers = list(/datum/skill_modifier/job/level/wiring) var/datum/action/innate/hierophant/hierophant_network = new threat = 3 var/datum/team/clockcult/clock_team diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index 1539bc384b..7a6850bfa1 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -7,9 +7,12 @@ desc = "A large, menacing creature covered in armored black scales." speak_emote = list("cackles") emote_hear = list("cackles","screeches") - response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" + response_help_continuous = "thinks better of touching" + response_help_simple = "think better of touching" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" icon = 'icons/mob/mob.dmi' icon_state = "imp" icon_living = "imp" @@ -23,7 +26,8 @@ minbodytemp = 250 //Weak to cold maxbodytemp = INFINITY faction = list("hell") - attacktext = "wildly tears into" + attack_verb_continuous = "wildly tears into" + attack_verb_simple = "wildly tear into" maxHealth = 200 health = 200 healable = 0 diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm index bda1fbabe6..1d773627c7 100644 --- a/code/modules/antagonists/ert/ert.dm +++ b/code/modules/antagonists/ert/ert.dm @@ -51,6 +51,7 @@ /datum/antagonist/ert/engineer role = "Engineer" outfit = /datum/outfit/ert/engineer + skill_modifiers = list(/datum/skill_modifier/job/level/wiring) /datum/antagonist/ert/engineer/amber outfit = /datum/outfit/ert/engineer/alert @@ -61,6 +62,7 @@ /datum/antagonist/ert/medic role = "Medical Officer" outfit = /datum/outfit/ert/medic + skill_modifiers = list(/datum/skill_modifier/job/affinity/surgery) /datum/antagonist/ert/medic/amber outfit = /datum/outfit/ert/medic/alert diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm index ad2eb4792a..e91feda006 100644 --- a/code/modules/antagonists/morph/morph.dm +++ b/code/modules/antagonists/morph/morph.dm @@ -28,7 +28,8 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE vision_range = 1 // Only attack when target is close wander = FALSE - attacktext = "glomps" + attack_verb_continuous = "glomps" + attack_verb_simple = "glomp" attack_sound = 'sound/effects/blobattack.ogg' butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 49b475e98b..5c011b6318 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -453,9 +453,9 @@ return qdel(src) -/obj/machinery/nuclearbomb/tesla_act(power, tesla_flags) +/obj/machinery/nuclearbomb/zap_act(power, zap_flags) ..() - if(tesla_flags & TESLA_MACHINE_EXPLOSIVE) + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over #define NUKERANGE 127 @@ -608,6 +608,7 @@ This is here to make the tiles around the station mininuke change when it's arme lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' icon_state = "datadisk0" + w_volume = ITEM_VOLUME_DISK /obj/item/disk/nuclear name = "nuclear authentication disk" diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm index 7510ad6997..454cde6d72 100644 --- a/code/modules/antagonists/nukeop/nukeop.dm +++ b/code/modules/antagonists/nukeop/nukeop.dm @@ -5,6 +5,7 @@ job_rank = ROLE_OPERATIVE antag_moodlet = /datum/mood_event/focused threat = 10 + skill_modifiers = list(/datum/skill_modifier/job/level/wiring) var/datum/team/nuclear/nuke_team var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 2638a6a8e3..e06e8691b3 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -27,19 +27,24 @@ sight = SEE_SELF throwforce = 0 blood_volume = 0 + has_field_of_vision = FALSE //we are a spoopy ghost see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - response_help = "passes through" - response_disarm = "swings through" - response_harm = "punches through" + response_help_continuous = "passes through" + response_help_simple = "pass through" + response_disarm_continuous = "swings through" + response_disarm_simple = "swing through" + response_harm_continuous = "punches through" + response_harm_simple = "punch through" unsuitable_atmos_damage = 0 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway. 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 maxbodytemp = INFINITY harm_intent_damage = 0 - friendly = "touches" + friendly_verb_continuous = "touches" + friendly_verb_simple = "touch" status_flags = 0 wander = FALSE density = FALSE diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index 5d409a7fb9..6b063559dc 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -6,9 +6,12 @@ desc = "A large, menacing creature covered in armored black scales." speak_emote = list("gurgles") emote_hear = list("wails","screeches") - response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" + response_help_continuous = "thinks better of touching" + response_help_simple = "think better of touching" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" icon = 'icons/mob/mob.dmi' icon_state = "daemon" icon_living = "daemon" @@ -24,7 +27,8 @@ minbodytemp = 0 maxbodytemp = INFINITY faction = list("slaughter") - attacktext = "wildly tears into" + attack_verb_continuous = "wildly tears into" + attack_verb_simple = "wildly tear into" maxHealth = 200 health = 200 healable = 0 @@ -116,8 +120,10 @@ desc = "A large, adorable creature covered in armor with pink bows." speak_emote = list("giggles","titters","chuckles") emote_hear = list("guffaws","laughs") - response_help = "hugs" - attacktext = "wildly tickles" + response_help_continuous = "hugs" + response_help_simple = "hug" + attack_verb_continuous = "wildly tickles" + attack_verb_simple = "wildly tickle" attack_sound = 'sound/items/bikehorn.ogg' feast_sound = 'sound/spookoween/scary_horn2.ogg' diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index c1f493ac52..d0e36394ab 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -84,9 +84,11 @@ hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD) obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE - attacktext = "shocks" + attack_verb_continuous = "shocks" + attack_verb_simple = "shock" attack_sound = 'sound/effects/empulse.ogg' - friendly = "pinches" + friendly_verb_continuous = "pinches" + friendly_verb_simple = "pinch" speed = 0 faction = list("swarmer") AIStatus = AI_OFF diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 1d30cdbf77..4422f2f174 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -4,6 +4,7 @@ antagpanel_category = "Traitor" job_rank = ROLE_TRAITOR antag_moodlet = /datum/mood_event/focused + skill_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) var/special_role = ROLE_TRAITOR var/employer = "The Syndicate" var/give_objectives = TRUE diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index d49a8f83c6..a9bc64a932 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -226,7 +226,11 @@ /datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success . = ..() - user.flags_1 |= TESLA_IGNORE_1 + ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell") + +/datum/spellbook_entry/lightningbolt/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) + . = ..() + REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell") /datum/spellbook_entry/infinite_guns name = "Lesser Summon Guns" diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 337486c78a..b8a9b6e793 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -67,6 +67,7 @@ desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous." icon = 'icons/obj/monitors.dmi' icon_state = "alarm0" + plane = ABOVE_WALL_PLANE use_power = IDLE_POWER_USE idle_power_usage = 4 active_power_usage = 8 diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 8f5ab7dd5e..97389848ba 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -17,6 +17,7 @@ active_power_usage = 0 power_channel = ENVIRON layer = GAS_PIPE_HIDDEN_LAYER //under wires + plane = ABOVE_WALL_PLANE resistance_flags = FIRE_PROOF max_integrity = 200 obj_flags = CAN_BE_HIT | ON_BLUEPRINTS diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm index c164dc5ae3..6b685d4bc1 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm @@ -7,6 +7,7 @@ name = "circulator/heat exchanger" desc = "A gas circulator pump and heat exchanger." icon_state = "circ-off-0" + plane = GAME_PLANE var/active = FALSE diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index a45728d51f..c229a4ba27 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -32,7 +32,7 @@ var/turf/T = loc if(level == 2 || (istype(T) && !T.intact)) showpipe = TRUE - plane = GAME_PLANE + plane = ABOVE_WALL_PLANE else showpipe = FALSE plane = FLOOR_PLANE diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 54f14b48a6..cdeb8e701d 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -6,6 +6,7 @@ max_integrity = 350 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30) layer = ABOVE_WINDOW_LAYER + plane = GAME_PLANE state_open = FALSE circuit = /obj/item/circuitboard/machine/cryo_tube pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY @@ -15,8 +16,8 @@ var/volume = 100 var/efficiency = 1 - var/sleep_factor = 0.00125 - var/unconscious_factor = 0.001 + var/base_knockout = 30 SECONDS + var/knockout_factor = 1 var/heat_capacity = 20000 var/conduction_coefficient = 0.3 @@ -53,10 +54,9 @@ var/C for(var/obj/item/stock_parts/matter_bin/M in component_parts) C += M.rating - + // 2 bins total, so C ranges from 2 to 8. efficiency = initial(efficiency) * C - sleep_factor = initial(sleep_factor) * C - unconscious_factor = initial(unconscious_factor) * C + knockout_factor = initial(knockout_factor) / max(1, (C * 0.33)) heat_capacity = initial(heat_capacity) / C conduction_coefficient = initial(conduction_coefficient) * C @@ -188,8 +188,10 @@ if(air1.gases.len) if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. - mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000) - mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000) + // temperature factor goes from 1 to about 2.5 + var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout + mob_occupant.Sleeping(amount) + mob_occupant.Unconscious(amount) if(beaker) if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index c1bd59f49b..79ff24e8b7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -7,6 +7,7 @@ max_integrity = 800 density = TRUE layer = ABOVE_WINDOW_LAYER + plane = GAME_PLANE pipe_flags = PIPING_ONE_PER_TURF var/volume = 10000 //in liters var/gas_type = 0 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index f81e8efb78..1dbf067114 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -9,6 +9,7 @@ max_integrity = 300 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) layer = OBJ_LAYER + plane = GAME_PLANE circuit = /obj/item/circuitboard/machine/thermomachine ui_x = 300 ui_y = 230 diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm index 7afc0d8786..c1f8d9c9d0 100644 --- a/code/modules/cargo/bounties/medical.dm +++ b/code/modules/cargo/bounties/medical.dm @@ -121,7 +121,7 @@ /datum/bounty/item/medical/defibrillator name = "New defibillators" - description = "After years of storge our defib units have become liabilities. Please send us some new ones." + description = "After years of storage our defibrillation units have worn out. Please send us some new ones." reward = 2250 required_count = 5 wanted_types = list(/obj/item/defibrillator) diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index d33d06feca..038030a4dd 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -119,6 +119,7 @@ var/list/data = list() data["requestonly"] = requestonly data["supplies"] = list() + data["emagged"] = obj_flags & EMAGGED for(var/pack in SSshuttle.supply_packs) var/datum/supply_pack/P = SSshuttle.supply_packs[pack] if(!data["supplies"][P.group]) @@ -133,7 +134,8 @@ "cost" = P.cost, "id" = pack, "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. - "access" = P.access + "access" = P.access, + "can_private_buy" = P.can_private_buy )) return data @@ -195,9 +197,10 @@ rank = "Silicon" var/datum/bank_account/account - if(self_paid && ishuman(usr)) - var/mob/living/carbon/human/H = usr - var/obj/item/card/id/id_card = H.get_idcard(TRUE) + if(self_paid) + if(!pack.can_private_buy && !(obj_flags & EMAGGED)) + return + var/obj/item/card/id/id_card = usr.get_idcard(TRUE) if(!istype(id_card)) say("No ID card detected.") return diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index 0a1346ba01..671c22bde5 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -68,7 +68,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message var/message = "" var/cost = 100 // Cost of item, in cargo credits. Must not alow for infinite price dupes, see above. - var/k_elasticity = 1/300 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 1/30 - > 0 + var/k_elasticity = 1/100 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 1/30 - > 100 var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type. var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type. var/list/exclude_types = list() // Types excluded from export diff --git a/code/modules/cargo/exports/gear.dm b/code/modules/cargo/exports/gear.dm index 8dba7f69da..646e1c6e47 100644 --- a/code/modules/cargo/exports/gear.dm +++ b/code/modules/cargo/exports/gear.dm @@ -1,5 +1,6 @@ /datum/export/gear include_subtypes = FALSE + k_elasticity = 0 //We always want clothing/gear //blanket /datum/export/gear/hat diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index b7bdcb1f59..c7a5e59046 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -111,7 +111,7 @@ include_subtypes = FALSE /datum/export/large/am_control_unit - cost = 4000 + cost = 2000 unit_name = "antimatter control unit" export_types = list(/obj/machinery/power/am_control_unit) diff --git a/code/modules/cargo/exports/organs_robotics.dm b/code/modules/cargo/exports/organs_robotics.dm index 7a77568cc7..a6c5ee93ca 100644 --- a/code/modules/cargo/exports/organs_robotics.dm +++ b/code/modules/cargo/exports/organs_robotics.dm @@ -2,15 +2,14 @@ /datum/export/robotics include_subtypes = FALSE - k_elasticity = 0 //ALWAYS worth selling upgrades + k_elasticity = 1/50 /datum/export/implant include_subtypes = FALSE - k_elasticity = 0 //ALWAYS worth selling upgrades + k_elasticity = 1/50 /datum/export/organs include_subtypes = TRUE - k_elasticity = 0 //ALWAYS worth selling orgains /datum/export/implant/autodoc cost = 150 @@ -60,11 +59,6 @@ unit_name = "thrusters set implant" export_types = list(/obj/item/organ/cyberimp/chest/thrusters) -/datum/export/implant/thrusters - cost = 150 - unit_name = "thrusters set implant" - export_types = list(/obj/item/organ/cyberimp/chest/thrusters) - /datum/export/implant/arm cost = 200 unit_name = "arm set implant" diff --git a/code/modules/cargo/exports/parts.dm b/code/modules/cargo/exports/parts.dm index 660d79cae4..da3c0cf31d 100644 --- a/code/modules/cargo/exports/parts.dm +++ b/code/modules/cargo/exports/parts.dm @@ -110,7 +110,7 @@ include_subtypes = FALSE /datum/export/glasswork_lens - cost = 1800 + cost = 1600 unit_name = "small glass lens" export_types = list(/obj/item/glasswork/glass_base/lens) @@ -133,13 +133,13 @@ include_subtypes = FALSE /datum/export/glasswork_teaplate - cost = 1200 + cost = 1000 unit_name = "tea gear" export_types = list(/obj/item/tea_plate) include_subtypes = FALSE /datum/export/glasswork_teacup - cost = 1800 + cost = 1600 unit_name = "tea gear" export_types = list(/obj/item/tea_cup) include_subtypes = FALSE diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm index be0d2d6bee..120bfbe5e4 100644 --- a/code/modules/cargo/exports/sheets.dm +++ b/code/modules/cargo/exports/sheets.dm @@ -120,12 +120,6 @@ message = "of cloth" export_types = list(/obj/item/stack/sheet/cloth) -/datum/export/stack/silk - cost = 200 //The new plasma - unit_name = "sheets" - message = "of silk" - export_types = list(/obj/item/stack/sheet/silk) - /datum/export/stack/duracloth cost = 40 unit_name = "sheets" diff --git a/code/modules/cargo/exports/tools.dm b/code/modules/cargo/exports/tools.dm index a68d7238b5..a889f0ed13 100644 --- a/code/modules/cargo/exports/tools.dm +++ b/code/modules/cargo/exports/tools.dm @@ -1,4 +1,7 @@ -/datum/export/toolbox +/datum/export/tool + k_elasticity = 1/500 //Tool selling almost allways fine a target + +/datum/export/tool/toolbox cost = 6 unit_name = "toolbox" export_types = list(/obj/item/storage/toolbox) @@ -29,93 +32,93 @@ // Lights/Eletronic -/datum/export/lights +/datum/export/tool/lights cost = 10 unit_name = "light fixer" export_types = list(/obj/item/wallframe/light_fixture) include_subtypes = TRUE -/datum/export/apc_board +/datum/export/tool/apc_board cost = 5 unit_name = "apc electronics" export_types = list(/obj/item/electronics/apc) include_subtypes = TRUE -/datum/export/apc_frame +/datum/export/tool/apc_frame cost = 3 unit_name = "apc frame" export_types = list(/obj/item/wallframe/apc) include_subtypes = TRUE -/datum/export/floodlights +/datum/export/tool/floodlights cost = 15 unit_name = "floodlight fixer" export_types = list(/obj/structure/floodlight_frame) include_subtypes = TRUE -/datum/export/bolbstubes +/datum/export/tool/bolbstubes cost = 1 //Time unit_name = "light replacement" export_types = list(/obj/item/light/tube, /obj/item/light/bulb) -/datum/export/lightreplacer +/datum/export/tool/lightreplacer cost = 20 unit_name = "lightreplacer" export_types = list(/obj/item/lightreplacer) // Basic tools -/datum/export/basicmining +/datum/export/tool/basicmining cost = 30 unit_name = "basic mining tool" export_types = list(/obj/item/pickaxe, /obj/item/pickaxe/mini, /obj/item/shovel, /obj/item/resonator) include_subtypes = FALSE -/datum/export/upgradedmining +/datum/export/tool/upgradedmining cost = 80 unit_name = "mining tool" export_types = list(/obj/item/pickaxe/silver, /obj/item/pickaxe/drill, /obj/item/gun/energy/plasmacutter, /obj/item/resonator/upgraded) include_subtypes = FALSE -/datum/export/advdmining +/datum/export/tool/advdmining cost = 150 unit_name = "advanced mining tool" export_types = list(/obj/item/pickaxe/diamond, /obj/item/pickaxe/drill/diamonddrill, /obj/item/pickaxe/drill/jackhammer, /obj/item/gun/energy/plasmacutter/adv) include_subtypes = FALSE -/datum/export/screwdriver +/datum/export/tool/screwdriver cost = 2 unit_name = "screwdriver" export_types = list(/obj/item/screwdriver) include_subtypes = FALSE -/datum/export/wrench +/datum/export/tool/wrench cost = 2 unit_name = "wrench" export_types = list(/obj/item/wrench) -/datum/export/crowbar +/datum/export/tool/crowbar cost = 2 unit_name = "crowbar" export_types = list(/obj/item/crowbar) -/datum/export/wirecutters +/datum/export/tool/wirecutters cost = 2 unit_name = "pair" message = "of wirecutters" export_types = list(/obj/item/wirecutters) -/datum/export/weldingtool +/datum/export/tool/weldingtool cost = 5 unit_name = "welding tool" export_types = list(/obj/item/weldingtool) include_subtypes = FALSE -/datum/export/weldingtool/emergency +/datum/export/tool/weldingtool/emergency cost = 2 unit_name = "emergency welding tool" export_types = list(/obj/item/weldingtool/mini) -/datum/export/weldingtool/industrial +/datum/export/tool/weldingtool/industrial cost = 10 unit_name = "industrial welding tool" export_types = list(/obj/item/weldingtool/largetank, /obj/item/weldingtool/hugetank) @@ -131,23 +134,23 @@ unit_name = "pocket fire extinguisher" export_types = list(/obj/item/extinguisher/mini) -/datum/export/flashlight +/datum/export/tool/flashlight cost = 3 unit_name = "flashlight" export_types = list(/obj/item/flashlight) include_subtypes = FALSE -/datum/export/flashlight/flare +/datum/export/tool/flashlight/flare cost = 2 unit_name = "flare" export_types = list(/obj/item/flashlight/flare) -/datum/export/flashlight/seclite +/datum/export/tool/flashlight/seclite cost = 5 unit_name = "seclite" export_types = list(/obj/item/flashlight/seclite) -/datum/export/analyzer +/datum/export/tool/analyzer cost = 5 unit_name = "analyzer" export_types = list(/obj/item/analyzer) @@ -163,32 +166,32 @@ export_types = list(/obj/item/radio) exclude_types = list(/obj/item/radio/mech) -/datum/export/rcd +/datum/export/tool/rcd cost = 100 unit_name = "rapid construction device" export_types = list(/obj/item/construction/rcd) -/datum/export/rcd_ammo +/datum/export/tool/rcd_ammo cost = 60 unit_name = "compressed matter cardridge" export_types = list(/obj/item/rcd_ammo) -/datum/export/rpd +/datum/export/tool/rpd cost = 100 unit_name = "rapid piping device" export_types = list(/obj/item/pipe_dispenser) -/datum/export/rld +/datum/export/tool/rld cost = 150 unit_name = "rapid light device" export_types = list(/obj/item/construction/rld) -/datum/export/rped +/datum/export/tool/rped cost = 100 unit_name = "rapid part exchange device" export_types = list(/obj/item/storage/part_replacer) -/datum/export/bsrped +/datum/export/tool/bsrped cost = 200 unit_name = "blue space part exchange device" export_types = list(/obj/item/storage/part_replacer/bluespace) diff --git a/code/modules/cargo/gondolapod.dm b/code/modules/cargo/gondolapod.dm index 1b4ebd6c1a..be2db06346 100644 --- a/code/modules/cargo/gondolapod.dm +++ b/code/modules/cargo/gondolapod.dm @@ -2,9 +2,12 @@ name = "gondola" real_name = "gondola" desc = "The silent walker. This one seems to be part of a delivery agency." - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "bops" + response_disarm_simple = "bop" + response_harm_continuous = "kicks" + response_harm_simple = "kick" faction = list("gondola") turns_per_move = 10 icon = 'icons/mob/gondolapod.dmi' diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 96557d58ef..f82e16ad5c 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -15,6 +15,7 @@ var/special_enabled = FALSE var/DropPodOnly = FALSE //only usable by the Bluespace Drop Pod via the express cargo console var/admin_spawned = FALSE //Can only an admin spawn this crate? + var/can_private_buy = TRUE //Can it be purchased privately by each crewmember? /datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account) var/obj/structure/closet/crate/C diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm index 87dfe243b3..3a3357cc42 100644 --- a/code/modules/cargo/packs/armory.dm +++ b/code/modules/cargo/packs/armory.dm @@ -10,6 +10,7 @@ group = "Armory" access = ACCESS_ARMORY crate_type = /obj/structure/closet/crate/secure/weapon + can_private_buy = FALSE /datum/supply_pack/security/armory/bulletarmor name = "Bulletproof Armor Crate" @@ -214,7 +215,7 @@ /datum/supply_pack/security/armory/wt550ammo name = "WT-550 Semi-Auto SMG Ammo Crate" - desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open." + desc = "Contains four 32-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open." cost = 1750 contains = list(/obj/item/ammo_box/magazine/wt550m9, /obj/item/ammo_box/magazine/wt550m9, @@ -224,7 +225,7 @@ /datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stamcrit someone name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate" - desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open." + desc = "Contains four 32-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open." cost = 1000 contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber, /obj/item/ammo_box/magazine/wt550m9/wtrubber, diff --git a/code/modules/cargo/packs/engine.dm b/code/modules/cargo/packs/engine.dm index 89775c07ee..499881a110 100644 --- a/code/modules/cargo/packs/engine.dm +++ b/code/modules/cargo/packs/engine.dm @@ -148,7 +148,7 @@ crate_name = "supermatter shard crate" crate_type = /obj/structure/closet/crate/secure/engineering dangerous = TRUE - + /datum/supply_pack/engine/tesla_coils name = "Tesla Coil Crate" desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!" diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm index 1ce3a6b084..771f7ce222 100644 --- a/code/modules/cargo/packs/materials.dm +++ b/code/modules/cargo/packs/materials.dm @@ -81,32 +81,6 @@ contains = list(/obj/item/stack/sheet/mineral/wood/fifty) crate_name = "wood planks crate" -/datum/supply_pack/materials/rawcotton - name = "Raw Cotton Crate" - desc = "Plushies have been on the down in the market, and now due to a flood of raw cotton the price of it is so cheap, its a steal! Contains 40 raw cotton sheets." - cost = 800 // 100 net cost, 20 x 20 = 400. 300 profit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000 - contains = list(/obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/ten - ) - crate_name = "cotton crate" - crate_type = /obj/structure/closet/crate/hydroponics - -/datum/supply_pack/materials/rawcottonbulk - name = "Raw Cotton Crate (Bulk)" - desc = "We have so much of this stuff we need to get rid of it in -bulk- now. This crate contains 240 raw cotton sheets." - cost = 1300 // 600 net cost 20 x 120 = 2400 profit if turned into cloth sheets or if turned into silk 200 x 60 = 12000 - contains = list(/obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - /obj/item/stack/sheet/cotton/thirty, - ) - crate_name = "bulk cotton crate" - crate_type = /obj/structure/closet/crate/hydroponics - /datum/supply_pack/materials/rcdammo name = "Spare RCD ammo" desc = "This crate contains sixteen RCD compressed matter packs, to help with any holes or projects people might be working on." diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index 5d02bbe60f..ab188f235b 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -252,6 +252,7 @@ crate_name = "virus crate" crate_type = /obj/structure/closet/crate/secure/plasma dangerous = TRUE + can_private_buy = FALSE /datum/supply_pack/medical/anitvirus name = "Virus Containment Crate" @@ -271,4 +272,4 @@ /obj/item/storage/box/syringes, /obj/item/storage/box/beakers) crate_name = "virus containment unit crate" - crate_type = /obj/structure/closet/crate/secure/plasma \ No newline at end of file + crate_type = /obj/structure/closet/crate/secure/plasma diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm index 22cb518926..249faae33d 100644 --- a/code/modules/cargo/packs/organic.dm +++ b/code/modules/cargo/packs/organic.dm @@ -370,22 +370,6 @@ /////////////////////////////////// Misc ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_pack/organic/hunting - name = "Hunting Gear" - desc = "Even in space, we can find prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a hunting shotgun. " - cost = 3500 - contraband = TRUE - contains = list(/obj/item/clothing/head/flatcap, - /obj/item/clothing/suit/hooded/wintercoat/captain, - /obj/item/reagent_containers/food/drinks/bottle/cognac, - /obj/item/storage/fancy/cigarettes/cigars/havana, - /obj/item/clothing/gloves/color/white, - /obj/item/clothing/under/rank/civilian/curator, - /obj/item/gun/ballistic/shotgun/lethal) - access = ACCESS_ARMORY - crate_name = "sporting crate" - crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:( - /datum/supply_pack/organic/party name = "Party Equipment" desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!" diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm index 51bb2b728f..fd6fee362d 100644 --- a/code/modules/cargo/packs/science.dm +++ b/code/modules/cargo/packs/science.dm @@ -17,6 +17,7 @@ cost = 2500 contains = list (/obj/item/reagent_containers/food/snacks/cube/ape) crate_name = "ape cube crate" + can_private_buy = FALSE /datum/supply_pack/science/beakers name = "Chemistry Beakers Crate" diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index d134d7bab8..a48874e974 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -10,6 +10,7 @@ group = "Security" access = ACCESS_SECURITY crate_type = /obj/structure/closet/crate/secure/gear + can_private_buy = FALSE /datum/supply_pack/security/ammo name = "Ammo Crate - General Purpose" @@ -57,6 +58,7 @@ /obj/item/toy/crayon/white, /obj/item/clothing/head/fedora/det_hat) crate_name = "forensics crate" + can_private_buy = TRUE /datum/supply_pack/security/helmets name = "Helmets Crate" @@ -134,6 +136,7 @@ /obj/item/grenade/barrier) cost = 2000 crate_name = "security barriers crate" + can_private_buy = TRUE /datum/supply_pack/security/securityclothes name = "Security Clothing Crate" @@ -152,6 +155,7 @@ /obj/item/clothing/suit/armor/hos/navyblue, /obj/item/clothing/head/beret/sec/navyhos) crate_name = "security clothing crate" + can_private_buy = TRUE /datum/supply_pack/security/supplies name = "Security Supplies Crate" @@ -179,6 +183,7 @@ contains = list(/obj/item/clothing/head/helmet/justice, /obj/item/clothing/mask/gas/sechailer) crate_name = "security clothing crate" + can_private_buy = TRUE /datum/supply_pack/security/baton name = "Stun Batons Crate" @@ -207,3 +212,19 @@ /obj/item/storage/box/wall_flash, /obj/item/storage/box/wall_flash) crate_name = "wall-mounted flash crate" + +/datum/supply_pack/security/hunting + name = "Hunting Gear" + desc = "Even in space, we can find prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a hunting shotgun. " + cost = 3500 + contraband = TRUE + contains = list(/obj/item/clothing/head/flatcap, + /obj/item/clothing/suit/hooded/wintercoat/captain, + /obj/item/reagent_containers/food/drinks/bottle/cognac, + /obj/item/storage/fancy/cigarettes/cigars/havana, + /obj/item/clothing/gloves/color/white, + /obj/item/clothing/under/rank/civilian/curator, + /obj/item/gun/ballistic/shotgun/lethal) + access = ACCESS_ARMORY + crate_name = "sporting crate" + crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:( diff --git a/code/modules/cargo/packs/vending.dm b/code/modules/cargo/packs/vending.dm index 344d19f6c9..810cfd8d6e 100644 --- a/code/modules/cargo/packs/vending.dm +++ b/code/modules/cargo/packs/vending.dm @@ -99,6 +99,7 @@ contains = list(/obj/machinery/vending/security) crate_name = "SecTech supply crate" crate_type = /obj/structure/closet/crate/secure/gear + can_private_buy = FALSE /datum/supply_pack/vending/snack name = "Snack Supply Crate" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index f865cfddbb..47255d9535 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -80,10 +80,24 @@ var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen. + /// Keys currently held + var/list/keys_held = list() + /// These next two vars are to apply movement for keypresses and releases made while move delayed. + /// Because discarding that input makes the game less responsive. + /// On next move, add this dir to the move that would otherwise be done + var/next_move_dir_add + /// On next move, subtract this dir from the move that would otherwise be done + var/next_move_dir_sub + /// Amount of keydowns in the last keysend checking interval var/client_keysend_amount = 0 + /// World tick time where client_keysend_amount will reset var/next_keysend_reset = 0 + /// World tick time where keysend_tripped will reset back to false var/next_keysend_trip_reset = 0 + /// When set to true, user will be autokicked if they trip the keysends in a second limit again var/keysend_tripped = FALSE + /// custom movement keys for this client + var/list/movement_keys = list() /// Messages currently seen by this client var/list/seen_messages diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 2d9fe65ae1..38afc9fa45 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -267,6 +267,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) else prefs = new /datum/preferences(src) GLOB.preferences_datums[ckey] = prefs + if(SSinput.initialized) + set_macros() + update_movement_keys(prefs) prefs.last_ip = address //these are gonna be used for banning prefs.last_id = computer_id //these are gonna be used for banning @@ -330,9 +333,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) qdel(src) return - if(SSinput.initialized) - set_macros() - chatOutput.start() // Starts the chat if(alert_mob_dupe_login) @@ -894,6 +894,23 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) y = clamp(y+change, min,max) change_view("[x]x[y]") +/client/proc/update_movement_keys(datum/preferences/direct_prefs) + var/datum/preferences/D = prefs || direct_prefs + if(!D?.key_bindings) + return + movement_keys = list() + for(var/key in D.key_bindings) + for(var/kb_name in D.key_bindings[key]) + switch(kb_name) + if("North") + movement_keys[key] = NORTH + if("East") + movement_keys[key] = EAST + if("West") + movement_keys[key] = WEST + if("South") + movement_keys[key] = SOUTH + /client/proc/change_view(new_size) if (isnull(new_size)) CRASH("change_view called without argument.") @@ -904,23 +921,27 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) new_size = "15x15" //END OF CIT CHANGES + var/list/old_view = getviewsize(view) view = new_size - apply_clickcatcher() + var/list/actualview = getviewsize(view) + apply_clickcatcher(actualview) mob.reload_fullscreen() if (isliving(mob)) var/mob/living/M = mob M.update_damage_hud() if (prefs.auto_fit_viewport) fit_viewport() + SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_CHANGE_VIEW, src, old_view, actualview) /client/proc/generate_clickcatcher() if(!void) void = new() screen += void -/client/proc/apply_clickcatcher() +/client/proc/apply_clickcatcher(list/actualview) generate_clickcatcher() - var/list/actualview = getviewsize(view) + if(!actualview) + actualview = getviewsize(view) void.UpdateGreed(actualview[1],actualview[2]) /client/proc/AnnouncePR(announcement) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index bb105f2652..77bcbacfcf 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1,11 +1,6 @@ - /* CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! *\ - | THIS FILE CONTAINS HOOKS FOR FOR | - | CHANGES SPECIFIC TO CITADEL. IF | - | YOU'RE FIXING A MERGE CONFLICT | - | HERE, PLEASE ASK FOR REVIEW FROM | - | ANOTHER MAINTAINER TO ENSURE YOU | - | DON'T INTRODUCE REGRESSIONS. | - \* */ +#define DEFAULT_SLOT_AMT 2 +#define HANDS_SLOT_AMT 2 +#define BACKPACK_SLOT_AMT 4 GLOBAL_LIST_EMPTY(preferences_datums) @@ -51,6 +46,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/chat_on_map = TRUE var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH var/see_chat_non_mob = TRUE + + /// Custom Keybindings + var/list/key_bindings = list() + + var/tgui_fancy = TRUE var/tgui_lock = TRUE var/windowflashing = TRUE @@ -189,9 +189,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/uplink_spawn_loc = UPLINK_PDA - var/sprint_spacebar = FALSE - var/sprint_toggle = FALSE - var/hud_toggle_flash = TRUE var/hud_toggle_color = "#ffffff" @@ -204,6 +201,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/vore_flags = 0 var/list/belly_prefs = list() var/vore_taste = "nothing in particular" + var/toggleeatingnoise = TRUE + var/toggledigestionnoise = TRUE + var/hound_sleeper = TRUE + var/cit_toggles = TOGGLES_CITADEL //backgrounds var/mutable_appearance/character_background @@ -214,6 +215,19 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/no_tetris_storage = FALSE + ///loadout stuff + var/gear_points = 10 + var/list/gear_categories + var/list/chosen_gear = list() + var/gear_tab + + var/screenshake = 100 + var/damagescreenshake = 2 + var/arousable = TRUE + var/widescreenpref = TRUE + var/autostand = TRUE + var/auto_ooc = FALSE + /datum/preferences/New(client/C) parent = C @@ -233,6 +247,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) return //we couldn't load character data so just randomize the character appearance + name random_character() //let's create a random character then - rather than a fat, bald and naked man. + key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys + C?.update_movement_keys(src) real_name = pref_species.random_name(gender,1) if(!loaded_preferences_successfully) save_preferences() @@ -254,6 +270,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Loadout" dat += "Game Preferences" dat += "Content Preferences" + dat += "Keybindings" if(!path) dat += "
Please create an account to save your preferences
" @@ -395,7 +412,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) mutant_colors = TRUE if (CONFIG_GET(number/body_size_min) != CONFIG_GET(number/body_size_max)) - dat += "Sprite Size: [features["body_size"]]%
" + dat += "Sprite Size: [features["body_size"]*100]%
" if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits)) @@ -843,7 +860,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "See Runechat for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
" dat += "
" dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" - dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Default"]
" dat += "
" dat += "PDA Color:     Change
" dat += "PDA Style: [pda_style]
" @@ -939,8 +955,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
" dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
" - dat += "Sprint Key: [sprint_spacebar ? "Space" : "Shift"]
" - dat += "Toggle Sprint: [sprint_toggle ? "Enabled" : "Disabled"]
" dat += "HUD Button Flashes: [hud_toggle_flash ? "Enabled" : "Disabled"]
" dat += "HUD Button Flash Color:     Change
" @@ -1063,6 +1077,56 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Ass Slapping: [(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]
" dat += "" dat += "
" + if(5) // Custom keybindings + dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Input"]
" + dat += "Keybindings mode controls how the game behaves with tab and map/input focus.
If it is on Hotkeys, the game will always attempt to force you to map focus, meaning keypresses are sent \ + directly to the map instead of the input. You will still be able to use the command bar, but you need to tab to do it every time you click on the game map.
\ + If it is on Input, the game will not force focus away from the input bar, and you can switch focus using TAB between these two modes: If the input bar is pink, that means that you are in non-hotkey mode, sending all keypresses of the normal \ + alphanumeric characters, punctuation, spacebar, backspace, enter, etc, typing keys into the input bar. If the input bar is white, you are in hotkey mode, meaning all keypresses go into the game's keybind handling system unless you \ + manually click on the input bar to shift focus there.
\ + Input mode is the closest thing to the old input system.
\ + IMPORTANT: While in input mode's non hotkey setting (tab toggled), Ctrl + KEY will send KEY to the keybind system as the key itself, not as Ctrl + KEY. This means Ctrl + T/W/A/S/D/all your familiar stuff still works, but you \ + won't be able to access any regular Ctrl binds.
" + // Create an inverted list of keybindings -> key + var/list/user_binds = list() + for (var/key in key_bindings) + for(var/kb_name in key_bindings[key]) + user_binds[kb_name] += list(key) + + var/list/kb_categories = list() + // Group keybinds by category + for (var/name in GLOB.keybindings_by_name) + var/datum/keybinding/kb = GLOB.keybindings_by_name[name] + kb_categories[kb.category] += list(kb) + + dat += "" + + for (var/category in kb_categories) + dat += "

[category]

" + for (var/i in kb_categories[category]) + var/datum/keybinding/kb = i + if(!length(user_binds[kb.name])) + dat += " Unbound" + var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys + if(LAZYLEN(default_keys)) + dat += "| Default: [default_keys.Join(", ")]" + dat += "
" + else + var/bound_key = user_binds[kb.name][1] + dat += " [bound_key]" + for(var/bound_key_index in 2 to length(user_binds[kb.name])) + bound_key = user_binds[kb.name][bound_key_index] + dat += " | [bound_key]" + if(length(user_binds[kb.name]) < MAX_KEYS_PER_KEYBIND) + dat += "| Add Secondary" + var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys + if(LAZYLEN(default_keys)) + dat += "| Default: [default_keys.Join(", ")]" + dat += "
" + + dat += "

" + dat += "\[Reset to default\]" + dat += "" dat += "
" @@ -1083,6 +1147,31 @@ GLOBAL_LIST_EMPTY(preferences_datums) #undef APPEARANCE_CATEGORY_COLUMN #undef MAX_MUTANT_ROWS +/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, var/old_key) + var/HTML = {" +
Keybinding: [kb.full_name]
[kb.description]

Press any key to change
Press ESC to clear
+ + "} + winshow(user, "capturekeypress", TRUE) + var/datum/browser/popup = new(user, "capturekeypress", "
Keybindings
", 350, 300) + popup.set_content(HTML) + popup.open(FALSE) + onclose(user, "capturekeypress", src) + /datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620) if(!SSjob) return @@ -2263,10 +2352,73 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("hotkeys") hotkeys = !hotkeys - if(hotkeys) - winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default") - else - winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default") + user.client.set_macros() + + if("keybindings_capture") + var/datum/keybinding/kb = GLOB.keybindings_by_name[href_list["keybinding"]] + var/old_key = href_list["old_key"] + CaptureKeybinding(user, kb, old_key) + return + + if("keybindings_set") + var/kb_name = href_list["keybinding"] + if(!kb_name) + user << browse(null, "window=capturekeypress") + ShowChoices(user) + return + + var/clear_key = text2num(href_list["clear_key"]) + var/old_key = href_list["old_key"] + if(clear_key) + if(key_bindings[old_key]) + key_bindings[old_key] -= kb_name + if(!length(key_bindings[old_key])) + key_bindings -= old_key + user << browse(null, "window=capturekeypress") + save_preferences() + ShowChoices(user) + return + + var/new_key = uppertext(href_list["key"]) + var/AltMod = text2num(href_list["alt"]) ? "Alt" : "" + var/CtrlMod = text2num(href_list["ctrl"]) ? "Ctrl" : "" + var/ShiftMod = text2num(href_list["shift"]) ? "Shift" : "" + var/numpad = text2num(href_list["numpad"]) ? "Numpad" : "" + // var/key_code = text2num(href_list["key_code"]) + + if(GLOB._kbMap[new_key]) + new_key = GLOB._kbMap[new_key] + + var/full_key + switch(new_key) + if("Alt") + full_key = "[new_key][CtrlMod][ShiftMod]" + if("Ctrl") + full_key = "[AltMod][new_key][ShiftMod]" + if("Shift") + full_key = "[AltMod][CtrlMod][new_key]" + else + full_key = "[AltMod][CtrlMod][ShiftMod][numpad][new_key]" + if(key_bindings[old_key]) + key_bindings[old_key] -= kb_name + if(!length(key_bindings[old_key])) + key_bindings -= old_key + key_bindings[full_key] += list(kb_name) + key_bindings[full_key] = sortList(key_bindings[full_key]) + + user << browse(null, "window=capturekeypress") + user.client.update_movement_keys() + save_preferences() + + if("keybindings_reset") + var/choice = tgalert(user, "Would you prefer 'hotkey' or 'classic' defaults?", "Setup keybindings", "Hotkey", "Classic", "Cancel") + if(choice == "Cancel") + ShowChoices(user) + return + hotkeys = (choice == "Hotkey") + key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key) + user.client.update_movement_keys() + if("chat_on_map") chat_on_map = !chat_on_map if("see_chat_non_mob") @@ -2385,21 +2537,18 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("ambientocclusion") ambientocclusion = !ambientocclusion if(parent && parent.screen && parent.screen.len) - var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen - PM.backdrop(parent.mob) + var/obj/screen/plane_master/game_world/G = parent.mob.hud_used.plane_masters["[GAME_PLANE]"] + var/obj/screen/plane_master/above_wall/A = parent.mob.hud_used.plane_masters["[ABOVE_WALL_PLANE]"] + var/obj/screen/plane_master/wall/W = parent.mob.hud_used.plane_masters["[WALL_PLANE]"] + G.backdrop(parent.mob) + A.backdrop(parent.mob) + W.backdrop(parent.mob) if("auto_fit_viewport") auto_fit_viewport = !auto_fit_viewport if(auto_fit_viewport && parent) parent.fit_viewport() - if("sprint_key") - sprint_spacebar = !sprint_spacebar - - if("sprint_toggle") - sprint_toggle = !sprint_toggle - - if("hud_toggle_flash") hud_toggle_flash = !hud_toggle_flash @@ -2578,3 +2727,37 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(!cached_holoform_icons[filter_type]) cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type) return cached_holoform_icons[filter_type] + +//Used in savefile update 32, can be removed once that is no longer relevant. +/datum/preferences/proc/force_reset_keybindings() + var/choice = tgalert(parent.mob, "Your basic keybindings need to be reset, emotes will remain as before. Would you prefer 'hotkey' or 'classic' mode?", "Reset keybindings", "Hotkey", "Classic") + hotkeys = (choice != "Classic") + var/list/oldkeys = key_bindings + key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key) + + for(var/key in oldkeys) + if(!key_bindings[key]) + key_bindings[key] = oldkeys[key] + parent.update_movement_keys() + +/datum/preferences/proc/is_loadout_slot_available(slot) + var/list/L + LAZYINITLIST(L) + for(var/i in chosen_gear) + var/datum/gear/G = i + var/occupied_slots = L[slot_to_string(initial(G.category))] ? L[slot_to_string(initial(G.category))] + 1 : 1 + LAZYSET(L, slot_to_string(initial(G.category)), occupied_slots) + switch(slot) + if(SLOT_IN_BACKPACK) + if(L[slot_to_string(SLOT_IN_BACKPACK)] < BACKPACK_SLOT_AMT) + return TRUE + if(SLOT_HANDS) + if(L[slot_to_string(SLOT_HANDS)] < HANDS_SLOT_AMT) + return TRUE + else + if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT) + return TRUE + +#undef DEFAULT_SLOT_AMT +#undef HANDS_SLOT_AMT +#undef BACKPACK_SLOT_AMT diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index ca8599c4d5..a7384ad392 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -5,7 +5,7 @@ // You do not need to raise this if you are adding new values that have sane defaults. // Only raise this value when changing the meaning/format/name/layout of an existing value // where you would want the updater procs below to run -#define SAVEFILE_VERSION_MAX 31 +#define SAVEFILE_VERSION_MAX 32 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn @@ -42,7 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //if your savefile is 3 months out of date, then 'tough shit'. /datum/preferences/proc/update_preferences(current_version, savefile/S) - return + if(current_version < 32) //If you remove this, remove force_reset_keybindings() too. + addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice. /datum/preferences/proc/update_character(current_version, savefile/S) if(current_version < 19) @@ -250,8 +251,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["parallax"] >> parallax S["ambientocclusion"] >> ambientocclusion S["auto_fit_viewport"] >> auto_fit_viewport - S["sprint_spacebar"] >> sprint_spacebar - S["sprint_toggle"] >> sprint_toggle S["hud_toggle_flash"] >> hud_toggle_flash S["hud_toggle_color"] >> hud_toggle_color S["menuoptions"] >> menuoptions @@ -261,6 +260,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["pda_color"] >> pda_color S["pda_skin"] >> pda_skin + // Custom hotkeys + S["key_bindings"] >> key_bindings + //citadel code S["arousable"] >> arousable S["screenshake"] >> screenshake @@ -295,8 +297,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null) ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) - sprint_spacebar = sanitize_integer(sprint_spacebar, 0, 1, initial(sprint_spacebar)) - sprint_toggle = sanitize_integer(sprint_toggle, 0, 1, initial(sprint_toggle)) hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash)) hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color)) ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) @@ -315,6 +315,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles)) auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc)) no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) + key_bindings = sanitize_islist(key_bindings, list()) return 1 @@ -362,8 +363,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["parallax"], parallax) WRITE_FILE(S["ambientocclusion"], ambientocclusion) WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport) - WRITE_FILE(S["sprint_spacebar"], sprint_spacebar) - WRITE_FILE(S["sprint_toggle"], sprint_toggle) WRITE_FILE(S["hud_toggle_flash"], hud_toggle_flash) WRITE_FILE(S["hud_toggle_color"], hud_toggle_color) WRITE_FILE(S["menuoptions"], menuoptions) @@ -372,6 +371,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["pda_style"], pda_style) WRITE_FILE(S["pda_color"], pda_color) WRITE_FILE(S["pda_skin"], pda_skin) + WRITE_FILE(S["key_bindings"], key_bindings) //citadel code WRITE_FILE(S["screenshake"], screenshake) @@ -465,6 +465,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_insect_wings"] >> features["insect_wings"] S["feature_insect_fluff"] >> features["insect_fluff"] S["feature_insect_markings"] >> features["insect_markings"] + S["feature_horns_color"] >> features["horns_color"] + S["feature_wings_color"] >> features["wings_color"] + //Custom names for(var/custom_name_id in GLOB.preferences_custom_names) @@ -541,6 +544,21 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["vore_taste"] >> vore_taste S["belly_prefs"] >> belly_prefs + //gear loadout + var/text_to_load + S["loadout"] >> text_to_load + var/list/saved_loadout_paths = splittext(text_to_load, "|") + chosen_gear = list() + gear_points = CONFIG_GET(number/initial_gear_points) + for(var/i in saved_loadout_paths) + var/datum/gear/path = text2path(i) + if(path) + var/init_cost = initial(path.cost) + if(init_cost > gear_points) + continue + chosen_gear += path + gear_points -= init_cost + //try to fix any outdated data if necessary if(needs_update >= 0) update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer) @@ -701,8 +719,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["shirt_color"] , shirt_color) WRITE_FILE(S["socks"] , socks) WRITE_FILE(S["socks_color"] , socks_color) - WRITE_FILE(S["horns_color"] , features["horns_color"]) - WRITE_FILE(S["wings_color"] , features["wings_color"]) WRITE_FILE(S["backbag"] , backbag) WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style) WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc) @@ -718,6 +734,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"]) WRITE_FILE(S["feature_lizard_legs"] , features["legs"]) WRITE_FILE(S["feature_deco_wings"] , features["deco_wings"]) + WRITE_FILE(S["feature_horns_color"] , features["horns_color"]) + WRITE_FILE(S["feature_wings_color"] , features["wings_color"]) WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"]) WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"]) WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"]) @@ -771,6 +789,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["vore_taste"] , vore_taste) WRITE_FILE(S["belly_prefs"] , belly_prefs) + //gear loadout + if(chosen_gear.len) + var/text_to_save = chosen_gear.Join("|") + S["loadout"] << text_to_save + else + S["loadout"] << "" //empty string to reset the value + cit_character_pref_save(S) return 1 diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 2e72c154d9..695d25dbf4 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -639,7 +639,7 @@ /obj/item/clothing/suit/space/hardsuit/ancient/mason name = "M.A.S.O.N RIG" - desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storge bags on to the suit." + desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storage bags on to the suit." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) @@ -649,7 +649,6 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | IMMUTABLE_SLOW resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - flags_1 = TESLA_IGNORE_1 /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason name = "M.A.S.O.N RIG helmet" @@ -665,7 +664,6 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - flags_1 = TESLA_IGNORE_1 /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize() . = ..() @@ -676,12 +674,14 @@ if (slot == SLOT_HEAD) var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.add_hud_to(user) + ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit") /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user) ..() - if (user.head == src) + if (HAS_TRAIT_FROM(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")) var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC] DHUD.remove_hud_from(user) + REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit") /obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move() var/mob/living/carbon/human/H = loc @@ -915,8 +915,8 @@ /obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() if(!isinhands) - var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER) - energy_overlay.plane = ABOVE_LIGHTING_LAYER + var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", EMISSIVE_LAYER) + energy_overlay.plane = EMISSIVE_PLANE energy_overlay.color = energy_color . += energy_overlay @@ -946,8 +946,8 @@ /obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() if(!isinhands) - var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER) - energy_overlay.plane = ABOVE_LIGHTING_LAYER + var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", EMISSIVE_LAYER) + energy_overlay.plane = EMISSIVE_PLANE energy_overlay.color = energy_color . += energy_overlay diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index e1deb5d28c..f4fd3f7bf3 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -395,10 +395,18 @@ Contains: actions_types = list() resistance_flags = FIRE_PROOF mutantrace_variation = NONE + var/charges = INFINITY -/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize() +/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/Initialize() . = ..() - AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD) + AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone)) + +/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/proc/anti_magic_gone() + var/mob/M = loc + if(!istype(M)) + return + do_sparks(2, TRUE, M) + M.show_message("\The [src] sparks and fizzles as its psychic wards wane away at last...", MSG_VISUAL) /obj/item/clothing/suit/space/hardsuit/ert/paranormal name = "paranormal response team suit" @@ -408,10 +416,18 @@ Contains: helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF + var/charges = INFINITY /obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize() . = ..() - AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING) + AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone)) + +/obj/item/clothing/suit/space/hardsuit/ert/paranormal/proc/anti_magic_gone() + var/mob/M = loc + if(!istype(M)) + return + do_sparks(2, TRUE, M) + M.show_message("\The [src] sparks and fizzles as its anti magic wards wane away at last...", MSG_VISUAL) /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor name = "inquisitor's hardsuit" @@ -424,6 +440,19 @@ Contains: icon_state = "hardsuit0-inq" item_state = "hardsuit0-inq" +/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old + desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted." + armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) + slowdown = 0.8 + obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints. + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old + charges = 12 + +/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old + desc = "A helmet worn by those who deal with paranormal threats for a living. Alas, this one looks pretty worn out and rusted." + armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) + charges = 12 + /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker name = "champion's hardsuit" desc = "Voices echo from the hardsuit, driving the user insane." @@ -437,6 +466,19 @@ Contains: icon_state = "hardsuit0-beserker" item_state = "hardsuit0-beserker" +/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old + desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome." + armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) + slowdown = 0.8 + obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints. + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old + charges = 6 + +/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old + desc = "Peering into the eyes of the helmet is enough to seal damnation. This one is pretty battle-worn, but still fearsome." + armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60) + charges = 6 + /obj/item/clothing/head/helmet/space/fragile name = "emergency space helmet" desc = "A bulky, air-tight helmet meant to protect the user during emergency situations. It doesn't look very durable." @@ -477,4 +519,4 @@ Contains: name = "paramedic EVA helmet" desc = "A deep blue space helmet with a large red cross on the faceplate to designate the wearer as trained emergency medical personnel." icon_state = "paramedic-eva-helmet" - item_state = "paramedic-eva-helmet" \ No newline at end of file + item_state = "paramedic-eva-helmet" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index ce3d2576f9..0a3923b28c 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -76,7 +76,7 @@ icon_state = "dragon" desc = "A suit of armour fashioned from the remains of an ash drake." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/spear) - armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) hoodtype = /obj/item/clothing/head/hooded/cloakhood/drake heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -87,7 +87,7 @@ name = "drake helm" icon_state = "dragon" desc = "The skull of a dragon." - armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100) + armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index c9b7695779..98fb836c38 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -164,21 +164,21 @@ desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap." siemens_coefficient = -1 reactivearmor_cooldown_duration = 20 - var/tesla_power = 25000 - var/tesla_range = 20 - var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE + var/zap_power = 25000 + var/zap_range = 20 + var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE var/legacy = FALSE var/legacy_dmg = 30 /obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user) ..() if(istype(user)) - user.flags_1 &= ~TESLA_IGNORE_1 + REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor") /obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot) ..() if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item? - user.flags_1 |= TESLA_IGNORE_1 + ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor") /obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) @@ -190,7 +190,7 @@ return owner.visible_message("[src] blocks [attack_text], sending out arcs of lightning!") if(!legacy) - tesla_zap(owner, tesla_range, tesla_power, tesla_flags) + tesla_zap(owner, zap_range, zap_power, zap_flags) else for(var/mob/living/M in view(7, owner)) if(M == owner) diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 88821e1afe..cb173f3bde 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -329,14 +329,14 @@ name = "bone talisman" desc = "A hunter's talisman, some say the old gods smile on those who wear it." icon_state = "talisman" - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) /obj/item/clothing/accessory/skullcodpiece name = "skull codpiece" desc = "A skull shaped ornament, intended to protect the important things in life." icon_state = "skull" above_suit = TRUE - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) /obj/item/clothing/accessory/skullcodpiece/fake name = "false codpiece" diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index f3126a362d..44430086eb 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -63,7 +63,7 @@ if(!SSmapping.empty_space) SSmapping.empty_space = SSmapping.add_new_zlevel("Empty Area For Pirates", list(ZTRAIT_LINKAGE = SELFLOOPING)) - + var/datum/map_template/shuttle/pirate/default/ship = new var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width) var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height) @@ -159,11 +159,12 @@ active = FALSE STOP_PROCESSING(SSobj,src) -/obj/machinery/shuttle_scrambler/update_icon_state() +/obj/machinery/shuttle_scrambler/update_overlays() + . = ..() if(active) - icon_state = "dominator-blue" - else - icon_state = "dominator" + var/mutable_appearance/M = mutable_appearance(icon, "dominator-overlay") + M.color = "#00FFFF" + . += M /obj/machinery/shuttle_scrambler/Destroy() toggle_off() diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 60f2aef629..69bfa6e569 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -22,7 +22,8 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/T = pick(turfs) - new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation + new /datum/spacevine_controller(T, list(pick(subtypesof(/datum/spacevine_mutation))), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation + /datum/spacevine_mutation @@ -416,7 +417,6 @@ if(muts && muts.len) for(var/datum/spacevine_mutation/M in muts) M.add_mutation_to_vinepiece(SV) - return if(parent) SV.mutations |= parent.mutations var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY] @@ -541,4 +541,4 @@ var/mob/living/M = A if(("vines" in M.faction) || ("plants" in M.faction)) return TRUE - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 0c2cbc0c67..2c1299f5b4 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -679,9 +679,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( var/list/mob/living/carbon/people = list() var/mob/living/carbon/person = null var/datum/language/understood_language = target.get_random_understood_language() - for(var/mob/living/carbon/H in view(target)) - if(H == target) - continue + for(var/mob/living/carbon/H in view(target) - target) if(!person) person = H else @@ -1064,6 +1062,8 @@ GLOBAL_LIST_INIT(hallucination_list, list( qdel(src) /obj/effect/hallucination/danger + layer = TURF_LAYER + plane = FLOOR_PLANE var/image/image /obj/effect/hallucination/danger/proc/show_icon() @@ -1087,7 +1087,8 @@ GLOBAL_LIST_INIT(hallucination_list, list( name = "lava" /obj/effect/hallucination/danger/lava/show_icon() - image = image('icons/turf/floors/lava.dmi',src,"smooth",TURF_LAYER) + image = image('icons/turf/floors/lava.dmi',src,"smooth",layer) + image.plane = plane if(target.client) target.client.images += image @@ -1257,7 +1258,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( ..() if(!target.halbody) var/list/possible_points = list() - for(var/turf/open/floor/F in view(target,world.view)) + for(var/turf/open/floor/F in target.fov_view(world.view)) possible_points += F if(possible_points.len) var/turf/open/floor/husk_point = pick(possible_points) @@ -1288,7 +1289,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( set waitfor = FALSE ..() var/list/turf/startlocs = list() - for(var/turf/open/T in view(world.view+1,target)-view(world.view,target)) + for(var/turf/open/T in target.fov_view(world.view+1)-view(world.view,target)) startlocs += T if(!startlocs.len) qdel(src) diff --git a/code/modules/food_and_drinks/autobottler.dm b/code/modules/food_and_drinks/autobottler.dm index 6d5e0508a9..37b6fca2ce 100644 --- a/code/modules/food_and_drinks/autobottler.dm +++ b/code/modules/food_and_drinks/autobottler.dm @@ -7,7 +7,7 @@ "Wines", "Beers", "Brands", - "Storge", + "Storage", ) production_animation = "protolathe_n" allowed_buildtypes = AUTOBOTTLER @@ -15,4 +15,4 @@ //Brands - This is just export verson of the booze bottles //Storge - Just the bottles not booze inside //Wines - Holds wines later made by Sci nodes -//Beers - Holds beers later made by Sci nodes \ No newline at end of file +//Beers - Holds beers later made by Sci nodes diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index c5268380a1..48bd0f1da4 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -451,7 +451,7 @@ /obj/item/reagent_containers/food/snacks/donkpocket/initialize_cooked_food(obj/item/reagent_containers/food/snacks/donkpocket/S, cooking_efficiency = 1) . = ..() if(istype(S)) - desc = initial(desc) //reset the desc since will now cool down. + S.desc = initial(S.desc) //reset the desc since will now cool down. for(var/R in S.bonus_reagents) LAZYSET(S.cached_reagents_amount, R, S.reagents.get_reagent_amount(R)) S.previous_typepath = type diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 314cd42446..0acb127517 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -29,7 +29,7 @@ --ms
- +
diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index 7f6d48e731..107282b642 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -38,8 +38,10 @@ health = 25 density = FALSE speech_span = "spooky" - friendly = "pets" - response_help = "chats with" + friendly_verb_continuous = "pets" + friendly_verb_simple = "pet" + response_help_continuous = "chats with" + response_help_simple = "chat with" light_range = 3 light_color = "#ff9842" var/last_poof diff --git a/code/modules/holodeck/mobs.dm b/code/modules/holodeck/mobs.dm index adac4ea7b2..121989bf1e 100644 --- a/code/modules/holodeck/mobs.dm +++ b/code/modules/holodeck/mobs.dm @@ -15,6 +15,9 @@ speak_chance = 1 turns_per_move = 2 butcher_results = list() - response_help = "pets" - response_disarm = "pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "pushes aside" + response_disarm_simple = "push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" diff --git a/code/modules/hydroponics/grown/peas.dm b/code/modules/hydroponics/grown/peas.dm new file mode 100644 index 0000000000..6229d98b2c --- /dev/null +++ b/code/modules/hydroponics/grown/peas.dm @@ -0,0 +1,102 @@ +// Finally, peas. Base plant. +/obj/item/seeds/peas + name = "pack of pea pods" + desc = "These seeds grows into vitamin rich peas!" + icon_state = "seed-peas" + species = "peas" + plantname = "Pea Vines" + product = /obj/item/reagent_containers/food/snacks/grown/peas + maturation = 3 + potency = 25 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "peas-grow" + icon_dead = "peas-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/peas/laugh) // TODO: Add /obj/item/seeds/peas/shoot at a later date, for the peashooter mutation line + reagents_add = list (/datum/reagent/consumable/nutriment/vitamin = 0.1, /datum/reagent/consumable/nutriment = 0.05, /datum/reagent/water = 0.05) + + +/obj/item/reagent_containers/food/snacks/grown/peas + seed = /obj/item/seeds/peas + name = "peapod" + desc = "Finally... peas." + icon_state = "peas" + filling_color = "#739122" + bitesize_mod = 1 + foodtype = VEGETABLES + tastes = list ("peas" = 1, "chalky saltiness" = 1) + wine_power = 50 + wine_flavor = "what is, distressingly, fermented peas." + // distill_regeant = /datum/reagent/saltpetre //if allowed, remove wine_power, ya dingus. + + +// Laughin' Peas +/obj/item/seeds/peas/laugh + name = "pack of laughin' peas" + desc = "These seeds give off a very soft purple glow.. they should grow into Laughin' Peas." + icon_state = "seed-laughpeas" + species = "laughpeas" + plantname = "Laughin' Peas" + product = /obj/item/reagent_containers/food/snacks/grown/laugh + maturation = 7 + potency = 10 + yield = 7 + production = 5 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "laughpeas-grow" + icon_dead = "laughpeas-dead" + genes = list (/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/purple) + mutatelist = list (/obj/item/seeds/peas/laugh/peace) + reagents_add = list (/datum/reagent/consumable/laughter = 0.05, /datum/reagent/consumable/sugar = 0.05, /datum/reagent/consumable/nutriment = 0.07) + rarity = 25 //It actually might make Central Command Officials loosen up a smidge, eh? + + +/obj/item/reagent_containers/food/snacks/grown/laugh + seed = /obj/item/seeds/peas/laugh + name = "pod of laughin' peas" + desc = "Ridens Cicer, guaranteed to improve your mood dramatically upon consumption!" + icon_state = "laughpeas" + filling_color = "#ee7bee" + bitesize_mod = 2 + foodtype = VEGETABLES + tastes = list ("a prancing rabbit" = 1) //Vib Ribbon sends her regards.. wherever she is. + wine_power = 90 + wine_flavor = "a vector-graphic rabbit dancing on your tongue" + + +// World Peas - Peace at last, peace at last... +/obj/item/seeds/peas/laugh/peace + name = "pack of world peas" + desc = "These rather large seeds give off a soothing blue glow..." + icon_state = "seed-worldpeas" + species = "worldpeas" + plantname = "World Peas" + product = /obj/item/reagent_containers/food/snacks/grown/peace + maturation = 20 + potency = 75 + yield = 1 + production = 10 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "worldpeas-grow" + icon_dead = "worldpeas-dead" + genes = list (/datum/plant_gene/trait/glow/blue) + reagents_add = list (/datum/reagent/pax = 0.1, /datum/reagent/drug/happiness = 0.1, /datum/reagent/consumable/nutriment = 0.15) + rarity = 50 // This absolutely will make even the most hardened Syndicate Operators relax, and lay down their arms. + + +/obj/item/reagent_containers/food/snacks/grown/peace + seed = /obj/item/seeds/peas/laugh/peace + name = "cluster of world peas" + desc = "A plant discovered through extensive genetic engineering, and iterative graft work. It's rumored to bring peace to any who consume it. In the wider AgSci community, it's attained the nickname of 'Pax Mundi'." //at last... world peas. I'm not sorry. + icon_state = "worldpeas" + filling_color = "#0099CC" + bitesize_mod = 4 + foodtype = VEGETABLES + tastes = list ("numbing tranquility" = 2, "warmth" = 1) + wine_power = 100 + wine_flavor = "mind-numbing peace and warmth" + + diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index ef63ba97f8..384991e976 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -873,3 +873,8 @@ pixel_x = -31 if(WEST) pixel_x = 31 + plane = ABOVE_WALL_PLANE + +/obj/item/electronic_assembly/wallmount/Moved(atom/OldLoc, Dir, Forced = FALSE) //reset the plane if moved off the wall. + . = ..() + plane = GAME_PLANE diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 8c7529651b..ebb91a894e 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -426,7 +426,7 @@ activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() +/obj/item/integrated_circuit/converter/rel_to_abs_coords/do_work() var/x1 = get_pin_data(IC_INPUT, 1) var/y1 = get_pin_data(IC_INPUT, 2) @@ -456,7 +456,7 @@ activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH -/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work() +/obj/item/integrated_circuit/converter/adv_rel_to_abs_coords/do_work() var/turf/T = get_turf(src) if(!T) diff --git a/code/modules/integrated_electronics/subtypes/weaponized.dm b/code/modules/integrated_electronics/subtypes/weaponized.dm index 2f6a2cd841..3123eeabbe 100644 --- a/code/modules/integrated_electronics/subtypes/weaponized.dm +++ b/code/modules/integrated_electronics/subtypes/weaponized.dm @@ -296,6 +296,7 @@ var/x_abs = clamp(T.x + target_x_rel, 0, world.maxx) var/y_abs = clamp(T.y + target_y_rel, 0, world.maxy) var/range = round(clamp(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1) + playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1) assembly.visible_message("\The [assembly] has thrown [A]!") log_attack("[assembly] [REF(assembly)] has thrown [A] with lethal force.") A.forceMove(drop_location()) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 8539ed071d..c700d668c5 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -69,10 +69,8 @@ // How much threat this job is worth in dynamic. Is subtracted if the player's not an antag, added if they are. var/threat = 0 - /// Starting skill levels. - var/list/starting_skills - /// Skill affinities to set - var/list/skill_affinities + /// Starting skill modifiers. + var/list/starting_modifiers //Only override this proc //H is usually a human unless an /equip override transformed it @@ -180,15 +178,10 @@ to_chat(M, "Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset.") /datum/job/proc/standard_assign_skills(datum/mind/M) - if(!starting_skills) + if(!starting_modifiers) return - for(var/skill in starting_skills) - M.skill_holder.boost_skill_value_to(skill, starting_skills[skill], TRUE) //silent - // do wipe affinities though - M.skill_holder.skill_affinities = list() - for(var/skill in skill_affinities) - M.skill_holder.skill_affinities[skill] = skill_affinities[skill] - UNSETEMPTY(M.skill_holder.skill_affinities) //if we didn't set any. + for(var/mod in starting_modifiers) + ADD_SINGLETON_SKILL_MODIFIER(M, mod, null) /datum/outfit/job name = "Standard Gear" diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index 1395b90b39..a7401791ab 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -17,7 +17,7 @@ var/do_special_check = TRUE threat = 5 - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC)) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) /datum/job/ai/equip(mob/living/carbon/human/H, visualsOnly, announce, latejoin, datum/outfit/outfit_override, client/preference_source = null) if(visualsOnly) diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm index 768aff0927..1962b8e8a9 100644 --- a/code/modules/jobs/job_types/atmospheric_technician.dm +++ b/code/modules/jobs/job_types/atmospheric_technician.dm @@ -20,8 +20,7 @@ paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_ENG - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC)) - skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN threat = 0.5 diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm index a477ff3da3..b2699071e3 100644 --- a/code/modules/jobs/job_types/chemist.dm +++ b/code/modules/jobs/job_types/chemist.dm @@ -21,8 +21,7 @@ display_order = JOB_DISPLAY_ORDER_CHEMIST threat = 1.5 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) - skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/chemist name = "Chemist" diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm index eee0c3437f..d8df767a9f 100644 --- a/code/modules/jobs/job_types/chief_engineer.dm +++ b/code/modules/jobs/job_types/chief_engineer.dm @@ -29,8 +29,7 @@ paycheck = PAYCHECK_COMMAND paycheck_department = ACCOUNT_ENG - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) - skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity) diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index 89bb4ed96b..adee2856fa 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -31,8 +31,7 @@ blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) threat = 2 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) - skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/cmo name = "Chief Medical Officer" diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm index d88d888aec..4f74542b2a 100644 --- a/code/modules/jobs/job_types/cyborg.dm +++ b/code/modules/jobs/job_types/cyborg.dm @@ -12,7 +12,7 @@ exp_requirements = 120 exp_type = EXP_TYPE_CREW - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC)) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic) display_order = JOB_DISPLAY_ORDER_CYBORG diff --git a/code/modules/jobs/job_types/geneticist.dm b/code/modules/jobs/job_types/geneticist.dm index 21ba9f0f9b..a40ca0fca3 100644 --- a/code/modules/jobs/job_types/geneticist.dm +++ b/code/modules/jobs/job_types/geneticist.dm @@ -21,7 +21,7 @@ display_order = JOB_DISPLAY_ORDER_GENETICIST threat = 1.5 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/geneticist name = "Geneticist" diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm index bff83df973..5ec4b83b2f 100644 --- a/code/modules/jobs/job_types/medical_doctor.dm +++ b/code/modules/jobs/job_types/medical_doctor.dm @@ -19,8 +19,7 @@ display_order = JOB_DISPLAY_ORDER_MEDICAL_DOCTOR threat = 0.5 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) - skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/doctor name = "Medical Doctor" diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index c253574268..9bdfdfe279 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -21,8 +21,7 @@ threat = 0.5 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) - skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/paramedic name = "Paramedic" diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm index b4801ce6df..f5ae93bb6a 100644 --- a/code/modules/jobs/job_types/roboticist.dm +++ b/code/modules/jobs/job_types/roboticist.dm @@ -18,9 +18,7 @@ paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_SCI - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) - skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) - + starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_ROBOTICIST threat = 1 diff --git a/code/modules/jobs/job_types/station_engineer.dm b/code/modules/jobs/job_types/station_engineer.dm index f5b8c7cd4e..d3f5db7dbb 100644 --- a/code/modules/jobs/job_types/station_engineer.dm +++ b/code/modules/jobs/job_types/station_engineer.dm @@ -20,8 +20,7 @@ paycheck = PAYCHECK_MEDIUM paycheck_department = ACCOUNT_ENG - starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED)) - skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO) + starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring) display_order = JOB_DISPLAY_ORDER_STATION_ENGINEER diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm index 37a21dd3ac..790e828931 100644 --- a/code/modules/jobs/job_types/virologist.dm +++ b/code/modules/jobs/job_types/virologist.dm @@ -22,8 +22,7 @@ threat = 1.5 - starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL) - skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL) + starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery) /datum/outfit/job/virologist name = "Virologist" diff --git a/code/modules/keybindings/bindings_admin.dm b/code/modules/keybindings/bindings_admin.dm deleted file mode 100644 index ca232adbe0..0000000000 --- a/code/modules/keybindings/bindings_admin.dm +++ /dev/null @@ -1,24 +0,0 @@ -/datum/admins/key_down(_key, client/user) - switch(_key) - if("F3") - user.get_admin_say() - return - if("F5") - user.admin_ghost() - return - if("F6") - player_panel_new() - return - if("F7") - user.togglebuildmodeself() - return - if("F8") - if(user.keys_held["Ctrl"]) - user.stealth() - else - user.invisimin() - return - if("F10") - user.get_dead_say() - return - ..() diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm index 5f3e879237..47d6b16feb 100644 --- a/code/modules/keybindings/bindings_atom.dm +++ b/code/modules/keybindings/bindings_atom.dm @@ -5,7 +5,7 @@ if(!user.keys_held["Ctrl"]) var/movement_dir = NONE for(var/_key in user.keys_held) - movement_dir = movement_dir | SSinput.movement_keys[_key] + movement_dir = movement_dir | user.movement_keys[_key] if(user.next_move_dir_add) movement_dir |= user.next_move_dir_add if(user.next_move_dir_sub) diff --git a/code/modules/keybindings/bindings_carbon.dm b/code/modules/keybindings/bindings_carbon.dm deleted file mode 100644 index e344bc9d20..0000000000 --- a/code/modules/keybindings/bindings_carbon.dm +++ /dev/null @@ -1,9 +0,0 @@ -/mob/living/carbon/key_down(_key, client/user) - switch(_key) - if("R", "Southwest") // Southwest is End - toggle_throw_mode() - return - if("C") - user_toggle_intentional_combat_mode() - return - return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index 6030362a61..a73dd9a59b 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -33,55 +33,69 @@ to_chat(src, "Invalid KeyDown detected! You have been disconnected from the server automatically.") log_admin("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") - QDEL_IN(src, 1) + qdel(src) + return + + if(_key == "Tab") + ForceAllKeysUp() //groan, more hacky kevcode return if(length(keys_held) > MAX_HELD_KEYS) keys_held.Cut(1,2) keys_held[_key] = TRUE - var/movement = SSinput.movement_keys[_key] + var/movement = movement_keys[_key] if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"]) next_move_dir_add |= movement // Client-level keybindings are ones anyone should be able to do at any time // Things like taking screenshots, hitting tab, and adminhelps. - + var/AltMod = keys_held["Alt"] ? "Alt" : "" + var/CtrlMod = keys_held["Ctrl"] ? "Ctrl" : "" + var/ShiftMod = keys_held["Shift"] ? "Shift" : "" + var/full_key switch(_key) - if("F1") - if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used? - winset(src, null, "command=.options") - else - get_adminhelp() - return - if("F2") // Screenshot. Hold shift to choose a name and location to save in - winset(src, null, "command=.screenshot [!keys_held["shift"] ? "auto" : ""]") - return - if("F12") // Toggles minimal HUD - mob.button_pressed_F12() - return + if("Alt", "Ctrl", "Shift") + full_key = "[AltMod][CtrlMod][ShiftMod]" + else + full_key = "[AltMod][CtrlMod][ShiftMod][_key]" + var/keycount = 0 + for(var/kb_name in prefs.key_bindings[full_key]) + keycount++ + var/datum/keybinding/kb = GLOB.keybindings_by_name[kb_name] + if(kb.can_use(src) && kb.down(src) && keycount >= MAX_COMMANDS_PER_KEY) + break - if(holder) - holder.key_down(_key, src) - if(mob.focus) - mob.focus.key_down(_key, src) + holder?.key_down(_key, src) + mob.focus?.key_down(_key, src) + +/// Keyup's all keys held down. +/client/proc/ForceAllKeysUp() + // simulate a user releasing all keys except for the mod keys. groan. i hate this. thanks, byond. why aren't keyups able to be forced to fire on macro change aoaoaoao. + // groan + for(var/key in keys_held) // all of these won't be the 3 mod keys. + if((key == "Ctrl") || (key == "Alt") || (key == "Shift")) + continue + keyUp("[key]") /client/verb/keyUp(_key as text) set instant = TRUE set hidden = TRUE keys_held -= _key - var/movement = SSinput.movement_keys[_key] + var/movement = movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement - if(holder) - holder.key_up(_key, src) - if(mob.focus) - mob.focus.key_up(_key, src) + // We don't do full key for release, because for mod keys you + // can hold different keys and releasing any should be handled by the key binding specifically + for (var/kb_name in prefs.key_bindings[_key]) + var/datum/keybinding/kb = GLOB.keybindings_by_name[kb_name] + if(kb.can_use(src) && kb.up(src)) + break + holder?.key_up(_key, src) + mob.focus?.key_up(_key, src) // Called every game tick /client/keyLoop() - if(holder) - holder.keyLoop(src) - if(mob.focus) - mob.focus.keyLoop(src) \ No newline at end of file + holder?.keyLoop(src) + mob.focus?.keyLoop(src) diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm deleted file mode 100644 index 9569de338c..0000000000 --- a/code/modules/keybindings/bindings_human.dm +++ /dev/null @@ -1,80 +0,0 @@ -/mob/living/carbon/human/key_down(_key, client/user) - if(client.keys_held["Shift"]) - switch(_key) - if("E") // Put held thing in belt or take out most recent thing from belt - var/obj/item/thing = get_active_held_item() - var/obj/item/storage/equipped_belt = get_item_by_slot(SLOT_BELT) - if(!equipped_belt) // We also let you equip a belt like this - if(!thing) - to_chat(user, "You have no belt to take something out of.") - return - equip_to_slot_if_possible(thing, SLOT_BELT) - return - if(!istype(equipped_belt)) // not a storage item - if(!thing) - to_chat(user, "You have no belt to take something out of.") - else - to_chat(user, "You can't fit anything in.") - return - if(thing) // put thing in belt - if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, user.mob)) - to_chat(user, "You can't fit anything in.") - return - if(!equipped_belt.contents.len) // nothing to take out - to_chat(user, "There's nothing in your belt to take out.") - return - var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len] - if(!stored || stored.on_found(src)) - return - stored.attack_hand(src) // take out thing from belt - return - - if("B") // Put held thing in backpack or take out most recent thing from backpack - var/obj/item/thing = get_active_held_item() - var/obj/item/storage/equipped_backpack = get_item_by_slot(SLOT_BACK) - if(!equipped_backpack) // We also let you equip a backpack like this - if(!thing) - to_chat(user, "You have no backpack to take something out of.") - return - equip_to_slot_if_possible(thing, SLOT_BACK) - return - if(!istype(equipped_backpack)) // not a storage item - if(!thing) - to_chat(user, "You have no backpack to take something out of.") - else - to_chat(user, "You can't fit anything in.") - return - if(thing) // put thing in backpack - if(!SEND_SIGNAL(equipped_backpack, COMSIG_TRY_STORAGE_INSERT, thing, user.mob)) - to_chat(user, "You can't fit anything in.") - return - if(!equipped_backpack.contents.len) // nothing to take out - to_chat(user, "There's nothing in your backpack to take out.") - return - var/obj/item/stored = equipped_backpack.contents[equipped_backpack.contents.len] - if(!stored || stored.on_found(src)) - return - stored.attack_hand(src) // take out thing from backpack - return - switch(_key) - if("Shift") - if(!user.prefs.sprint_spacebar) - user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE) //Yes, this looks hacky. Yes, this works. - return - if("Space") - if(user.prefs.sprint_spacebar) - user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE) - return - return ..() - -/mob/living/carbon/human/key_up(_key, client/user) - switch(_key) - if("Shift") - if(!user.prefs.sprint_spacebar && !user.prefs.sprint_toggle) - sprint_hotkey(FALSE) - return - if("Space") - if(user.prefs.sprint_spacebar && !user.prefs.sprint_toggle) - sprint_hotkey(FALSE) - return - return ..() diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm deleted file mode 100644 index ec6c5dd539..0000000000 --- a/code/modules/keybindings/bindings_living.dm +++ /dev/null @@ -1,27 +0,0 @@ -/mob/living/key_down(_key, client/user) - switch(_key) - if("B") - resist() - return - if("1") - if(possible_a_intents) - a_intent_change(INTENT_HELP) - return - if("2") - if(possible_a_intents) - a_intent_change(INTENT_DISARM) - return - if("3") - if(possible_a_intents) - a_intent_change(INTENT_GRAB) - return - if("4") - if(possible_a_intents) - a_intent_change(INTENT_HARM) - return - if ("V") - lay_down() - return - - - return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_mob.dm b/code/modules/keybindings/bindings_mob.dm deleted file mode 100644 index 36b4775c34..0000000000 --- a/code/modules/keybindings/bindings_mob.dm +++ /dev/null @@ -1,94 +0,0 @@ -// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things -// All it takes is one badmin setting their focus to someone else's client to mess things up -// Or we can have NPC's send actual keypresses and detect that by seeing no client - -/mob/key_down(_key, client/user) - switch(_key) - if("Delete", "H") - if(!pulling) - to_chat(src, "You are not pulling anything.") - else - stop_pulling() - return - if("Insert", "G") - a_intent_change(INTENT_HOTKEY_RIGHT) - return - if("F") - a_intent_change(INTENT_HOTKEY_LEFT) - return - if("X", "Northeast") // Northeast is Page-up - swap_hand() - return - if("Y", "Z", "Southeast") // Southeast is Page-down - mode() // attack_self(). No idea who came up with "mode()" - return - if("Q", "Northwest") // Northwest is Home - var/obj/item/I = get_active_held_item() - if(!I) - to_chat(src, "You have nothing to drop in your hand!") - else - dropItemToGround(I) - return - if("E") - quick_equip() - return - if("Alt") - toggle_move_intent() - return - //Bodypart selections - if("Numpad8") - user.body_toggle_head() - return - if("Numpad4") - user.body_r_arm() - return - if("Numpad5") - user.body_chest() - return - if("Numpad6") - user.body_l_arm() - return - if("Numpad1") - user.body_r_leg() - return - if("Numpad2") - user.body_groin() - return - if("Numpad3") - user.body_l_leg() - return - - if(client.keys_held["Ctrl"]) - switch(SSinput.movement_keys[_key]) - if(NORTH) - if(client.keys_held["Shift"]) - northshift() - else - northface() - return - if(SOUTH) - if(client.keys_held["Shift"]) - southshift() - else - southface() - return - if(WEST) - if(client.keys_held["Shift"]) - westshift() - else - westface() - return - if(EAST) - if(client.keys_held["Shift"]) - eastshift() - else - eastface() - return - return ..() - -/mob/key_up(_key, client/user) - switch(_key) - if("Alt") - toggle_move_intent() - return - return ..() diff --git a/code/modules/keybindings/bindings_robot.dm b/code/modules/keybindings/bindings_robot.dm deleted file mode 100644 index 29fb36fa65..0000000000 --- a/code/modules/keybindings/bindings_robot.dm +++ /dev/null @@ -1,22 +0,0 @@ -/mob/living/silicon/robot/key_down(_key, client/user) - switch(_key) - if("1", "2", "3") - toggle_module(text2num(_key)) - return - if("4") - a_intent_change(INTENT_HOTKEY_LEFT) - return - if("Q") - uneq_active() - return - if("Shift") - sprint_hotkey(TRUE) - return - return ..() - -/mob/living/silicon/robot/key_up(_key, client/user) - switch(_key) - if("Shift") - sprint_hotkey(FALSE) - return - return ..() diff --git a/code/modules/keybindings/focus.dm b/code/modules/keybindings/focus.dm index 205b293e9a..d542b49267 100644 --- a/code/modules/keybindings/focus.dm +++ b/code/modules/keybindings/focus.dm @@ -1,6 +1,3 @@ -/mob - var/datum/focus //What receives our keyboard inputs. src by default - /mob/proc/set_focus(datum/new_focus) if(focus == new_focus) return diff --git a/code/modules/keybindings/keybind/__defines.dm b/code/modules/keybindings/keybind/__defines.dm new file mode 100644 index 0000000000..baa095987c --- /dev/null +++ b/code/modules/keybindings/keybind/__defines.dm @@ -0,0 +1,20 @@ +#define CATEGORY_CLIENT "CLIENT" +#define CATEGORY_EMOTE "EMOTE" +#define CATEGORY_ADMIN "ADMIN" +#define CATEGORY_XENO "XENO" +#define CATEGORY_CARBON "CARBON" +#define CATEGORY_HUMAN "HUMAN" +#define CATEGORY_ROBOT "ROBOT" +#define CATEGORY_MISC "MISC" +#define CATEGORY_MOVEMENT "MOVEMENT" +#define CATEGORY_TARGETING "TARGETING" + +#define WEIGHT_HIGHEST 0 +#define WEIGHT_ADMIN 10 +#define WEIGHT_CLIENT 20 +#define WEIGHT_ROBOT 30 +#define WEIGHT_MOB 40 +#define WEIGHT_LIVING 50 +#define WEIGHT_DEAD 60 +#define WEIGHT_EMOTE 70 +#define WEIGHT_LOWEST 999 diff --git a/code/modules/keybindings/keybind/_keybind.dm b/code/modules/keybindings/keybind/_keybind.dm new file mode 100644 index 0000000000..1d68e2d037 --- /dev/null +++ b/code/modules/keybindings/keybind/_keybind.dm @@ -0,0 +1,24 @@ +/datum/keybinding + var/list/hotkey_keys + var/list/classic_keys + var/name + var/full_name + var/description = "" + var/category = CATEGORY_MISC + var/weight = WEIGHT_LOWEST + var/keybind_signal + +/datum/keybinding/New() + + // Default keys to the master "hotkey_keys" + if(LAZYLEN(hotkey_keys) && !LAZYLEN(classic_keys)) + classic_keys = hotkey_keys.Copy() + +/datum/keybinding/proc/down(client/user) + return FALSE + +/datum/keybinding/proc/up(client/user) + return FALSE + +/datum/keybinding/proc/can_use(client/user) + return TRUE diff --git a/code/modules/keybindings/keybind/admin.dm b/code/modules/keybindings/keybind/admin.dm new file mode 100644 index 0000000000..b63221e97a --- /dev/null +++ b/code/modules/keybindings/keybind/admin.dm @@ -0,0 +1,96 @@ +/datum/keybinding/admin + category = CATEGORY_ADMIN + weight = WEIGHT_ADMIN + +/datum/keybinding/admin/can_use(client/user) + return user.holder ? TRUE : FALSE + +/datum/keybinding/admin/admin_say + hotkey_keys = list("F3") + name = "admin_say" + full_name = "Admin say" + description = "Talk with other admins." + +/datum/keybinding/admin/admin_say/down(client/user) + user.get_admin_say() + return TRUE + +/datum/keybinding/admin/admin_ghost + hotkey_keys = list("F5") + name = "admin_ghost" + full_name = "Aghost" + description = "Go ghost" + +/datum/keybinding/admin/admin_ghost/down(client/user) + user.admin_ghost() + return TRUE + +/datum/keybinding/admin/player_panel_new + hotkey_keys = list("F6") + name = "player_panel_new" + full_name = "Player Panel New" + description = "Opens up the new player panel" + +/datum/keybinding/admin/player_panel_new/down(client/user) + user.holder.player_panel_new() + return TRUE + +/datum/keybinding/admin/toggle_buildmode_self + hotkey_keys = list("F7") + name = "toggle_buildmode_self" + full_name = "Toggle Buildmode Self" + description = "Toggles buildmode" + +/datum/keybinding/admin/toggle_buildmode_self/down(client/user) + user.togglebuildmodeself() + return TRUE + +/datum/keybinding/admin/stealthmode + hotkey_keys = list("CtrlF8") + name = "stealth_mode" + full_name = "Stealth mode" + description = "Enters stealth mode" + +/datum/keybinding/admin/stealthmode/down(client/user) + user.stealth() + return TRUE + +/datum/keybinding/admin/invisimin + hotkey_keys = list("F8") + name = "invisimin" + full_name = "Admin invisibility" + description = "Toggles ghost-like invisibility (Don't abuse this)" + +/datum/keybinding/admin/invisimin/down(client/user) + user.invisimin() + return TRUE + +/datum/keybinding/admin/deadsay + hotkey_keys = list("F10") + name = "dsay" + full_name = "deadsay" + description = "Allows you to send a message to dead chat" + +/datum/keybinding/admin/deadsay/down(client/user) + user.get_dead_say() + return TRUE + +/datum/keybinding/admin/deadmin + hotkey_keys = list("Unbound") + name = "deadmin" + full_name = "Deadmin" + description = "Shed your admin powers" + +/datum/keybinding/admin/deadmin/down(client/user) + user.deadmin() + return TRUE + +/datum/keybinding/admin/readmin + hotkey_keys = list("Unbound") + name = "readmin" + full_name = "Readmin" + description = "Regain your admin powers" + +/datum/keybinding/admin/readmin/down(client/user) + user.readmin() + return TRUE diff --git a/code/modules/keybindings/keybind/carbon.dm b/code/modules/keybindings/keybind/carbon.dm new file mode 100644 index 0000000000..46cb5cd0ac --- /dev/null +++ b/code/modules/keybindings/keybind/carbon.dm @@ -0,0 +1,62 @@ +/datum/keybinding/carbon + category = CATEGORY_CARBON + weight = WEIGHT_MOB + +/datum/keybinding/carbon/can_use(client/user) + return iscarbon(user.mob) + +/datum/keybinding/carbon/toggle_throw_mode + hotkey_keys = list("R", "Southwest") // END + name = "toggle_throw_mode" + full_name = "Toggle throw mode" + description = "Toggle throwing the current item or not." + category = CATEGORY_CARBON + +/datum/keybinding/carbon/toggle_throw_mode/down(client/user) + var/mob/living/carbon/C = user.mob + C.toggle_throw_mode() + return TRUE + +/datum/keybinding/carbon/select_help_intent + hotkey_keys = list("1") + name = "select_help_intent" + full_name = "Select help intent" + description = "" + category = CATEGORY_CARBON + +/datum/keybinding/carbon/select_help_intent/down(client/user) + user.mob?.a_intent_change(INTENT_HELP) + return TRUE + +/datum/keybinding/carbon/select_disarm_intent + hotkey_keys = list("2") + name = "select_disarm_intent" + full_name = "Select disarm intent" + description = "" + category = CATEGORY_CARBON + +/datum/keybinding/carbon/select_disarm_intent/down(client/user) + user.mob?.a_intent_change(INTENT_DISARM) + return TRUE + +/datum/keybinding/carbon/select_grab_intent + hotkey_keys = list("3") + name = "select_grab_intent" + full_name = "Select grab intent" + description = "" + category = CATEGORY_CARBON + +/datum/keybinding/carbon/select_grab_intent/down(client/user) + user.mob?.a_intent_change(INTENT_GRAB) + return TRUE + +/datum/keybinding/carbon/select_harm_intent + hotkey_keys = list("4") + name = "select_harm_intent" + full_name = "Select harm intent" + description = "" + category = CATEGORY_CARBON + +/datum/keybinding/carbon/select_harm_intent/down(client/user) + user.mob?.a_intent_change(INTENT_HARM) + return TRUE diff --git a/code/modules/keybindings/keybind/client.dm b/code/modules/keybindings/keybind/client.dm new file mode 100644 index 0000000000..1d44efa063 --- /dev/null +++ b/code/modules/keybindings/keybind/client.dm @@ -0,0 +1,33 @@ +/datum/keybinding/client + category = CATEGORY_CLIENT + weight = WEIGHT_HIGHEST + +/datum/keybinding/client/admin_help + hotkey_keys = list("F1") + name = "admin_help" + full_name = "Admin Help" + description = "Ask an admin for help." + +/datum/keybinding/client/admin_help/down(client/user) + user.get_adminhelp() + return TRUE + +/datum/keybinding/client/screenshot + hotkey_keys = list("F2") + name = "screenshot" + full_name = "Screenshot" + description = "Take a screenshot." + +/datum/keybinding/client/screenshot/down(client/user) + winset(user, null, "command=.screenshot [!user.keys_held["shift"] ? "auto" : ""]") + return TRUE + +/datum/keybinding/client/minimal_hud + hotkey_keys = list("F12") + name = "minimal_hud" + full_name = "Minimal HUD" + description = "Hide most HUD features" + +/datum/keybinding/client/minimal_hud/down(client/user) + user.mob.button_pressed_F12() + return TRUE diff --git a/code/modules/keybindings/keybind/emote.dm b/code/modules/keybindings/keybind/emote.dm new file mode 100644 index 0000000000..6099826819 --- /dev/null +++ b/code/modules/keybindings/keybind/emote.dm @@ -0,0 +1,15 @@ +/datum/keybinding/emote + category = CATEGORY_EMOTE + weight = WEIGHT_EMOTE + var/emote_key + +/datum/keybinding/emote/proc/link_to_emote(datum/emote/faketype) + hotkey_keys = list("Unbound") + emote_key = initial(faketype.key) + name = initial(faketype.key) + full_name = capitalize(initial(faketype.key)) + description = "Do the emote '*[emote_key]'" + +/datum/keybinding/emote/down(client/user) + . = ..() + return user.mob.emote(emote_key, intentional=TRUE) diff --git a/code/modules/keybindings/keybind/human.dm b/code/modules/keybindings/keybind/human.dm new file mode 100644 index 0000000000..43f5653472 --- /dev/null +++ b/code/modules/keybindings/keybind/human.dm @@ -0,0 +1,39 @@ +/datum/keybinding/human + category = CATEGORY_HUMAN + weight = WEIGHT_MOB + +/datum/keybinding/human/can_use(client/user) + return ishuman(user.mob) + +/datum/keybinding/human/quick_equip + hotkey_keys = list("E") + name = "quick_equip" + full_name = "Quick Equip" + description = "Quickly puts an item in the best slot available" + +/datum/keybinding/human/quick_equip/down(client/user) + var/mob/living/carbon/human/H = user.mob + H.quick_equip() + return TRUE + +/datum/keybinding/human/quick_equipbelt + hotkey_keys = list("ShiftE") + name = "quick_equipbelt" + full_name = "Quick equip belt" + description = "Put held thing in belt or take out most recent thing from belt" + +/datum/keybinding/human/quick_equipbelt/down(client/user) + var/mob/living/carbon/human/H = user.mob + H.smart_equipbelt() + return TRUE + +/datum/keybinding/human/bag_equip + hotkey_keys = list("ShiftB") + name = "bag_equip" + full_name = "Bag equip" + description = "Put held thing in backpack or take out most recent thing from backpack" + +/datum/keybinding/human/bag_equip/down(client/user) + var/mob/living/carbon/human/H = user.mob + H.smart_equipbag() + return TRUE diff --git a/code/modules/keybindings/keybind/living.dm b/code/modules/keybindings/keybind/living.dm new file mode 100644 index 0000000000..0408d0889b --- /dev/null +++ b/code/modules/keybindings/keybind/living.dm @@ -0,0 +1,41 @@ +/datum/keybinding/living + category = CATEGORY_HUMAN + weight = WEIGHT_MOB + +/datum/keybinding/living/can_use(client/user) + return isliving(user.mob) + +/datum/keybinding/living/resist + hotkey_keys = list("B") + name = "resist" + full_name = "Resist" + description = "Break free of your current state. Handcuffed? on fire? Resist!" + +/datum/keybinding/living/resist/down(client/user) + var/mob/living/L = user.mob + L.resist() + return TRUE + +/datum/keybinding/living/toggle_combat_mode + hotkey_keys = list("C") + name = "toggle_combat_mode" + full_name = "Toggle combat mode" + description = "Toggles whether or not you're in combat mode." + +/datum/keybinding/living/toggle_combat_mode/can_use(client/user) + return iscarbon(user.mob) // for now, only carbons should be using combat mode, although all livings have combat mode implemented. + +/datum/keybinding/living/toggle_combat_mode/down(client/user) + var/mob/living/carbon/C = user.mob + C.user_toggle_intentional_combat_mode() + return TRUE + +/datum/keybinding/living/toggle_resting + hotkey_keys = list("V") + name = "toggle_resting" + full_name = "Toggle Resting" + description = "Toggles whether or not you are intentionally laying down." + +/datum/keybinding/living/toggle_resting/down(client/user) + var/mob/living/L = user.mob + L.lay_down() diff --git a/code/modules/keybindings/keybind/mob.dm b/code/modules/keybindings/keybind/mob.dm new file mode 100644 index 0000000000..083d4a19fd --- /dev/null +++ b/code/modules/keybindings/keybind/mob.dm @@ -0,0 +1,123 @@ +/datum/keybinding/mob + category = CATEGORY_HUMAN + weight = WEIGHT_MOB + +/datum/keybinding/mob/stop_pulling + hotkey_keys = list("H", "Delete") + name = "stop_pulling" + full_name = "Stop pulling" + description = "" + +/datum/keybinding/mob/stop_pulling/down(client/user) + var/mob/M = user.mob + if(!M.pulling) + to_chat(user, "You are not pulling anything.") + else + M.stop_pulling() + return TRUE + +/datum/keybinding/mob/cycle_intent_right + hotkey_keys = list("Northwest", "F") // HOME + name = "cycle_intent_right" + full_name = "Cycle Action Intent Right" + description = "" + +/datum/keybinding/mob/cycle_intent_right/down(client/user) + var/mob/M = user.mob + M.a_intent_change(INTENT_HOTKEY_RIGHT) + return TRUE + +/datum/keybinding/mob/cycle_intent_left + hotkey_keys = list("Insert", "G") + name = "cycle_intent_left" + full_name = "Cycle Action Intent Left" + description = "" + +/datum/keybinding/mob/cycle_intent_left/down(client/user) + var/mob/M = user.mob + M.a_intent_change(INTENT_HOTKEY_LEFT) + return TRUE + +/datum/keybinding/mob/swap_hands + hotkey_keys = list("X", "Northeast") // PAGEUP + name = "swap_hands" + full_name = "Swap hands" + description = "" + +/datum/keybinding/mob/swap_hands/down(client/user) + var/mob/M = user.mob + M.swap_hand() + return TRUE + +/datum/keybinding/mob/activate_inhand + hotkey_keys = list("Z", "Southeast") // PAGEDOWN + name = "activate_inhand" + full_name = "Activate in-hand" + description = "Uses whatever item you have inhand" + +/datum/keybinding/mob/activate_inhand/down(client/user) + var/mob/M = user.mob + M.mode() + return TRUE + +/datum/keybinding/mob/drop_item + hotkey_keys = list("Q") + name = "drop_item" + full_name = "Drop Item" + description = "" + +/datum/keybinding/mob/drop_item/down(client/user) + if(iscyborg(user.mob)) //cyborgs can't drop items + return FALSE + var/mob/M = user.mob + var/obj/item/I = M.get_active_held_item() + if(!I) + to_chat(user, "You have nothing to drop in your hand!") + else + user.mob.dropItemToGround(I) + return TRUE + +/datum/keybinding/mob/say_with_indicator + hotkey_keys = list("CtrlT") + classic_keys = list() + name = "say_with_indicator" + full_name = "Say with Typing Indicator" + +/datum/keybinding/mob/say_with_indicator/down(client/user) + var/mob/M = user.mob + M.say_typing_indicator() + return TRUE + +/datum/keybinding/mob/me_with_indicator + hotkey_keys = list("CtrlM") + classic_keys = list() + name = "me_with_indicator" + full_name = "Me (emote) with Typing Indicator" + +/datum/keybinding/mob/me_with_indicator/down(client/user) + var/mob/M = user.mob + M.me_typing_indicator() + return TRUE + +/datum/keybinding/living/subtle + hotkey_keys = list("5") + classic_keys = list() + name = "subtle_emote" + full_name = "Subtle Emote" + +/datum/keybinding/living/subtle/down(client/user) + var/mob/living/L = user.mob + L.subtle_keybind() + return TRUE + +/datum/keybinding/mob/whisper + hotkey_keys = list("Y") + classic_keys = list() + name = "whisper" + full_name = "Whisper" + +/datum/keybinding/mob/whisper/down(client/user) + var/mob/M = user.mob + M.whisper_keybind() + return TRUE + diff --git a/code/modules/keybindings/keybind/movement.dm b/code/modules/keybindings/keybind/movement.dm new file mode 100644 index 0000000000..176e6b9fb8 --- /dev/null +++ b/code/modules/keybindings/keybind/movement.dm @@ -0,0 +1,187 @@ +/datum/keybinding/movement + category = CATEGORY_MOVEMENT + weight = WEIGHT_HIGHEST + +/datum/keybinding/movement/north + hotkey_keys = list("W", "North") + name = "North" + full_name = "Move North" + description = "Moves your character north" + +/datum/keybinding/movement/south + hotkey_keys = list("S", "South") + name = "South" + full_name = "Move South" + description = "Moves your character south" + +/datum/keybinding/movement/west + hotkey_keys = list("A", "West") + name = "West" + full_name = "Move West" + description = "Moves your character left" + +/datum/keybinding/movement/east + hotkey_keys = list("D", "East") + name = "East" + full_name = "Move East" + description = "Moves your character east" + +/datum/keybinding/mob/face_north + hotkey_keys = list("CtrlW", "CtrlNorth") + name = "face_north" + full_name = "Face North" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/face_north/down(client/user) + var/mob/M = user.mob + M.northface() + return TRUE + +/datum/keybinding/mob/face_east + hotkey_keys = list("CtrlD", "CtrlEast") + name = "face_east" + full_name = "Face East" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/face_east/down(client/user) + var/mob/M = user.mob + M.eastface() + return TRUE + +/datum/keybinding/mob/face_south + hotkey_keys = list("CtrlS", "CtrlSouth") + name = "face_south" + full_name = "Face South" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/face_south/down(client/user) + var/mob/M = user.mob + M.southface() + return TRUE + +/datum/keybinding/mob/face_west + hotkey_keys = list("CtrlA", "CtrlWest") + name = "face_west" + full_name = "Face West" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/face_west/down(client/user) + var/mob/M = user.mob + M.westface() + return TRUE + +/datum/keybinding/mob/shift_north + hotkey_keys = list("CtrlShiftW", "CtrlShiftNorth") + name = "pixel_shift_north" + full_name = "Pixel Shift North" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/shift_north/down(client/user) + var/mob/M = user.mob + M.northshift() + return TRUE + +/datum/keybinding/mob/shift_east + hotkey_keys = list("CtrlShiftD", "CtrlShiftEast") + name = "pixel_shift_east" + full_name = "Pixel Shift East" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/shift_east/down(client/user) + var/mob/M = user.mob + M.eastshift() + return TRUE + +/datum/keybinding/mob/shift_south + hotkey_keys = list("CtrlShiftS", "CtrlShiftSouth") + name = "pixel_shift_south" + full_name = "Pixel Shift South" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/shift_south/down(client/user) + var/mob/M = user.mob + M.southshift() + return TRUE + +/datum/keybinding/mob/shift_west + hotkey_keys = list("CtrlShiftA", "CtrlShiftWest") + name = "pixel_shift_west" + full_name = "Pixel Shift West" + description = "" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/shift_west/down(client/user) + var/mob/M = user.mob + M.westshift() + return TRUE + +/datum/keybinding/living/hold_sprint + hotkey_keys = list("Shift") + name = "hold_sprint" + full_name = "Sprint (hold down)" + description = "Hold down to sprint" + category = CATEGORY_MOVEMENT + +/datum/keybinding/living/hold_sprint/can_use(client/user) + return ishuman(user.mob) || iscyborg(user.mob) + +/datum/keybinding/living/hold_sprint/down(client/user) + var/mob/living/L = user.mob + L.sprint_hotkey(TRUE) + return TRUE + +/datum/keybinding/living/hold_sprint/up(client/user) + var/mob/living/L = user.mob + L.sprint_hotkey(FALSE) + return TRUE + +/datum/keybinding/living/toggle_sprint + hotkey_keys = list() + name = "toggle_sprint" + full_name = "Sprint (toggle)" + description = "Press to toggle sprint" + category = CATEGORY_MOVEMENT + +/datum/keybinding/living/toggle_sprint/can_use(client/user) + return ishuman(user.mob) || iscyborg(user.mob) + +/datum/keybinding/living/toggle_sprint/down(client/user) + var/mob/living/L = user.mob + L.default_toggle_sprint(TRUE) + return TRUE + +/datum/keybinding/mob/toggle_move_intent + hotkey_keys = list("Alt") + name = "toggle_move_intent" + full_name = "Hold to toggle move intent" + description = "Held down to cycle to the other move intent, release to cycle back" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/toggle_move_intent/down(client/user) + var/mob/M = user.mob + M.toggle_move_intent() + return TRUE + +/datum/keybinding/mob/toggle_move_intent/up(client/user) + var/mob/M = user.mob + M.toggle_move_intent() + return TRUE + +/datum/keybinding/mob/toggle_move_intent_alternative + hotkey_keys = list("Unbound") + name = "toggle_move_intent_alt" + full_name = "press to cycle move intent" + description = "Pressing this cycle to the opposite move intent, does not cycle back" + category = CATEGORY_MOVEMENT + +/datum/keybinding/mob/toggle_move_intent_alternative/down(client/user) + var/mob/M = user.mob + M.toggle_move_intent() + return TRUE diff --git a/code/modules/keybindings/keybind/robot.dm b/code/modules/keybindings/keybind/robot.dm new file mode 100644 index 0000000000..b9f6ce83eb --- /dev/null +++ b/code/modules/keybindings/keybind/robot.dm @@ -0,0 +1,61 @@ +/datum/keybinding/robot + category = CATEGORY_ROBOT + weight = WEIGHT_ROBOT + +/datum/keybinding/robot/can_use(client/user) + return iscyborg(user.mob) + +/datum/keybinding/robot/moduleone + hotkey_keys = list("1") + name = "module_one" + full_name = "Toggle module 1" + description = "Equips or unequips the first module" + +/datum/keybinding/robot/moduleone/down(client/user) + var/mob/living/silicon/robot/R = user.mob + R.toggle_module(1) + return TRUE + +/datum/keybinding/robot/moduletwo + hotkey_keys = list("2") + name = "module_two" + full_name = "Toggle module 2" + description = "Equips or unequips the second module" + +/datum/keybinding/robot/moduletwo/down(client/user) + var/mob/living/silicon/robot/R = user.mob + R.toggle_module(2) + return TRUE + +/datum/keybinding/robot/modulethree + hotkey_keys = list("3") + name = "module_three" + full_name = "Toggle module 3" + description = "Equips or unequips the third module" + +/datum/keybinding/robot/modulethree/down(client/user) + var/mob/living/silicon/robot/R = user.mob + R.toggle_module(3) + return TRUE + +/datum/keybinding/robot/intent_cycle + hotkey_keys = list("4") + name = "cycle_intent" + full_name = "Cycle intent left" + description = "Cycles the intent left" + +/datum/keybinding/robot/intent_cycle/down(client/user) + var/mob/living/silicon/robot/R = user.mob + R.a_intent_change(INTENT_HOTKEY_LEFT) + return TRUE + +/datum/keybinding/robot/unequip_module + hotkey_keys = list("Q") + name = "unequip_module" + full_name = "Unequip module" + description = "Unequips the active module" + +/datum/keybinding/robot/unequip_module/down(client/user) + var/mob/living/silicon/robot/R = user.mob + R.uneq_active() + return TRUE diff --git a/code/modules/keybindings/keybind/targeting.dm b/code/modules/keybindings/keybind/targeting.dm new file mode 100644 index 0000000000..1548d768cf --- /dev/null +++ b/code/modules/keybindings/keybind/targeting.dm @@ -0,0 +1,76 @@ +/datum/keybinding/mob/target_head_cycle + hotkey_keys = list("Numpad8") + name = "target_head_cycle" + full_name = "Target: Cycle head" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_head_cycle/down(client/user) + user.body_toggle_head() + return TRUE + +/datum/keybinding/mob/target_r_arm + hotkey_keys = list("Numpad4") + name = "target_r_arm" + full_name = "Target: right arm" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_r_arm/down(client/user) + user.body_r_arm() + return TRUE + +/datum/keybinding/mob/target_body_chest + hotkey_keys = list("Numpad5") + name = "target_body_chest" + full_name = "Target: Body" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_body_chest/down(client/user) + user.body_chest() + return TRUE + +/datum/keybinding/mob/target_left_arm + hotkey_keys = list("Numpad6") + name = "target_left_arm" + full_name = "Target: left arm" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_left_arm/down(client/user) + user.body_l_arm() + return TRUE + +/datum/keybinding/mob/target_right_leg + hotkey_keys = list("Numpad1") + name = "target_right_leg" + full_name = "Target: Right leg" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_right_leg/down(client/user) + user.body_r_leg() + return TRUE + +/datum/keybinding/mob/target_body_groin + hotkey_keys = list("Numpad2") + name = "target_body_groin" + full_name = "Target: Groin" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_body_groin/down(client/user) + user.body_groin() + return TRUE + +/datum/keybinding/mob/target_left_leg + hotkey_keys = list("Numpad3") + name = "target_left_leg" + full_name = "Target: left leg" + description = "" + category = CATEGORY_TARGETING + +/datum/keybinding/mob/target_left_leg/down(client/user) + user.body_l_leg() + return TRUE diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index 9a13bfb11c..a53820b5d2 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,55 +1,47 @@ -/client - /// Keys currently held - var/list/keys_held = list() - /// These next two vars are to apply movement for keypresses and releases made while move delayed. - /// Because discarding that input makes the game less responsive. - /// On next move, add this dir to the move that would otherwise be done - var/next_move_dir_add - /// On next move, subtract this dir from the move that would otherwise be done - var/next_move_dir_sub - -// Set a client's focus to an object and override these procs on that object to let it handle keypresses - /datum/proc/key_down(key, client/user) // Called when a key is pressed down initially return + /datum/proc/key_up(key, client/user) // Called when a key is released return + /datum/proc/keyLoop(client/user) // Called once every frame set waitfor = FALSE return // removes all the existing macros /client/proc/erase_all_macros() - var/list/macro_sets = params2list(winget(src, null, "macros")) var/erase_output = "" - for(var/i in 1 to macro_sets.len) - var/setname = macro_sets[i] - var/list/macro_set = params2list(winget(src, "[setname].*", "command")) // The third arg doesnt matter here as we're just removing them all - for(var/k in 1 to macro_set.len) - var/list/split_name = splittext(macro_set[k], ".") - var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command" - erase_output = "[erase_output];[macro_name].parent=null" + var/list/macro_set = params2list(winget(src, "default.*", "command")) // The third arg doesnt matter here as we're just removing them all + for(var/k in 1 to length(macro_set)) + var/list/split_name = splittext(macro_set[k], ".") + var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command" + erase_output = "[erase_output];[macro_name].parent=null" winset(src, null, erase_output) -/client/proc/set_macros() +/client/proc/apply_macro_set(name, list/macroset) + ASSERT(name) + ASSERT(islist(macroset)) + winclone(src, "default", name) + for(var/i in 1 to length(macroset)) + var/key = macroset[i] + var/command = macroset[key] + winset(src, "[name]-[REF(key)]", "parent=[name];name=[key];command=[command]") + +/client/proc/set_macros(datum/preferences/prefs_override = prefs) set waitfor = FALSE keys_held.Cut() erase_all_macros() - var/list/macro_sets = SSinput.macro_sets - for(var/i in 1 to macro_sets.len) - var/setname = macro_sets[i] - if(setname != "default") - winclone(src, "default", setname) - var/list/macro_set = macro_sets[setname] - for(var/k in 1 to macro_set.len) - var/key = macro_set[k] - var/command = macro_set[key] - winset(src, "[setname]-[REF(key)]", "parent=[setname];name=[key];command=[command]") + apply_macro_set(SKIN_MACROSET_HOTKEYS, SSinput.macroset_hotkey) + apply_macro_set(SKIN_MACROSET_CLASSIC_HOTKEYS, SSinput.macroset_classic_hotkey) + apply_macro_set(SKIN_MACROSET_CLASSIC_INPUT, SSinput.macroset_classic_input) - if(prefs.hotkeys) - winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default") + set_hotkeys_preference() + +/client/proc/set_hotkeys_preference(datum/preferences/prefs_override = prefs) + if(prefs_override.hotkeys) + winset(src, null, "map.focus=true input.background-color=[COLOR_INPUT_DISABLED] mainwindow.macro=[SKIN_MACROSET_HOTKEYS]") else - winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default") + winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=[SKIN_MACROSET_CLASSIC_INPUT]") diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index a45275e0c8..39f8e296af 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -16,7 +16,6 @@ resistance_flags = FIRE_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC - /obj/item/clothing/head/hooded/explorer name = "explorer hood" desc = "An armoured hood for exploring harsh environments." @@ -51,7 +50,7 @@ visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) - armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40) + armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40) resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) @@ -140,7 +139,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS hoodtype = /obj/item/clothing/head/hooded/explorer/seva - armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 25, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) + armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS /obj/item/clothing/head/hooded/explorer/seva @@ -149,7 +148,7 @@ icon_state = "seva" item_state = "seva" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 25, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) + armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS /obj/item/clothing/mask/gas/seva diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 9767ff3866..53ce676317 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -39,7 +39,7 @@ if(11) new /obj/item/ship_in_a_bottle(src) if(12) - new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src) + new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old(src) if(13) new /obj/item/jacobs_ladder(src) if(14) @@ -67,7 +67,7 @@ new /obj/item/grenade/clusterbuster/inferno(src) if(24) new /obj/item/reagent_containers/food/drinks/bottle/holywater/hell(src) - new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src) + new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old(src) if(25) new /obj/item/book/granter/spell/summonitem(src) if(26) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 988197f04f..dcaaffe487 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -193,9 +193,14 @@ return ..() /obj/machinery/mineral/equipment_vendor/proc/RedeemVoucher(obj/item/mining_voucher/voucher, mob/redeemer) - var/items = list("Survival Capsule and Explorer's Webbing", "Resonator Kit", "Minebot Kit", "Extraction and Rescue Kit", "Crusher Kit", "Mining Conscription Kit") + var/items = list( "Survival Capsule and Explorer's Webbing" = image(icon = 'icons/obj/storage.dmi', icon_state = "explorerpack"), + "Resonator Kit" = image(icon = 'icons/obj/mining.dmi', icon_state = "resonator"), + "Minebot Kit" = image(icon = 'icons/mob/aibots.dmi', icon_state = "mining_drone"), + "Extraction and Rescue Kit" = image(icon = 'icons/obj/fulton.dmi', icon_state = "extraction_pack"), + "Crusher Kit" = image(icon = 'icons/obj/mining.dmi', icon_state = "crusher"), + "Mining Conscription Kit" = image(icon = 'icons/obj/storage.dmi', icon_state = "duffel")) - var/selection = input(redeemer, "Pick your equipment", "Mining Voucher Redemption") as null|anything in items + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) return var/drop_location = drop_location() @@ -366,9 +371,10 @@ new /obj/item/clothing/glasses/meson/prescription(src) /obj/machinery/mineral/equipment_vendor/proc/RedeemSVoucher(obj/item/suit_voucher/voucher, mob/redeemer) - var/items = list("Exo-suit", "SEVA suit") + var/items = list( "Exo-suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "exo"), + "SEVA suit" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "seva")) - var/selection = input(redeemer, "Pick your suit.", "Suit Voucher Redemption") as null|anything in items + var/selection = show_radial_menu(redeemer, src, items, require_near = TRUE, tooltips = TRUE) if(!selection || !Adjacent(redeemer) || QDELETED(voucher) || voucher.loc != redeemer) return var/drop_location = drop_location() diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 0c8aef51a8..fb37dcbca0 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -24,7 +24,8 @@ environment_smash = ENVIRONMENT_SMASH_NONE check_friendly_fire = TRUE stop_automated_movement_when_pulled = TRUE - attacktext = "drills" + attack_verb_continuous = "drills" + attack_verb_simple = "drill" attack_sound = 'sound/weapons/circsawhit.ogg' sentience_type = SENTIENCE_MINEBOT speak_emote = list("states") diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index b54b990c77..f6b7110803 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -102,7 +102,22 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ /obj/item/stack/ore/glass/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(..() || !ishuman(hit_atom)) return - var/mob/living/carbon/human/C = hit_atom + var/mob/living/carbon/human/poorsod = hit_atom + eyesand(poorsod) + +/obj/item/stack/ore/glass/attack(mob/living/M, mob/living/user) + if(!ishuman(M)) + return ..() + if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD) + return ..() + var/mob/living/carbon/human/poorsod = M + visible_message("[user] throws the sand at [poorsod]'s face!") + if(ishuman(user)) + var/mob/living/carbon/human/sayer = user + sayer.forcesay("POCKET SAAND!!") + eyesand(poorsod) + +/obj/item/stack/ore/glass/proc/eyesand(mob/living/carbon/human/C) if(C.head && C.head.flags_cover & HEADCOVERSEYES) visible_message("[C]'s headgear blocks the sand!") return @@ -116,8 +131,10 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ C.adjustStaminaLoss(15)//the pain from your eyes burning does stamina damage C.confused += 5 to_chat(C, "\The [src] gets into your eyes! The pain, it burns!") + C.forcesay("*scream") qdel(src) + /obj/item/stack/ore/glass/ex_act(severity, target) if (severity == EXPLODE_NONE) return diff --git a/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm index cbb38a3a6a..2ec6da2da8 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/legs_and_taurs.dm @@ -64,6 +64,7 @@ taur_mode = STYLE_HOOF_TAURIC alt_taur_mode = STYLE_PAW_TAURIC color_src = MUTCOLORS + extra = TRUE /datum/sprite_accessory/taur/drake name = "Drake" @@ -72,6 +73,12 @@ color_src = MUTCOLORS extra = TRUE +/datum/sprite_accessory/taur/drake/old + name = "Drake (Old)" + icon_state = "drake_old" + color_src = MATRIXED + extra = FALSE + /datum/sprite_accessory/taur/drider name = "Drider" icon_state = "drider" diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm index 2bb0d6ba77..33dbd7059f 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -450,6 +450,18 @@ color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' +/datum/sprite_accessory/tails/human/tamamo_kitsune + name = "Tamamo Kitsune Tails" //Tamamo-no-Tiro, let it be known! + icon_state = "9sune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + +/datum/sprite_accessory/tails_animated/human/tamamo_kitsune + name = "Tamamo Kitsune Tails" + icon_state = "9sune" + color_src = MATRIXED + icon = 'modular_citadel/icons/mob/mam_tails.dmi' + /datum/sprite_accessory/tails/human/tentacle name = "Tentacle" icon_state = "tentacle" @@ -816,6 +828,14 @@ datum/sprite_accessory/mam_tails/insect name = "Squirrel" icon_state = "squirrel" +/datum/sprite_accessory/mam_tails/tamamo_kitsune + name = "Tamamo Kitsune Tails" + icon_state = "9sune" + +/datum/sprite_accessory/mam_tails_animated/tamamo_kitsune + name = "Tamamo Kitsune Tails" + icon_state = "9sune" + /datum/sprite_accessory/mam_tails/tentacle name = "Tentacle" icon_state = "tentacle" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index b8e56f3d7c..838de24b60 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -707,7 +707,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //this is a mob verb instead of atom for performance reasons //see /mob/verb/examinate() in mob.dm for more info //overridden here and in /mob/living for different point span classes and sanity checks -/mob/dead/observer/pointed(atom/A as mob|obj|turf in view()) +/mob/dead/observer/pointed(atom/A as mob|obj|turf in fov_view()) if(!..()) return 0 usr.visible_message("[src] points to [A].") diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index e8a9b50e98..3547d5f846 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -164,7 +164,7 @@ if(!B) return forceMove(B.loc) - src.client.eye = src + reset_perspective(src) src.visible_message("[src] rises out of the pool of blood!") exit_blood_effect(B) if(iscarbon(src)) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 4bca3e7f62..08d415fc3c 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -4,6 +4,7 @@ var/emp_damage = 0//Handles a type of MMI damage var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE. stat = DEAD //we start dead by default + has_field_of_vision = FALSE //Not really worth it. see_invisible = SEE_INVISIBLE_LIVING possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas speech_span = SPAN_ROBOT diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 90621ecd3f..6d3bf648f6 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -51,6 +51,12 @@ var/datum/brain_trauma/BT = X BT.owner = owner BT.on_gain() + if(damage > BRAIN_DAMAGE_MILD) + var/datum/skill_modifier/S + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, C, S) + if(damage > BRAIN_DAMAGE_SEVERE) + var/datum/skill_modifier/S + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, C, S) //Update the body's icon so it doesnt appear debrained anymore C.update_hair() @@ -66,6 +72,8 @@ if((!QDELETED(src) || C) && !no_id_transfer) transfer_identity(C) if(C) + REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, C) + REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, C) C.update_hair() /obj/item/organ/brain/prepare_eat() @@ -219,31 +227,6 @@ Insert(C) else ..() -/* TO BE REMOVED, KEPT IN CASE OF BUGS -/obj/item/organ/brain/proc/get_brain_damage() - var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER - var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold) - . = round((1 - (offset_integrity / brain_damage_threshold)) * BRAIN_DAMAGE_DEATH, DAMAGE_PRECISION) - -/obj/item/organ/brain/proc/adjust_brain_damage(amount, maximum) - var/adjusted_amount - if(amount >= 0 && maximum) - var/brainloss = get_brain_damage() - var/new_brainloss = clamp(brainloss + amount, 0, maximum) - if(brainloss > new_brainloss) //brainloss is over the cap already - return 0 - adjusted_amount = new_brainloss - brainloss - else - adjusted_amount = amount - - adjusted_amount = round(adjusted_amount * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER, DAMAGE_PRECISION) - if(adjusted_amount) - if(adjusted_amount >= DAMAGE_PRECISION) - take_damage(adjusted_amount) - else if(adjusted_amount <= -DAMAGE_PRECISION) - obj_integrity = min(max_integrity, obj_integrity-adjusted_amount) - . = adjusted_amount -*/ /obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth) . = ..() @@ -261,18 +244,28 @@ . = ..() //if we're not more injured than before, return without gambling for a trauma if(damage <= prev_damage) + if(damage < prev_damage && owner) + if(prev_damage > BRAIN_DAMAGE_MILD && damage <= BRAIN_DAMAGE_MILD) + REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner) + if(prev_damage > BRAIN_DAMAGE_SEVERE && damage <= BRAIN_DAMAGE_SEVERE) + REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner) return damage_delta = damage - prev_damage if(damage > BRAIN_DAMAGE_MILD) if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit gain_trauma_type(BRAIN_TRAUMA_MILD) + if(prev_damage <= BRAIN_DAMAGE_MILD && owner) + var/datum/skill_modifier/S + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner, S) if(damage > BRAIN_DAMAGE_SEVERE) if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% if(prob(20)) gain_trauma_type(BRAIN_TRAUMA_SPECIAL) else gain_trauma_type(BRAIN_TRAUMA_SEVERE) - + if(prev_damage <= BRAIN_DAMAGE_SEVERE && owner) + var/datum/skill_modifier/S + ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner, S) if (owner) if(owner.stat < UNCONSCIOUS) //conscious or soft-crit var/brain_message diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index a3600e6827..951185ee92 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -140,7 +140,8 @@ Des: Removes all infected images from the alien. /mob/living/carbon/alien/proc/alien_evolve(mob/living/carbon/alien/new_xeno) to_chat(src, "You begin to evolve!") - visible_message("[src] begins to twist and contort!") + visible_message("[src] begins to twist and contort!", + "You begin to twist and contort!") new_xeno.setDir(dir) if(!alien_name_regex.Find(name)) new_xeno.name = name diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index cdb8aff2c6..00ce3a320a 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -27,13 +27,16 @@ In all, this is a lot like the monkey code. /N AdjustUnconscious(-60, FALSE) AdjustSleeping(-100, FALSE) update_mobility() - visible_message("[M.name] nuzzles [src] trying to wake [p_them()] up!") + visible_message("[M.name] nuzzles [src] trying to wake [p_them()] up!", + "[M.name] nuzzles you trying to wake you up!", target = M, + target_message = "You nuzzle [src] trying to wake [p_them()] up!") if(INTENT_DISARM, INTENT_HARM) if(health > 0) M.do_attack_animation(src, ATTACK_EFFECT_BITE) playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ - "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) + "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE, null, M, + "You bite [src]!") adjustBruteLoss(1) log_combat(M, src, "attacked") updatehealth() diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index be81e850b7..3827aef8c1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -22,9 +22,9 @@ Doesn't work on other aliens/AI.*/ action = new(src) /obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE) - if(!skip_cost_check || !istype(user)) + if(!istype(user)) return TRUE - if(cost_check(check_turf,user)) + if(skip_cost_check || cost_check(check_turf,user)) if(fire(user) && user) // Second check to prevent runtimes when evolving user.adjustPlasma(-plasma_cost) return TRUE diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index c813ce40f0..11849641ef 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -25,6 +25,7 @@ /mob/living/carbon/alien/humanoid/Initialize() AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null)) . = ..() + AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3) /mob/living/carbon/alien/humanoid/restrained(ignore_grab) return handcuffed diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f694890b95..39179346f1 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -22,9 +22,6 @@ QDEL_NULL(dna) GLOB.carbon_list -= src -/mob/living/carbon/initialize_footstep() - AddComponent(/datum/component/footstep, 0.6, 2) - /mob/living/carbon/relaymove(mob/user, direction) if(user in src.stomach_contents) if(prob(40)) @@ -256,7 +253,8 @@ var/obj/item/ITEM = get_item_by_slot(slot) if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) visible_message("[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].", \ - "[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].") + "[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].", \ + target = usr, target_message = "You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].") if(do_mob(usr, src, POCKET_STRIP_DELAY)) if(internal) internal = null @@ -267,7 +265,8 @@ update_internals_hud_icon(1) visible_message("[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].", \ - "[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].") + "[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].", \ + target = usr, target_message = "You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].") /mob/living/carbon/fall(forced) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 9a4f905dd1..94589b3a4a 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -185,7 +185,8 @@ M.powerlevel = 0 visible_message("The [M.name] has shocked [src]!", \ - "The [M.name] has shocked [src]!") + "The [M.name] has shocked you!", target = M, + target_message = "You have shocked [src]!") do_sparks(5, TRUE, src) var/power = M.powerlevel + rand(0,3) @@ -234,38 +235,44 @@ var/obj/item/organ/O = X O.emp_act(severity) +///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects. /mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) - if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1)) - return FALSE - if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) - return FALSE - shock_damage *= siemens_coeff - if(dna && dna.species) - shock_damage *= dna.species.siemens_coeff - if(shock_damage < 1) - return 0 - if(reagents.has_reagent(/datum/reagent/teslium)) - shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging! - if((flags & SHOCK_ILLUSION)) - adjustStaminaLoss(shock_damage) - else - take_overall_damage(0,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." \ - ) - jitteriness += 1000 //High numbers for violent convulsions + . = ..() + if(!.) + return + //Propagation through pulling, fireman carry + if(!(flags & SHOCK_ILLUSION)) + var/list/shocking_queue = list() + if(iscarbon(pulling) && source != pulling) + shocking_queue += pulling + if(iscarbon(pulledby) && source != pulledby) + shocking_queue += pulledby + if(iscarbon(buckled) && source != buckled) + shocking_queue += buckled + for(var/mob/living/carbon/carried in buckled_mobs) + if(source != carried) + shocking_queue += carried + //Found our victims, now lets shock them all + for(var/victim in shocking_queue) + var/mob/living/carbon/C = victim + C.electrocute_act(shock_damage*0.75, src, 1, flags) + //Stun + var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN) + if(should_stun) + Stun(40) + //Jitter and other fluff. + jitteriness += 1000 do_jitter_animation(jitteriness) stuttering += 2 - if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)) - Stun(40) - spawn(20) - jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less - if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)) - DefaultCombatKnockdown(60) + addtimer(CALLBACK(src, .proc/secondary_shock, should_stun), 20) return shock_damage +///Called slightly after electrocute act to reduce jittering and apply a secondary stun. +/mob/living/carbon/proc/secondary_shock(should_stun) + jitteriness = max(jitteriness - 990, 10) + if(should_stun) + DefaultCombatKnockdown(60) + /mob/living/carbon/proc/help_shake_act(mob/living/carbon/M) if(on_fire) to_chat(M, "You can't put [p_them()] out with just your bare hands!") @@ -280,12 +287,14 @@ to_chat(M, "You need to unbuckle [src] first to do that!") return M.visible_message("[M] shakes [src] trying to get [p_them()] up!", \ - "You shake [src] trying to get [p_them()] up!") + "You shake [src] trying to get [p_them()] up!", target = src, + target_message = "[M] shakes you trying to get you up!") else if(M.zone_selected == BODY_ZONE_PRECISE_MOUTH) // I ADDED BOOP-EH-DEH-NOSEH - Jon M.visible_message( \ "[M] boops [src]'s nose.", \ - "You boop [src] on the nose.", ) + "You boop [src] on the nose.", target = src, + target_message = "[M] boops your nose.") playsound(src, 'sound/items/Nose_boop.ogg', 50, 0) else if(check_zone(M.zone_selected) == BODY_ZONE_HEAD) @@ -294,7 +303,8 @@ S = dna.species M.visible_message("[M] gives [src] a pat on the head to make [p_them()] feel better!", \ - "You give [src] a pat on the head to make [p_them()] feel better!") + "You give [src] a pat on the head to make [p_them()] feel better!", target = src, + target_message = "[M] gives you a pat on the head to make you feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat) friendly_check = TRUE if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail()) @@ -307,11 +317,13 @@ else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM) M.visible_message( \ "[M] shakes [src]'s hand.", \ - "You shake [src]'s hand.", ) + "You shake [src]'s hand.", target = src, + target_message = "[M] shakes your hand.") else M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \ - "You hug [src] to make [p_them()] feel better!") + "You hug [src] to make [p_them()] feel better!", target = src,\ + target_message = "[M] hugs you to make you feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug) friendly_check = TRUE @@ -433,3 +445,17 @@ var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS) if(istype(ears) && !ears.deaf) . = TRUE + +/mob/living/carbon/getBruteLoss_nonProsthetic() + var/amount = 0 + for(var/obj/item/bodypart/BP in bodyparts) + if (BP.status < 2) + amount += BP.brute_dam + return amount + +/mob/living/carbon/getFireLoss_nonProsthetic() + var/amount = 0 + for(var/obj/item/bodypart/BP in bodyparts) + if (BP.status < 2) + amount += BP.burn_dam + return amount diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index adca193ce0..5528669afa 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -63,7 +63,7 @@ /mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) - if (!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) + if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) return FALSE if(!forced && (status_flags & GODMODE)) return FALSE @@ -74,7 +74,7 @@ return amount /mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) - if (!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) //Vamps don't heal naturally. + if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) //Vamps don't heal naturally. return FALSE if(!forced && (status_flags & GODMODE)) return FALSE diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 60fa395319..4cf82bb0b4 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -25,7 +25,8 @@ if(M in stomach_contents) stomach_contents.Remove(M) M.forceMove(Tsec) - visible_message("[M] bursts out of [src]!") + M.visible_message("[M] bursts out of [src]!", + "You burst out of [src]!") ..() /mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts) diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm deleted file mode 100644 index a712240622..0000000000 --- a/code/modules/mob/living/carbon/give.dm +++ /dev/null @@ -1,58 +0,0 @@ -/mob/living/verb/give() - set category = "IC" - set name = "Give" - set src in oview(1) //Cannot handle giving shit to mobs on your own tile, but it's a small, small loss - - give_item(usr) - -/mob/living/proc/give_item(mob/living/carbon/user) - - -/mob/living/carbon/give_item(mob/living/carbon/user) - if(!istype(user)) - return - if(src.stat == 2 || user.stat == 2 || src.client == null) - return - if(src.handcuffed) - user << "Those hands are cuffed right now." - return //Can't receive items while cuffed - var/obj/item/I - if(user.get_active_held_item() == null) - user << "You don't have anything in your [get_held_index_name(get_held_index_of_item(I))] to give to [src]." - return - I = user.get_active_held_item() - if(!I) - return - if(src == user) //Shouldn't happen - user << "You tried to give yourself \the [I], but you didn't want it." - return - if(get_empty_held_index_for_side()) - switch(alert(src, "[user] wants to give you \a [I]?", , "Yes", "No")) - if("Yes") - if(!I) - return - if(!Adjacent(user)) - user <<"You need to stay still while giving an object." - src << "[user] moved away."//What an asshole - - return - if(user.get_active_held_item() != I) - user << "You need to keep the item in your hand." - src << "[user] has put \the [I] away!" - return - if(!get_empty_held_index_for_side()) - user << "Your hands are full." - user << "Their hands are full." - return - if(!user.dropItemToGround(I)) - src << "[user] can't let go of \the [I]!" - user << "You can't seem to let go of \the [I]." - return - - src.put_in_hands(I) - update_inv_hands() - src.visible_message("[user] handed \the [I] to [src].") - if("No") - src.visible_message("[user] tried to hand \the [I] to [src] but \he didn't want it.") - else - user << "[src]'s hands are full." diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ea91a90ee9..007bca3518 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -26,6 +26,7 @@ physiology = new() AddComponent(/datum/component/personal_crafting) + AddComponent(/datum/component/footstep, FOOTSTEP_MOB_HUMAN, 1, 2) . = ..() if(CONFIG_GET(flag/disable_stambuffer)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 856c57687f..3a2d0535e6 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -102,11 +102,15 @@ . = ..(user, TRUE) if(.) return - var/hulk_verb = pick("smash","pummel") + var/hulk_verb_continous = "smashes" + var/hulk_verb_simple = "smash" + if(prob(50)) + hulk_verb_continous = "pummels" + hulk_verb_simple = "pummel" playsound(loc, user.dna.species.attack_sound, 25, 1, -1) - var/message = "[user] has [hulk_verb]ed [src]!" - visible_message("[message]", \ - "[message]") + visible_message("[user] [hulk_verb_continous] [src]!", \ + "[user] [hulk_verb_continous] you!", null, COMBAT_MESSAGE_RANGE, null, user, + "You [hulk_verb_simple] [src]!") adjustBruteLoss(15) return 1 @@ -130,14 +134,16 @@ var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) - visible_message("[M] disarmed [src]!", \ - "[M] disarmed [src]!") + visible_message("[M] has disarmed [src]!", \ + "[M] has disarmed you!", null, COMBAT_MESSAGE_RANGE, null, M, + "You have disarmed [src]!") else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) DefaultCombatKnockdown(100) log_combat(M, src, "tackled") visible_message("[M] has tackled down [src]!", \ - "[M] has tackled down [src]!") + "[M] has tackled you down!", null, COMBAT_MESSAGE_RANGE, null, M, + "You have tackled [src] down!") if(M.limb_destroyer) dismembering_strike(M, affecting.body_zone) @@ -159,7 +165,8 @@ if(!damage) playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1) visible_message("[M] has lunged at [src]!", \ - "[M] has lunged at [src]!") + "[M] has lunged at you!", target = M, \ + target_message = "You have lunged at [src]!") return 0 var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) if(!affecting) @@ -168,7 +175,8 @@ playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ - "[M] has slashed at [src]!") + "[M] has slashed at you!", target = M, \ + target_message = "You have slashed at [src]!") log_combat(M, src, "attacked") if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful return 1 @@ -178,14 +186,16 @@ var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) - visible_message("[M] disarmed [src]!", \ - "[M] disarmed [src]!") + visible_message("[M] has disarmed [src]!", \ + "[M] has disarmed you!", target = M, \ + target_message = "You have disarmed [src]!") else playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) DefaultCombatKnockdown(M.meleeKnockdownPower) log_combat(M, src, "tackled") visible_message("[M] has tackled down [src]!", \ - "[M] has tackled down [src]!") + "[M] has tackled you down!", target = M, \ + target_message = "You have tackled down [src]!") /mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) . = ..() @@ -268,7 +278,8 @@ updatehealth() visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE) + "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, target = M, + target_message = "You have hit [src]!") log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") else @@ -348,40 +359,34 @@ apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) -//Added a safety check in case you want to shock a human mob directly through electrocute_act. +///Calculates the siemens coeff based on clothing and species, can also restart hearts. /mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) - if(flags & SHOCK_TESLA) - var/total_coeff = 1 - if(gloves) - var/obj/item/clothing/gloves/G = gloves - if(G.siemens_coefficient <= 0) - total_coeff -= 0.5 + //Calculates the siemens coeff based on clothing. Completely ignores the arguments + if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks + if(gloves && gloves.siemens_coefficient <= 0) + siemens_coeff -= 0.5 if(wear_suit) - var/obj/item/clothing/suit/S = wear_suit - if(S.siemens_coefficient <= 0) - total_coeff -= 0.95 - else if(S.siemens_coefficient == (-1)) - total_coeff -= 1 - siemens_coeff = total_coeff - if(flags_1 & TESLA_IGNORE_1) - siemens_coeff = 0 - else if(!(flags & SHOCK_NOGLOVES)) - var/gloves_siemens_coeff = 1 + if(wear_suit.siemens_coefficient == -1) + siemens_coeff -= 1 + else if(wear_suit.siemens_coefficient <= 0) + siemens_coeff -= 0.95 + siemens_coeff = max(siemens_coeff, 0) + else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks if(gloves) - var/obj/item/clothing/gloves/G = gloves - gloves_siemens_coeff = G.siemens_coefficient - siemens_coeff = gloves_siemens_coeff - if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION)) - if(shock_damage * siemens_coeff >= 1 && prob(25)) - var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART) - heart.beating = TRUE - if(stat == CONSCIOUS) - to_chat(src, "You feel your heart beating again!") + siemens_coeff *= gloves.siemens_coefficient siemens_coeff *= physiology.siemens_coeff . = ..() - if(.) - electrocution_animation(40) - + //Don't go further if the shock was blocked/too weak. + if(!.) + return + //Note we both check that the user is in cardiac arrest and can actually heartattack + //If they can't, they're missing their heart and this would runtime + if(undergoing_cardiac_arrest() && can_heartattack() && !(flags & SHOCK_ILLUSION)) + if(shock_damage * siemens_coeff >= 1 && prob(25)) + var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART) + if(heart.Restart() && stat == CONSCIOUS) + to_chat(src, "You feel your heart beating again!") + electrocution_animation(40) /mob/living/carbon/human/emp_act(severity) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index e0eec0e599..e7be540eb9 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -9,6 +9,7 @@ /// Enable stamina combat combat_flags = COMBAT_FLAGS_DEFAULT status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER + has_field_of_vision = FALSE //Handled by species. blocks_emissive = EMISSIVE_BLOCK_UNIQUE diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 580b0aaaf0..8de143e2bd 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -277,3 +277,65 @@ qdel(slot) for(var/obj/item/I in held_items) qdel(I) + +/mob/living/carbon/human/proc/smart_equipbag() // take most recent item out of bag or place held item in bag + if(incapacitated()) + return + var/obj/item/thing = get_active_held_item() + var/obj/item/equipped_back = get_item_by_slot(SLOT_BACK) + if(!equipped_back) // We also let you equip a backpack like this + if(!thing) + to_chat(src, "You have no backpack to take something out of!") + return + if(equip_to_slot_if_possible(thing, ITEM_SLOT_BACK)) + update_inv_hands() + return + if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item + if(!thing) + equipped_back.attack_hand(src) + else + to_chat(src, "You can't fit anything in!") + return + if(thing) // put thing in backpack + if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, src)) + to_chat(src, "You can't fit anything in!") + return + if(!equipped_back.contents.len) // nothing to take out + to_chat(src, "There's nothing in your backpack to take out!") + return + var/obj/item/stored = equipped_back.contents[equipped_back.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from backpack + return + +/mob/living/carbon/human/proc/smart_equipbelt() // put held thing in belt or take most recent item out of belt + if(incapacitated()) + return + var/obj/item/thing = get_active_held_item() + var/obj/item/equipped_belt = get_item_by_slot(SLOT_BELT) + if(!equipped_belt) // We also let you equip a belt like this + if(!thing) + to_chat(src, "You have no belt to take something out of!") + return + if(equip_to_slot_if_possible(thing, ITEM_SLOT_BELT)) + update_inv_hands() + return + if(!SEND_SIGNAL(equipped_belt, COMSIG_CONTAINS_STORAGE)) // not a storage item + if(!thing) + equipped_belt.attack_hand(src) + else + to_chat(src, "You can't fit anything in!") + return + if(thing) // put thing in belt + if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, src)) + to_chat(src, "You can't fit anything in!") + return + if(!equipped_belt.contents.len) // nothing to take out + to_chat(src, "There's nothing in your belt to take out!") + return + var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len] + if(!stored || stored.on_found(src)) + return + stored.attack_hand(src) // take out thing from belt + return diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm new file mode 100644 index 0000000000..a89921143a --- /dev/null +++ b/code/modules/mob/living/carbon/human/login.dm @@ -0,0 +1,4 @@ +/mob/living/carbon/human/Login() + ..() + if(dna?.species?.has_field_of_vision && CONFIG_GET(flag/use_field_of_vision)) + LoadComponent(/datum/component/field_of_vision, field_of_vision_type) diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm index 4d411deb53..fd0df0bde9 100644 --- a/code/modules/mob/living/carbon/human/physiology.dm +++ b/code/modules/mob/living/carbon/human/physiology.dm @@ -25,5 +25,8 @@ var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations. + /// footstep type override for both shoeless and not footstep sounds. + var/footstep_type + /datum/physiology/New() armor = new diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 51837498c8..5018b04cc4 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -10,6 +10,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows + var/has_field_of_vision = TRUE //Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner var/list/offset_features = list( @@ -104,6 +105,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both. var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths. + /// Our default override for typing indicator state + var/typing_indicator_state + /////////// // PROCS // /////////// @@ -328,6 +332,24 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]] + if(H.physiology) + if(mutant_bodyparts["taur"]) + var/datum/sprite_accessory/taur/T = GLOB.taur_list[H.dna.features["taur"]] + switch(T?.taur_mode) + if(STYLE_HOOF_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_SHOE + if(STYLE_PAW_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_CLAW + if(STYLE_SNEK_TAURIC) + H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL + else + H.physiology.footstep_type = null + else + H.physiology.footstep_type = null + + if(H.client && has_field_of_vision && CONFIG_GET(flag/use_field_of_vision)) + H.LoadComponent(/datum/component/field_of_vision, H.field_of_vision_type) + C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod) SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) @@ -363,6 +385,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) C.dna.mutation_index[new_species.inert_mutation] = create_sequence(new_species.inert_mutation) C.dna.default_mutation_genes[new_species.inert_mutation] = C.dna.mutation_index[new_species.inert_mutation] + if(!new_species.has_field_of_vision && has_field_of_vision && ishuman(C) && CONFIG_GET(flag/use_field_of_vision)) + var/datum/component/field_of_vision/F = C.GetComponent(/datum/component/field_of_vision) + if(F) + qdel(F) + SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) /datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour) @@ -1397,7 +1424,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(target.check_martial_melee_block()) - target.visible_message("[target] blocks [user]'s grab attempt!") + target.visible_message("[target] blocks [user]'s grab attempt!", target = user, \ + target_message = "[target] blocks your grab attempt!") return 0 if(attacker_style && attacker_style.grab_act(user,target)) return 1 @@ -1413,7 +1441,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) to_chat(user, "You're too exhausted.") //CITADEL CHANGE - ditto return FALSE //CITADEL CHANGE - ditto if(target.check_martial_melee_block()) - target.visible_message("[target] blocks [user]'s attack!") + target.visible_message("[target] blocks [user]'s attack!", target = user, \ + target_message = "[target] blocks your attack!") return FALSE if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount @@ -1468,8 +1497,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted playsound(target.loc, user.dna.species.miss_sound, 25, TRUE, -1) target.visible_message("[user]'s [atk_verb] misses [target]!", \ - "You avoid [user]'s [atk_verb]!", "You hear a swoosh!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "Your [atk_verb] misses [target]!") + "You avoid [user]'s [atk_verb]!", "You hear a swoosh!", null, COMBAT_MESSAGE_RANGE, null, \ + user, "Your [atk_verb] misses [target]!") log_combat(user, target, "attempted to punch") return FALSE @@ -1478,8 +1507,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) playsound(target.loc, user.dna.species.attack_sound, 25, 1, -1) - target.visible_message("[user] has [atk_verb]ed [target]!", \ - "[user] has [atk_verb]ed [target]!", null, COMBAT_MESSAGE_RANGE) + target.visible_message("[user] [atk_verb]s [target]!", \ + "[user] [atk_verb]s you!", null, COMBAT_MESSAGE_RANGE, null, \ + user, "You [atk_verb] [target]!") target.lastattacker = user.real_name target.lastattackerckey = user.ckey @@ -1501,8 +1531,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if((punchedstam > 50) && prob(punchedstam*0.5)) //If our punch victim has been hit above the threshold, and they have more than 50 stamina damage, roll for stun, probability of 1% per 2 stamina damage target.visible_message("[user] knocks [target] down!", \ - "You're knocked down by [user]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You knock [target] down!") + "You're knocked down by [user]!", + "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, null, + user, "You knock [target] down!") var/knockdown_duration = 40 + (punchedstam + (punchedbrute*0.5))*0.8 - armor_block target.DefaultCombatKnockdown(knockdown_duration) @@ -1534,7 +1565,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/target_aiming_for_groin = target.zone_selected == "groin" if(target.check_martial_melee_block()) //END EDIT - target.visible_message("[target] blocks [user]'s disarm attempt!") + target.visible_message("[target] blocks [user]'s disarm attempt!", target = user, \ + target_message = "[target] blocks your disarm attempt!") return FALSE if(IS_STAMCRIT(user)) to_chat(user, "You're too exhausted!") @@ -1543,11 +1575,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth)) playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) - user.visible_message(\ - "\The [user] slaps \the [target] in the face!",\ - "You slap [user == target ? "yourself" : "\the [target]"] in the face! ",\ - "You hear a slap." - ) + target.visible_message(\ + "\The [user] slaps [user == target ? "[user.p_them()]self" : "\the [target]"] in the face!",\ + "[user] slaps you in the face! ",\ + "You hear a slap.", target = user, target_message = "You slap [user == target ? "yourself" : "\the [target]"] in the face! ") user.do_attack_animation(target, ATTACK_EFFECT_FACE_SLAP) user.adjustStaminaLossBuffered(3) if (!HAS_TRAIT(target, TRAIT_PERMABONER)) @@ -1565,11 +1596,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if (!HAS_TRAIT(target, TRAIT_PERMABONER)) stop_wagging_tail(target) playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1) - user.visible_message(\ - "\The [user] slaps \the [target]'s ass!",\ - "You slap [user == target ? "your" : "\the [target]'s"] ass!",\ - "You hear a slap." - ) + target.visible_message(\ + "\The [user] slaps [user == target ? "[user.p_their()] own" : "\the [target]'s"] ass!",\ + "[user] slaps your ass! ",\ + "You hear a slap.", target = user, target_message = "You slap [user == target ? "your own" : "\the [target]'s"] ass! ") + return FALSE else @@ -1588,21 +1619,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) //var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) if(target.pulling == user) - target.visible_message("[user] wrestles out of [target]'s grip!") + target.visible_message("[user] wrestles out of [target]'s grip!", \ + "[user] wrestles out of your grip!", target = user, \ + target_message = "You wrestle out of [target]'s grip!") target.stop_pulling() playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) log_combat(user, target, "disarmed out of grab from") return - //var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) CIT CHANGE - comments this out to prevent compile errors due to the below commented out bit var/randn = rand(1, 100) - /*if(randn <= 25) CITADEL CHANGE - moves disarm push attempts to right click - playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - target.visible_message("[user] has pushed [target]!", - "[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE) - target.apply_effect(40, EFFECT_KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")) - target.forcesay(GLOB.hit_appends) - log_combat(user, target, "pushed over") - return*/ if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) // CITADEL CHANGE randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE @@ -1619,13 +1643,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing var/obj/item/I = null if(target.pulling) - target.visible_message("[user] has broken [target]'s grip on [target.pulling]!") + target.visible_message("[user] has broken [target]'s grip on [target.pulling]!", \ + "[user] has broken your grip on [target.pulling]!", target = user, \ + target_message = "You have broken [target]'s grip on [target.pulling]!") target.stop_pulling() else I = target.get_active_held_item() if(target.dropItemToGround(I)) target.visible_message("[user] has disarmed [target]!", \ - "[user] has disarmed [target]!", null, COMBAT_MESSAGE_RANGE) + "[user] has disarmed you!", null, COMBAT_MESSAGE_RANGE, null, \ + user, "You have disarmed [target]!") else I = null playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) @@ -1635,7 +1662,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) playsound(target, 'sound/weapons/punchmiss.ogg', 25, 1, -1) target.visible_message("[user] attempted to disarm [target]!", \ - "[user] attemped to disarm [target]!", null, COMBAT_MESSAGE_RANGE) + "[user] attemped to disarm [target]!", null, COMBAT_MESSAGE_RANGE, null, \ + user, "You attempted to disarm [target]!") log_combat(user, target, "attempted to disarm") @@ -1723,7 +1751,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20) if(H.stat == CONSCIOUS) H.visible_message("[H] has been knocked senseless!", \ - "[H] has been knocked senseless!") + "You have been knocked senseless!") H.confused = max(H.confused, 20) H.adjust_blurriness(10) if(prob(10)) @@ -1781,7 +1809,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) attacker_style = M.mind.martial_art if((M != H) && M.a_intent != INTENT_HELP && (H.mob_run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected, null) & BLOCK_SUCCESS)) log_combat(M, H, "attempted to touch") - H.visible_message("[M] attempted to touch [H]!") + H.visible_message("[M] attempted to touch [H]!", \ + "[M] attempted to touch you!", target = M, \ + target_message = "You attempted to touch [H]!") return TRUE switch(M.a_intent) if(INTENT_HELP) @@ -1818,7 +1848,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) to_chat(user, "You're too exhausted.") return FALSE if(target.check_martial_melee_block()) - target.visible_message("[target] blocks [user]'s shoving attempt!") + target.visible_message("[target] blocks [user]'s shoving attempt!", \ + "You block [user]'s shoving attempt!", target = user, \ + target_message = "[target] blocks your shoving attempt!") return FALSE if(attacker_style && attacker_style.disarm_act(user,target)) return TRUE @@ -1863,19 +1895,22 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND) if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest) target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_SOLID) - user.visible_message("[user.name] shoves [target.name], knocking them down!", - "You shove [target.name], knocking them down!", null, COMBAT_MESSAGE_RANGE) + target.visible_message("[user.name] shoves [target.name], knocking them down!", + "[user.name] shoves you, knocking you down!", null, COMBAT_MESSAGE_RANGE, null, + user, "You shove [target.name], knocking them down!") log_combat(user, target, "shoved", "knocking them down") else if(target_collateral_human && !targetatrest) target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_HUMAN) target_collateral_human.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_COLLATERAL) - user.visible_message("[user.name] shoves [target.name] into [target_collateral_human.name]!", - "You shove [target.name] into [target_collateral_human.name]!", null, COMBAT_MESSAGE_RANGE) + target.visible_message("[user.name] shoves [target.name] into [target_collateral_human.name]!", + "[user.name] shoves you into [target_collateral_human.name]!", null, COMBAT_MESSAGE_RANGE, null, + user, "You shove [target.name] into [target_collateral_human.name]!") append_message += ", into [target_collateral_human.name]" else - user.visible_message("[user.name] shoves [target.name]!", - "You shove [target.name]!", null, COMBAT_MESSAGE_RANGE) + target.visible_message("[user.name] shoves [target.name]!", + "[user.name] shoves you!", null, COMBAT_MESSAGE_RANGE, null, + user, "You shove [target.name]!") var/obj/item/target_held_item = target.get_active_held_item() if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) target_held_item = null diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index ef730da219..1d19f28aa8 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -13,6 +13,7 @@ blacklisted = TRUE limbs_id = "human" skinned_type = /obj/item/stack/sheet/animalhide/human + has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head. var/pumpkin = FALSE var/obj/item/dullahan_relay/myhead @@ -132,13 +133,13 @@ return INITIALIZE_HINT_QDEL owner = new_owner START_PROCESSING(SSobj, src) - RegisterSignal(owner, COMSIG_CLICK_SHIFT, .proc/examinate_check) + RegisterSignal(owner, COMSIG_MOB_CLICKED_SHIFT_ON, .proc/examinate_check) RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner) RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head) RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head) -/obj/item/dullahan_relay/proc/examinate_check(atom/source, mob/user) - if(user.client.eye == src) +/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/target) + if(source.client.eye == src) return COMPONENT_ALLOW_EXAMINATE /obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers) diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm index 5d9269b2f0..0a44891a70 100644 --- a/code/modules/mob/living/carbon/human/species_types/dwarves.dm +++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm @@ -33,12 +33,11 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // var/mob/living/carbon/human/H = C H.facial_hair_style = dwarf_hair H.update_hair() - H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM. + AddElement(/datum/element/dwarfism, COMSIG_SPECIES_LOSS, src) RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used. /datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species) . = ..() - H.transform = H.transform.Scale(1, 1.25) //And we undo it. UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used. //Dwarf Name stuff @@ -121,7 +120,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) // return //Filth Reactions - Since miasma now exists var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically. - for(var/fuck in view(owner,7)) //hello byond for view loop. + for(var/fuck in owner.fov_view(7)) //hello byond for view loop. if(istype(fuck, /mob/living/carbon/human)) var/mob/living/carbon/human/H = fuck if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH))) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 81132080ab..2b9d28a5f7 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -293,7 +293,7 @@ if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc light_amount = min(1,T.get_lumcount()) - 0.5 - H.adjust_nutrition(light_amount * 10, NUTRITION_LEVEL_FULL) + H.adjust_nutrition(light_amount * 4, NUTRITION_LEVEL_FULL) if(light_amount > 0.2) //if there's enough light, heal H.heal_overall_damage(1,1) H.adjustToxLoss(-1) diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index fd958ccc13..817498e417 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -13,7 +13,7 @@ disliked_food = MEAT | DAIRY liked_food = VEGETABLES | FRUIT | GRAIN species_language_holder = /datum/language_holder/sylvan - var/light_nutrition_gain_factor = 10 + var/light_nutrition_gain_factor = 4 var/light_toxheal = 1 var/light_oxyheal = 1 var/light_burnheal = 1 @@ -76,7 +76,7 @@ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS) mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs") limbs_id = "pod" - light_nutrition_gain_factor = 7.5 + light_nutrition_gain_factor = 3 light_bruteheal = 0.2 light_burnheal = 0.2 light_toxheal = 0.7 diff --git a/code/modules/mob/living/carbon/human/typing_indicator.dm b/code/modules/mob/living/carbon/human/typing_indicator.dm new file mode 100644 index 0000000000..16ed95790a --- /dev/null +++ b/code/modules/mob/living/carbon/human/typing_indicator.dm @@ -0,0 +1,2 @@ +/mob/living/carbon/human/get_typing_indicator_icon_state() + return dna?.species?.typing_indicator_state || ..() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 18c3fde188..5b91119789 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -45,6 +45,7 @@ /mob/living/carbon/monkey/ComponentInitialize() . = ..() AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD) + AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, 2) /mob/living/carbon/monkey/Destroy() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ced9fa3200..502ebcbe5d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -9,10 +9,6 @@ diag_hud.add_to_hud(src) faction += "[REF(src)]" GLOB.mob_living_list += src - initialize_footstep() - -/mob/living/proc/initialize_footstep() - AddComponent(/datum/component/footstep) /mob/living/prepare_huds() ..() @@ -46,7 +42,8 @@ return ..() /mob/living/proc/ZImpactDamage(turf/T, levels) - visible_message("[src] crashes into [T] with a sickening noise!") + visible_message("[src] crashes into [T] with a sickening noise!", \ + "You crash into [T] with a sickening noise!") adjustBruteLoss((levels * 5) ** 1.5) DefaultCombatKnockdown(levels * 50) @@ -124,7 +121,9 @@ to_chat(src, "You're too exhausted to crawl under [L].") return TRUE ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL) - visible_message("[src] is attempting to crawl under [L].", "You are now attempting to crawl under [L].") + visible_message("[src] is attempting to crawl under [L].", + "You are now attempting to crawl under [L].", + target = L, target_message = "[src] is attempting to crawl under you.") if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND)) DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL) return TRUE @@ -276,7 +275,9 @@ if(AM.pulledby) if(!supress_message) - visible_message("[src] has pulled [AM] from [AM.pulledby]'s grip.") + AM.pulledby.visible_message("[src] has pulled [AM] from [AM.pulledby]'s grip.", + "[src] has pulled [AM] from your grip.", target = src, + target_message = "You have pulled [AM] from [AM.pulledby]'s grip.") log_combat(AM, AM.pulledby, "pulled from", src) AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. @@ -291,7 +292,9 @@ log_combat(src, M, "grabbed", addition="passive grab") if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER))) - visible_message("[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!") //Cit change - And they thought ERP was bad. + visible_message("[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!", + "You have grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!", target = M, + target_message = "[src] has grabbed you[(zone_selected == "l_arm" || zone_selected == "r_arm")? " by your hands":" passively"]!") if(!iscarbon(src)) M.LAssailant = null else @@ -379,7 +382,7 @@ stop_pulling() //same as above -/mob/living/pointed(atom/A as mob|obj|turf in view()) +/mob/living/pointed(atom/A as mob|obj|turf in fov_view()) if(incapacitated()) return FALSE if(HAS_TRAIT(src, TRAIT_DEATHCOMA)) @@ -756,12 +759,16 @@ . = ..() if(pulledby.grab_state > GRAB_PASSIVE) if(CHECK_MOBILITY(src, MOBILITY_RESIST) && prob(30/pulledby.grab_state)) - visible_message("[src] has broken free of [pulledby]'s grip!") + pulledby.visible_message("[src] has broken free of [pulledby]'s grip!", + "[src] has broken free of your grip!", target = src, + target_message = "You have broken free of [pulledby]'s grip!") pulledby.stop_pulling() return TRUE else if(moving_resist && client) //we resisted by trying to move // this is a horrible system and whoever thought using client instead of mob is okay is not an okay person client.move_delay = world.time + 20 - visible_message("[src] resists against [pulledby]'s grip!") + pulledby.visible_message("[src] resists against [pulledby]'s grip!", + "[src] resists against your grip!", target = src, + target_message = "You resist against [pulledby]'s grip!") else pulledby.stop_pulling() return TRUE @@ -826,7 +833,8 @@ strip_silence = g.strip_silence if (!strip_silence) who.visible_message("[src] tries to remove [who]'s [what.name].", \ - "[src] tries to remove [who]'s [what.name].") + "[src] tries to remove your [what.name].", target = src, + target_message = "You try to remove [who]'s [what.name].") what.add_fingerprint(src) else to_chat(src,"You try to remove [who]'s [what.name].") @@ -874,7 +882,9 @@ to_chat(src, "\The [what.name] doesn't fit in that place!") return - visible_message("[src] tries to put [what] on [who].") + who.visible_message("[src] tries to put [what] on [who].", + "[src] tries to put [what] on you.", target = src, + target_message = "You try to put [what] on [who].") if(do_mob(src, who, what.equip_delay_other)) if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE, TRUE)) if(temporarilyRemoveItemFromInventory(what)) @@ -899,7 +909,7 @@ var/final_pixel_y = get_standard_pixel_y_offset(lying) animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2) - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life(). + floating_need_update = TRUE /mob/living/proc/get_temperature(datum/gas_mixture/environment) var/loc_temp = environment ? environment.temperature : T0C @@ -1058,7 +1068,7 @@ /mob/living/proc/IgniteMob() if(fire_stacks > 0 && !on_fire) on_fire = 1 - src.visible_message("[src] catches fire!", \ + visible_message("[src] catches fire!", \ "You're set on fire!") new/obj/effect/dummy/lighting_obj/moblight/fire(src) throw_alert("fire", /obj/screen/alert/fire) diff --git a/code/modules/mob/living/living_block.dm b/code/modules/mob/living/living_block.dm index 8156f83dbd..817863f257 100644 --- a/code/modules/mob/living/living_block.dm +++ b/code/modules/mob/living/living_block.dm @@ -85,7 +85,8 @@ if(. & BLOCK_SUCCESS) return if(prob(final_block_chance)) - owner.visible_message("[owner] blocks [attack_text] with [src]!") + owner.visible_message("[owner] blocks [attack_text] with [src]!", + "You block [attack_text] with [src]!") return . | BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL return . | BLOCK_NONE diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4cf6fc3694..17eb51b154 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -43,21 +43,21 @@ P.setAngle(SIMPLIFY_DEGREES(P.Angle + rand(120, 240))) if(!silent) visible_message("[P] gets deflected by [src]!", \ - "[P] gets deflected by [src]!") + "You deflect [P]!") if(REDIRECT_METHOD_REFLECT) P.setAngle(SIMPLIFY_DEGREES(P.Angle + 180)) if(!silent) visible_message("[P] gets reflected by [src]!", \ - "[P] gets reflected by [src]!") + "You reflect [P]!") if(REDIRECT_METHOD_PASSTHROUGH) if(!silent) visible_message("[P] passes through [src]!", \ - "[P] passes through [src]!") + "[P] passes through you!") return if(REDIRECT_METHOD_RETURN_TO_SENDER) if(!silent) visible_message("[src] deflects [P] back at their attacker!", \ - "[src] deflects [P] back at their attacker!") + "You deflect [P] back at your attacker!") if(P.firer) P.setAngle(Get_Angle(src, P.firer)) else @@ -141,7 +141,7 @@ playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg. if(!blocked) visible_message("[src] has been hit by [I].", \ - "[src] has been hit by [I].") + "You have been hit by [I].") var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) apply_damage(I.throwforce, dtype, impacting_zone, armor) if(I.thrownby) @@ -175,12 +175,15 @@ return updatehealth() visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE) + "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, null, + M.occupant, "You hit [src] with your [M.name]!") log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") else step_away(src,M) log_combat(M.occupant, src, "pushed", M) - visible_message("[M] pushes [src] out of the way.", null, null, 5) + visible_message("[M] pushes [src] out of the way.", \ + "[M] pushes you out of the way.", null, COMBAT_MESSAGE_RANGE, null, + M.occupant, "You push [src] out of the way with your [M.name].") /mob/living/fire_act() adjust_fire_stacks(3) @@ -224,7 +227,8 @@ var/old_grab_state = user.grab_state var/grab_upgrade_time = instant ? 0 : 30 visible_message("[user] starts to tighten [user.p_their()] grip on [src]!", \ - "[user] starts to tighten [user.p_their()] grip on you!") + "[user] starts to tighten [user.p_their()] grip on you!", target = user, + target_message = "You start to tighten your grip on [src]!") switch(user.grab_state) if(GRAB_AGGRESSIVE) log_combat(user, src, "attempted to neck grab", addition="neck grab") @@ -242,25 +246,29 @@ var/add_log = "" if(HAS_TRAIT(user, TRAIT_PACIFISM)) visible_message("[user] has firmly gripped [src]!", - "[user] has firmly gripped you!") + "[user] has firmly gripped you!", target = user, + target_message = "You have firmly gripped [src]!") add_log = " (pacifist)" else visible_message("[user] has grabbed [src] aggressively!", \ - "[user] has grabbed you aggressively!") + "[user] has grabbed you aggressively!", target = user, \ + target_message = "You have grabbed [src] aggressively!") update_mobility() stop_pulling() log_combat(user, src, "grabbed", addition="aggressive grab[add_log]") if(GRAB_NECK) log_combat(user, src, "grabbed", addition="neck grab") visible_message("[user] has grabbed [src] by the neck!",\ - "[user] has grabbed you by the neck!") + "[user] has grabbed you by the neck!", target = user, \ + target_message = "You have grabbed [src] by the neck!") update_mobility() //we fall down if(!buckled && !density) Move(user.loc) if(GRAB_KILL) log_combat(user, src, "strangled", addition="kill grab") visible_message("[user] is strangling [src]!", \ - "[user] is strangling you!") + "[user] is strangling you!", target = user, \ + target_message = "You are strangling [src]!") update_mobility() //we fall down if(!buckled && !density) Move(user.loc) @@ -272,7 +280,9 @@ SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user) if((user != src) && user.a_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)) log_combat(user, src, "attempted to touch") - visible_message("[user] attempted to touch [src]!") + visible_message("[user] attempted to touch [src]!", + "[user] attempted to touch you!", target = user, + target_message = "You attempted to touch [src]!") return TRUE /mob/living/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) @@ -310,13 +320,16 @@ log_combat(M, src, "attacked") M.do_attack_animation(src) visible_message("The [M.name] glomps [src]!", \ - "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE) + "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE, null, + M, "You glomp [src]!") return TRUE /mob/living/attack_animal(mob/living/simple_animal/M) M.face_atom(src) if(M.melee_damage_upper == 0) - M.visible_message("\The [M] [M.friendly] [src]!") + M.visible_message("\The [M] [M.friendly_verb_continuous] [src]!", + "You [M.friendly_verb_simple] [src]!", target = src, + target_message = "\The [M] [M.friendly_verb_continuous] you!") return FALSE else if(HAS_TRAIT(M, TRAIT_PACIFISM)) @@ -327,8 +340,9 @@ if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) M.do_attack_animation(src) - visible_message("\The [M] [M.attacktext] [src]!", \ - "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE) + visible_message("\The [M] [M.attack_verb_continuous] [src]!", \ + "\The [M] [M.attack_verb_continuous] you!", null, COMBAT_MESSAGE_RANGE, null, + M, "You [M.attack_verb_simple] [src]!") log_combat(M, src, "attacked") return TRUE @@ -347,17 +361,21 @@ log_combat(M, src, "attacked") playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) visible_message("[M.name] bites [src]!", \ - "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) + "[M.name] bites you!", null, COMBAT_MESSAGE_RANGE, null, + M, "You bite [src]!") return TRUE else visible_message("[M.name] has attempted to bite [src]!", \ - "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) + "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE, null, + M, "You have attempted to bite [src]!") return FALSE /mob/living/attack_larva(mob/living/carbon/alien/larva/L) switch(L.a_intent) if(INTENT_HELP) - visible_message("[L.name] rubs its head against [src].") + visible_message("[L.name] rubs its head against [src].", + "[L.name] rubs its head against you.", target = L, \ + target_message = "You rub your head against [src].") return FALSE else @@ -370,21 +388,26 @@ if(prob(90)) log_combat(L, src, "attacked") visible_message("[L.name] bites [src]!", \ - "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) + "[L.name] bites you!", null, COMBAT_MESSAGE_RANGE, null, L, \ + "You bite [src]!") playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) return TRUE else visible_message("[L.name] has attempted to bite [src]!", \ - "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE) + "[L.name] has attempted to bite you!", null, COMBAT_MESSAGE_RANGE, null, L, \ + "You have attempted to bite [src]!") /mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) if((M != src) && M.a_intent != INTENT_HELP && (mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)) - visible_message("[M] attempted to touch [src]!") + visible_message("[M] attempted to touch [src]!", + "[M] attempted to touch you!") return FALSE switch(M.a_intent) if (INTENT_HELP) if(!isalien(src)) //I know it's ugly, but the alien vs alien attack_alien behaviour is a bit different. - visible_message("[M] caresses [src] with its scythe like arm.") + visible_message("[M] caresses [src] with its scythe like arm.", + "[M] caresses you with its scythe like arm.", target = M, + target_message = "You caress [src] with your scythe like arm.") return FALSE if (INTENT_GRAB) grabbedby(M) @@ -412,21 +435,26 @@ take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1)) return 1 +///As the name suggests, this should be called to apply electric shocks. /mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags) - if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1)) + shock_damage *= siemens_coeff + if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE)) return FALSE if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) return FALSE - if(shock_damage > 0) - if(!(flags & SHOCK_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 + if(shock_damage < 1) + return FALSE + if(!(flags & SHOCK_ILLUSION)) + adjustFireLoss(shock_damage) + else + adjustStaminaLoss(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) . = ..() @@ -505,4 +533,11 @@ if(!used_item) used_item = get_active_held_item() ..() - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. + floating_need_update = TRUE + + +/mob/living/proc/getBruteLoss_nonProsthetic() + return getBruteLoss() + +/mob/living/proc/getFireLoss_nonProsthetic() + return getFireLoss() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 228028eb9b..f8abf94083 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -4,6 +4,9 @@ see_in_dark = 2 hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD,RAD_HUD) pressure_resistance = 10 + has_field_of_vision = TRUE + + typing_indicator_enabled = TRUE var/resize = 1 //Badminnery resize var/lastattacker = null diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 6a84162ea8..4b90191dcc 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -1,6 +1,8 @@ /mob/living/Moved() . = ..() update_turf_movespeed(loc) + //Hide typing indicator if we move. + clear_typing_indicator() if(is_shifted) is_shifted = FALSE pixel_x = get_standard_pixel_x_offset(lying) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index dff5584617..4e3093dda2 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -28,6 +28,7 @@ sec_hud = DATA_HUD_SECURITY_BASIC d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED mob_size = MOB_SIZE_LARGE + has_field_of_vision = FALSE //Vision through cameras. var/list/network = list("ss13") var/obj/machinery/camera/current var/list/connected_robots = list() @@ -868,30 +869,33 @@ light_cameras() if(istype(A, /obj/machinery/camera)) current = A - if(client) - if(ismovable(A)) - if(A != GLOB.ai_camera_room_landmark) - end_multicam() - client.perspective = EYE_PERSPECTIVE - client.eye = A - else + if(!client) + return + if(ismovable(A)) + if(A != GLOB.ai_camera_room_landmark) end_multicam() - if(isturf(loc)) - if(eyeobj) - client.eye = eyeobj - client.perspective = EYE_PERSPECTIVE - else - client.eye = client.mob - client.perspective = MOB_PERSPECTIVE - else + client.perspective = EYE_PERSPECTIVE + client.eye = A + else + end_multicam() + if(isturf(loc)) + if(eyeobj) + client.eye = eyeobj client.perspective = EYE_PERSPECTIVE - client.eye = loc - update_sight() - if(client.eye != src) - var/atom/AT = client.eye - AT.get_remote_view_fullscreens(src) + else + client.eye = client.mob + client.perspective = MOB_PERSPECTIVE else - clear_fullscreen("remote_view", 0) + client.perspective = EYE_PERSPECTIVE + client.eye = loc + update_sight() + if(client.eye != src) + var/atom/AT = client.eye + AT.get_remote_view_fullscreens(src) + else + clear_fullscreen("remote_view", 0) + SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE, A) + return TRUE /mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0) . = ..() diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index ba162ecf2c..dcb7ac66c9 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -32,22 +32,28 @@ /mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user) switch(user.a_intent) if(INTENT_HELP) - visible_message("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.") + visible_message("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.", + "[user] gently pats you on the head, eliciting an off-putting buzzing from your holographic field.", target = user, + target_message = "You gently pat [src] on the head, eliciting an off-putting buzzing from its holographic field.") if(INTENT_DISARM) - visible_message("[user] boops [src] on the head!") + visible_message("[user] boops [src] on the head!", + "[user] boops you on the head!", target = user, + target_message = "You boop [src] on the head!") if(INTENT_HARM) user.do_attack_animation(src) if (user.name == master) visible_message("Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.") - spawn(10) - fold_in() - if(user.put_in_hands(card)) - user.visible_message("[user] promptly scoops up [user.p_their()] pAI's card.") + fold_in() + if(user.put_in_hands(card)) + user.visible_message("[user] promptly scoops up [user.p_their()] pAI's card.", + "You promptly scoops up your pAI's card.") else if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, "You don't want to hurt [src]!") return - visible_message("[user] stomps on [src]!.") + visible_message("[user] stomps on [src]!.", + "[user] stomps on you!.", target = user, + target_message = "You stomp on [src]!.") take_holo_damage(2) else grabbedby(user) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 5750543a92..e337618e4b 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -32,15 +32,17 @@ var/obj/item/I = get_active_held_item() if(I) uneq_active() - visible_message("[M] disarmed [src]!", \ - "[M] has disabled [src]'s active module!", null, COMBAT_MESSAGE_RANGE) + visible_message("[M] has disarmed [src]!", \ + "[M] has disabled your active module!", null, COMBAT_MESSAGE_RANGE, null, M, + "You have disarmed [src]!") log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") else Paralyze(40) step(src,get_dir(M,src)) log_combat(M, src, "pushed") visible_message("[M] has forced back [src]!", \ - "[M] has forced back [src]!", null, COMBAT_MESSAGE_RANGE) + "[M] has forced you back!", null, COMBAT_MESSAGE_RANGE, null, M, + "You have forced back [src]!") playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) /mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M) diff --git a/code/modules/mob/living/silicon/robot/update_icons.dm b/code/modules/mob/living/silicon/robot/update_icons.dm index 72ad21c51e..a567446e9e 100644 --- a/code/modules/mob/living/silicon/robot/update_icons.dm +++ b/code/modules/mob/living/silicon/robot/update_icons.dm @@ -57,3 +57,5 @@ cut_overlays() else icon_state = "[module.cyborg_base_icon]" + + SEND_SIGNAL(src, COMSIG_ROBOT_UPDATE_ICONS) diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 94ce1e42fc..cd50ffbae6 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -17,7 +17,8 @@ log_combat(M, src, "attacked") playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ - "[M] has slashed at [src]!") + "[M] has slashed at you!", target = M, \ + target_message = "You have slashed at [src]!") if(prob(8)) flash_act(affect_silicon = 1) log_combat(M, src, "attacked") @@ -25,8 +26,9 @@ updatehealth() else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - visible_message("[M] took a swipe at [src]!", \ - "[M] took a swipe at [src]!") + visible_message("[M] take a swipe at [src]!", \ + "[M] take a swipe at you!", target = M, \ + target_message = "You take a swipe at [src]!") /mob/living/silicon/attack_animal(mob/living/simple_animal/M) . = ..() @@ -36,7 +38,8 @@ for(var/mob/living/N in buckled_mobs) N.DefaultCombatKnockdown(20) unbuckle_mob(N) - N.visible_message("[N] is knocked off of [src] by [M]!") + N.visible_message("[N] is knocked off of [src] by [M]!", + "You are knocked off of [src] by [M]!") switch(M.melee_damage_type) if(BRUTE) adjustBruteLoss(damage) @@ -62,7 +65,8 @@ adjustBruteLoss(rand(10, 15)) playsound(loc, "punch", 25, 1, -1) visible_message("[user] has punched [src]!", \ - "[user] has punched [src]!") + "[user] has punched you!", target = user, \ + target_message = "You have punched [src]!") return TRUE return FALSE @@ -73,14 +77,16 @@ switch(M.a_intent) if (INTENT_HELP) M.visible_message("[M] pets [src].", \ - "You pet [src].") + "You pet [src].", target = src, + target_message = "[M] pets you.") if(INTENT_GRAB) grabbedby(M) else M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) playsound(src.loc, 'sound/effects/bang.ogg', 10, 1) visible_message("[M] punches [src], but doesn't leave a dent.", \ - "[M] punches [src], but doesn't leave a dent.", null, COMBAT_MESSAGE_RANGE) + "[M] punches you, but doesn't leave a dent.", null, COMBAT_MESSAGE_RANGE, null, M, + "You punch [src], but don't leave a dent.") /mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M) if(M.a_intent == INTENT_HARM) @@ -109,7 +115,8 @@ if(prob(severity*50)) unbuckle_mob(M) M.DefaultCombatKnockdown(40) - M.visible_message("[M] is thrown off of [src]!") + M.visible_message("[M] is thrown off of [src]!", + "You are thrown off of [src]!") flash_act(affect_silicon = 1) /mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone) @@ -127,13 +134,15 @@ adjustBruteLoss(P.damage) if(prob(P.damage*1.5)) for(var/mob/living/M in buckled_mobs) - M.visible_message("[M] is knocked off of [src]!") + M.visible_message("[M] is knocked off of [src]!", + "You are knocked off of [src]!") unbuckle_mob(M) M.DefaultCombatKnockdown(40) if(P.stun || P.knockdown) for(var/mob/living/M in buckled_mobs) unbuckle_mob(M) - M.visible_message("[M] is knocked off of [src] by the [P]!") + M.visible_message("[M] is knocked off of [src] by the [P]!", + "You are knocked off of [src] by the [P]!") P.on_hit(src) return BULLET_ACT_HIT diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index fe18d48718..1e56e91ae1 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -7,7 +7,9 @@ switch(M.a_intent) if(INTENT_HELP) if (health > 0) - visible_message("[M] [response_help] [src].") + visible_message("[M] [response_help_continuous] [src].", \ + "[M] [response_help_continuous] you.", null, null, null, + M, "You [response_help_simple] [src].") playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if(INTENT_GRAB) @@ -16,13 +18,22 @@ else grabbedby(M) - if(INTENT_HARM, INTENT_DISARM) + if(INTENT_DISARM) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + visible_message("[M] [response_disarm_continuous] [src]!",\ + "[M] [response_disarm_continuous] you!", null, COMBAT_MESSAGE_RANGE, null, \ + M, "You [response_disarm_simple] [src]!") + playsound(src, 'sound/weapons/thudswoosh.ogg', 25, 1) + log_combat(M, src, "disarmed") + + if(INTENT_HARM) if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, "You don't want to hurt [src]!") return M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - visible_message("[M] [response_harm] [src]!",\ - "[M] [response_harm] [src]!", null, COMBAT_MESSAGE_RANGE) + visible_message("[M] [response_harm_continuous] [src]!",\ + "[M] [response_harm_continuous] you!", null, COMBAT_MESSAGE_RANGE, null, \ + M, "You [response_harm_simple] [src]!") playsound(loc, attacked_sound, 25, 1, -1) attack_threshold_check(harm_intent_damage) log_combat(M, src, "attacked") @@ -35,8 +46,9 @@ if(.) return playsound(loc, "punch", 25, 1, -1) - visible_message("[user] has punched [src]!", \ - "[user] has punched [src]!", null, COMBAT_MESSAGE_RANGE) + visible_message("[user] punches [src]!", \ + "[user] punches you!", null, COMBAT_MESSAGE_RANGE, null, \ + user, "You punch [src]!") adjustBruteLoss(15) return TRUE @@ -48,7 +60,9 @@ return 1 if (M.a_intent == INTENT_HELP) if (health > 0) - visible_message("[M.name] [response_help] [src].") + visible_message("[M.name] [response_help_continuous] [src].", \ + "[M.name] [response_help_continuous] you.", \ + target = M, target_message = "You [response_help_simple] [src].") playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) /mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M) @@ -57,12 +71,14 @@ return if(M.a_intent == INTENT_DISARM) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) - visible_message("[M] [response_disarm] [name]!", \ - "[M] [response_disarm] [name]!", null, COMBAT_MESSAGE_RANGE) + visible_message("[M] [response_disarm_continuous] [name]!", \ + "[M] [response_disarm_continuous] [name]!", null, COMBAT_MESSAGE_RANGE, null, \ + M, "You [response_disarm_simple] [name]!") log_combat(M, src, "disarmed") else visible_message("[M] has slashed at [src]!", \ - "[M] has slashed at [src]!", null, COMBAT_MESSAGE_RANGE) + "[M] has slashed at [src]!", null, COMBAT_MESSAGE_RANGE, null, \ + M, "[M] has slashed at [src]!") playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) attack_threshold_check(M.meleeSlashSAPower) log_combat(M, src, "attacked") @@ -102,7 +118,7 @@ temp_damage *= damage_coeff[damagetype] if(temp_damage >= 0 && temp_damage <= force_threshold) - visible_message("[src] looks unharmed.") + visible_message("[src] looks unharmed!") return FALSE else apply_damage(damage, damagetype, null, getarmor(null, armorcheck)) diff --git a/code/modules/mob/living/simple_animal/astral.dm b/code/modules/mob/living/simple_animal/astral.dm index ebc89e2577..48203b24b9 100644 --- a/code/modules/mob/living/simple_animal/astral.dm +++ b/code/modules/mob/living/simple_animal/astral.dm @@ -5,10 +5,15 @@ icon_state = "ghost" icon_living = "ghost" mob_biotypes = MOB_SPIRIT - attacktext = "raises the hairs on the neck of" - response_harm = "disrupts the concentration of" - response_disarm = "wafts" - friendly = "communes with" + has_field_of_vision = FALSE //we are a spoopy ghost + attack_verb_continuous = "raises the hair on the neck of" + attack_verb_simple = "raise the hair on the neck of" + response_harm_continuous = "disrupts the concentration of" + response_harm_simple = "disrupt the concentration of" + response_disarm_continuous = "wafts" + response_disarm_simple = "waft" + friendly_verb_continuous = "communes with" + friendly_verb_simple = "commute with" loot = null maxHealth = 10 health = 10 @@ -18,7 +23,6 @@ deathmessage = "disappears as if it was never really there to begin with" incorporeal_move = 1 alpha = 50 - attacktext = "touches the mind of" speak_emote = list("echos") movement_type = FLYING var/pseudo_death = FALSE @@ -32,7 +36,6 @@ /mob/living/simple_animal/astral/death() icon_state = "shade_dead" Stun(1000) - friendly = "deads at" pseudo_death = TRUE incorporeal_move = 0 to_chat(src, "Your astral projection is interrupted and your mind is sent back to your body with a shock!") diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index adb49938e1..73099d8d9f 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -20,9 +20,7 @@ weather_immunities = list("lava","ash") var/clean_time = 50 //How long do we take to clean? - var/broom = FALSE //Do we have an speed buff from a broom? - var/adv_mop = FALSE //Do we have a cleaning buff from a better mop? - + var/upgrades = 0 var/blood = 1 var/trash = 0 @@ -79,26 +77,38 @@ if(open) to_chat(user, "Please close the access panel before locking it.") else - to_chat(user, "\The [src] doesn't seem to respect your authority.") + to_chat(user, "The [src] doesn't seem to respect your authority.") - if(istype(W, /obj/item/mop/advanced)) - if(bot_core.allowed(user) && open && adv_mop == TRUE) + else if(istype(W, /obj/item/mop/advanced)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_ADVANCED_MOP)) to_chat(user, "You replace \the [src] old mop with a new better one!") - adv_mop = TRUE + upgrades |= UPGRADE_CLEANER_ADVANCED_MOP clean_time = 20 //2.5 the speed! window_name = "Automatic Station Cleaner v2.1 BETA" //New! qdel(W) + if(!open) + to_chat(user, "The [src] access pannle is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return else - to_chat(user, "\the [src] already has this mop!") + to_chat(user, "The [src] already has this mop!") - if(istype(W, /obj/item/twohanded/broom)) - if(bot_core.allowed(user) && open && broom == TRUE) + else if(istype(W, /obj/item/twohanded/broom)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_BROOM)) to_chat(user, "You add to \the [src] a broom speeding it up!") - broom = TRUE + upgrades |= UPGRADE_CLEANER_BROOM base_speed = 1 //2x faster! qdel(W) + if(!open) + to_chat(user, "The [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return else - to_chat(user, "\the [src] already has a broom!") + to_chat(user, "The [src] already has a broom!") else return ..() diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 469a395169..6febb942a1 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -44,8 +44,6 @@ var/cell_type = /obj/item/stock_parts/cell var/vest_type = /obj/item/clothing/suit/armor/vest - do_footstep = TRUE - /mob/living/simple_animal/bot/ed209/Initialize(mapload,created_name,created_lasercolor) . = ..() diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 1bf3883ea7..0f4608f48c 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -33,6 +33,8 @@ var/oldloc = null var/toolbox = /obj/item/storage/toolbox/mechanical + var/upgrades = 0 + #define HULL_BREACH 1 #define LINE_SPACE_MODE 2 #define FIX_TILE 3 @@ -120,6 +122,36 @@ to_chat(user, "You load [loaded] tiles into the floorbot. It now contains [specialtiles] tiles.") else to_chat(user, "You need at least one floor tile to put into [src]!") + + else if(istype(W, /obj/item/storage/toolbox/artistic)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_ARTBOX)) + to_chat(user, "You upgrade \the [src] case to hold more!") + upgrades |= UPGRADE_FLOOR_ARTBOX + maxtiles += 100 //Double the storage! + qdel(W) + if(!open) + to_chat(user, "The [src] access pannle is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has a upgraded case!") + + else if(istype(W, /obj/item/storage/toolbox/syndicate)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_SYNDIBOX)) + to_chat(user, "You upgrade \the [src] case to hold more!") + upgrades |= UPGRADE_FLOOR_SYNDIBOX + maxtiles += 200 //Double bse storage + base_speed = 1 //2x faster! + qdel(W) + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has a upgraded case!") + + else ..() diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index e4e81bb5db..7d93669c31 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -42,6 +42,7 @@ var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users. var/declare_cooldown = 0 //Prevents spam of critical patient alerts. var/stationary_mode = 0 //If enabled, the Medibot will not move automatically. + var/injection_time = 30 //How long we take to inject someone //Setting which reagents to use to treat what by default. By id. var/treatment_brute_avoid = /datum/reagent/medicine/tricordrazine var/treatment_brute = /datum/reagent/medicine/bicaridine @@ -51,19 +52,25 @@ var/treatment_fire = /datum/reagent/medicine/kelotane var/treatment_tox_avoid = /datum/reagent/medicine/tricordrazine var/treatment_tox = /datum/reagent/medicine/charcoal - var/treatment_tox_toxlover = /datum/reagent/toxin + var/treatment_tox_toxlover = /datum/reagent/toxin //Injects toxins into people that heal via toxins var/treatment_virus_avoid = null var/treatment_virus = /datum/reagent/medicine/spaceacillin var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) + var/upgrades = 0 + var/upgraded_dispenser_1 //Do we have the nicer chemicals? - replaces dex with salbutamol + var/upgraded_dispenser_2 //Do we have the nicer chemicals? - replaces kep with oxandrolone + var/upgraded_dispenser_3 //Do we have the nicer chemicals? - replaces bic with sal acid + var/upgraded_dispenser_4 //Do we have the nicer chemicals? - replaces charcoal/toxin with pentetic acid / pentetic jelly + /mob/living/simple_animal/bot/medbot/mysterious name = "\improper Mysterious Medibot" desc = "International Medibot of mystery." skin = "bezerk" - treatment_brute = /datum/reagent/medicine/tricordrazine - treatment_fire = /datum/reagent/medicine/tricordrazine - treatment_tox = /datum/reagent/medicine/tricordrazine + treatment_brute = /datum/reagent/medicine/regen_jelly + treatment_fire = /datum/reagent/medicine/regen_jelly + treatment_tox = /datum/reagent/medicine/regen_jelly /mob/living/simple_animal/bot/medbot/derelict name = "\improper Old Medibot" @@ -220,7 +227,6 @@ /mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/reagent_containers/glass)) - . = 1 //no afterattack if(locked) to_chat(user, "You cannot insert a beaker because the panel is locked!") return @@ -234,6 +240,97 @@ to_chat(user, "You insert [W].") show_controls(user) + else if(istype(W, /obj/item/reagent_containers/syringe/piercing)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) + to_chat(user, "You replace \the [src] syringe with a diamond-tipped one!") + upgrades |= UPGRADE_MEDICAL_PIERERCING + qdel(W) + if(!open) + to_chat(user, "The [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has a diamond-tipped syringe!") + + else if(istype(W, /obj/item/hypospray/mkii)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_HYPOSPRAY)) + to_chat(user, "You replace \the [src] syringe base with a DeForest Medical MK.II Hypospray!") + upgrades |= UPGRADE_MEDICAL_HYPOSPRAY + injection_time = 15 //Half the time half the death! + window_name = "Automatic Medical Unit v2.4 ALPHA" + qdel(W) + if(!open) + to_chat(user, "The [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has a DeForest Medical Hypospray base!") + + else if(istype(W, /obj/item/circuitboard/machine/chem_dispenser)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_BOARD)) + to_chat(user, "You add in the board upgrading \the [src] reagent banks!") + upgrades |= UPGRADE_MEDICAL_CHEM_BOARD + treatment_oxy = /datum/reagent/medicine/salbutamol //Replaces Dex with salbutamol "better" healing of o2 + qdel(W) + if(!open) + to_chat(user, "The [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has this upgrade!") + + else if(istype(W, /obj/item/circuitboard/machine/cryo_tube)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CRYO_BOARD)) + to_chat(user, "You add in the board upgrading \the [src] reagent banks!") + upgrades |= UPGRADE_MEDICAL_CRYO_BOARD + treatment_fire = /datum/reagent/medicine/oxandrolone //Replaces Kep with oxandrolone "better" healing of burns + qdel(W) + if(!open) + to_chat(user, "The [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has this upgrade!") + + else if(istype(W, /obj/item/circuitboard/machine/chem_master)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_MASTER)) + to_chat(user, "You add in the board upgrading \the [src] reagent banks!") + upgrades |= UPGRADE_MEDICAL_CHEM_MASTER + treatment_brute = /datum/reagent/medicine/sal_acid //Replaces Bic with Sal Acid "better" healing of brute + qdel(W) + if(!open) + to_chat(user, "the [src] access pannel is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "the [src] access pannel locked off to you!") + return + else + to_chat(user, "the [src] already has this upgrade!") + + else if(istype(W, /obj/item/circuitboard/machine/sleeper)) + if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_SLEEP_BOARD)) + to_chat(user, "You add in the board upgrading \the [src] reagent banks!") + upgrades |= UPGRADE_MEDICAL_SLEEP_BOARD + treatment_tox = /datum/reagent/medicine/pen_acid //replaces charcoal with pen acid a "better" healing of toxins + treatment_tox_toxlover = /datum/reagent/medicine/pen_acid/pen_jelly //Injects pen jelly into people that heal via toxins + qdel(W) + if(!open) + to_chat(user, "The [src] access pannle is not open!") + return + if(!bot_core.allowed(user)) + to_chat(user, "The [src] access pannel locked off to you!") + return + else + to_chat(user, "The [src] already has this upgrade!") + else var/current_health = health ..() @@ -249,6 +346,8 @@ audible_message("[src] buzzes oddly!") flick("medibot_spark", src) playsound(src, "sparks", 75, 1) + if(!CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) + upgrades |= UPGRADE_MEDICAL_PIERERCING //Jabs even harder through the clothing! if(user) oldpatient = user @@ -361,7 +460,7 @@ if(ishuman(C)) var/mob/living/carbon/human/H = C - if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing)) + if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing) && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING)) var/obj/item/clothing/CS = H.wear_suit var/obj/item/clothing/CH = H.head if (CS.clothing_flags & CH.clothing_flags & THICKMATERIAL) @@ -418,7 +517,7 @@ else ..() -/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view()) +/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in fov_view()) ..() if(!is_blind(src)) chemscan(src, A) @@ -504,7 +603,7 @@ "[src] is trying to inject you!") var/failed = FALSE - if(do_mob(src, patient, 30)) //Is C == patient? This is so confusing + if(do_mob(src, patient, injection_time)) //Is C == patient? This is so confusing if((get_dist(src, patient) <= 1) && (on) && assess_patient(patient)) if(reagent_id == "internal_beaker") if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 674cc722d8..354bc9ed0f 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -5,9 +5,12 @@ gender = NEUTER mob_biotypes = NONE speak_emote = list("hisses") - response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" + response_help_continuous = "thinks better of touching" + response_help_simple = "think better of touching" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" threat = 1 speak_chance = 1 icon = 'icons/mob/mob.dmi' @@ -122,12 +125,14 @@ threat = 3 maxHealth = 150 health = 150 - response_harm = "harmlessly punches" + response_harm_continuous = "harmlessly punches" + response_harm_simple = "harmlessly punch" harm_intent_damage = 0 obj_damage = 90 melee_damage_lower = 25 melee_damage_upper = 25 - attacktext = "smashes their armored gauntlet into" + attack_verb_continuous = "smashes their armored gauntlet into" + attack_verb_simple = "smash your armored gauntlet into" speed = 2.5 environment_smash = ENVIRONMENT_SMASH_WALLS attack_sound = 'sound/weapons/punch3.ogg' @@ -188,7 +193,8 @@ melee_damage_lower = 20 melee_damage_upper = 20 retreat_distance = 2 //AI wraiths will move in and out of combat - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift) runetype = /datum/action/innate/cult/create_rune/tele @@ -232,14 +238,16 @@ icon_living = "artificer" maxHealth = 50 health = 50 - response_harm = "viciously beats" + response_harm_continuous = "viciously beats" + response_harm_simple = "viciously beat" harm_intent_damage = 5 obj_damage = 60 melee_damage_lower = 5 melee_damage_upper = 5 retreat_distance = 10 minimum_distance = 10 //AI artificers will flee like fuck - attacktext = "rams" + attack_verb_continuous = "rams" + attack_verb_simple = "ram" environment_smash = ENVIRONMENT_SMASH_WALLS attack_sound = 'sound/weapons/punch2.ogg' construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall, @@ -319,7 +327,8 @@ sight = SEE_MOBS melee_damage_lower = 15 melee_damage_upper = 20 - attacktext = "butchers" + attack_verb_continuous = "butchers" + attack_verb_simple = "butcher" attack_sound = 'sound/weapons/bladeslice.ogg' construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/area_conversion, /obj/effect/proc_holder/spell/targeted/forcewall/cult) diff --git a/code/modules/mob/living/simple_animal/friendly/bumbles.dm b/code/modules/mob/living/simple_animal/friendly/bumbles.dm index 1a78a47031..2d236a4327 100644 --- a/code/modules/mob/living/simple_animal/friendly/bumbles.dm +++ b/code/modules/mob/living/simple_animal/friendly/bumbles.dm @@ -5,14 +5,18 @@ icon_living = "bumbles" icon_dead = "bumbles_dead" turns_per_move = 1 - response_help = "pets" - response_disarm = "brushes aside" - response_harm = "squashes" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "brushes aside" + response_help_simple = "brush aside" + response_harm_continuous = "squashes" + response_harm_simple = "squash" speak_emote = list("buzzes") maxHealth = 100 health = 100 harm_intent_damage = 1 - friendly = "bzzs" + friendly_verb_continuous = "bzzs" + friendly_verb_simple = "bzz" density = FALSE movement_type = FLYING pass_flags = PASSTABLE | PASSGRILLE | PASSMOB diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm index 80fba5a9a4..bf4f45e283 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -5,14 +5,18 @@ icon_living = "butterfly" icon_dead = "butterfly_dead" turns_per_move = 1 - response_help = "shoos" - response_disarm = "brushes aside" - response_harm = "squashes" + response_help_continuous = "shoos" + response_help_simple = "shoo" + response_disarm_continuous = "brushes aside" + response_disarm_simple = "brush aside" + response_harm_continuous = "squashes" + response_harm_simple = "squash" speak_emote = list("flutters") maxHealth = 2 health = 2 harm_intent_damage = 1 - friendly = "nudges" + friendly_verb_continuous = "nudges" + friendly_verb_simple = "nudge" density = FALSE movement_type = FLYING pass_flags = PASSTABLE | PASSGRILLE | PASSMOB diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 7d41068020..5f7ff198e2 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -24,15 +24,18 @@ animal_species = /mob/living/simple_animal/pet/cat childtype = list(/mob/living/simple_animal/pet/cat/kitten) butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" var/turns_since_scan = 0 var/mob/living/simple_animal/mouse/movement_target gold_core_spawnable = FRIENDLY_SPAWN collar_type = "cat" var/held_icon = "cat2" - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/pet/cat/Initialize() . = ..() @@ -245,7 +248,8 @@ harm_intent_damage = 10 butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \ /obj/item/reagent_containers/food/snacks/meat/slab = 2) - response_harm = "takes a bite out of" + response_harm_continuous = "takes a bite out of" + response_harm_simple = "take a bite out of" attacked_sound = 'sound/items/eatfood.ogg' deathmessage = "loses its false life and collapses!" death_sound = "bodyfall" @@ -306,7 +310,6 @@ if (pseudo_death == TRUE) //secret cat chem icon_state = "custom_cat_dead" Stun(1000) - friendly = "deads at" return else ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm index 95aa86aaab..9a34f2c176 100644 --- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -14,9 +14,12 @@ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY mob_biotypes = MOB_ORGANIC|MOB_BUG - response_help = "pokes" - response_disarm = "shoos" - response_harm = "splats" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "splats" + response_harm_simple = "splat" speak_emote = list("chitters") density = FALSE ventcrawler = VENTCRAWLER_ALWAYS diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index cce5edc513..d86362c974 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -12,11 +12,15 @@ speak_chance = 1 turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 4) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "stomps" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "stomps" + response_harm_continuous = "stomp" stop_automated_movement = 1 - friendly = "pinches" + friendly_verb_continuous = "pinches" + friendly_verb_simple = "pinch" ventcrawler = VENTCRAWLER_ALWAYS var/obj/item/inventory_head var/obj/item/inventory_mask @@ -41,9 +45,6 @@ real_name = "Coffee" desc = "It's Coffee, the other pet!" gender = FEMALE - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "stomps" gold_core_spawnable = NO_SPAWN /mob/living/simple_animal/crab/evil @@ -53,9 +54,10 @@ icon_state = "evilcrab" icon_living = "evilcrab" icon_dead = "evilcrab_dead" - response_help = "pokes" - response_disarm = "shoves" - response_harm = "stomps" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "shoves" + response_disarm_simple = "shove" gold_core_spawnable = HOSTILE_SPAWN /mob/living/simple_animal/crab/kreb @@ -65,9 +67,6 @@ icon_state = "kreb" icon_living = "kreb" icon_dead = "kreb_dead" - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "stomps" gold_core_spawnable = NO_SPAWN /mob/living/simple_animal/crab/evil/kreb diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 485cece8b7..57a4ecc5c9 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -2,9 +2,12 @@ /mob/living/simple_animal/pet/dog mob_biotypes = MOB_ORGANIC|MOB_BEAST - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "bops" + response_disarm_simple = "bop" + response_harm_continuous = "kicks" + response_harm_simple = "kick" speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") speak_emote = list("barks", "woofs") emote_hear = list("barks!", "woofs!", "yaps.","pants.") @@ -15,7 +18,7 @@ turns_per_move = 10 var/held_icon = "corgi" - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/pet/dog/ComponentInitialize() . = ..() @@ -332,9 +335,6 @@ desc = "It's the HoP's beloved corgi." var/turns_since_scan = 0 var/obj/movement_target - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" gold_core_spawnable = NO_SPAWN unique_pet = TRUE var/age = 0 @@ -604,9 +604,6 @@ icon_state = "lisa" icon_living = "lisa" icon_dead = "lisa_dead" - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" var/turns_since_scan = 0 var/puppies = 0 held_icon = "lisa" 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 e67e649ac6..59fa94a1fa 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -13,13 +13,17 @@ turns_per_move = 5 see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 4) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" faction = list("neutral") mob_biotypes = MOB_ORGANIC|MOB_BEAST attack_same = 1 - attacktext = "kicks" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" attack_sound = 'sound/weapons/punch1.ogg' health = 40 maxHealth = 40 @@ -30,7 +34,7 @@ blood_volume = BLOOD_VOLUME_NORMAL var/obj/item/udder/udder = null - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/retaliate/goat/Initialize() udder = new() @@ -121,10 +125,14 @@ turns_per_move = 5 see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 6) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - attacktext = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" attack_sound = 'sound/weapons/punch1.ogg' health = 50 maxHealth = 50 @@ -132,7 +140,7 @@ gold_core_spawnable = FRIENDLY_SPAWN blood_volume = BLOOD_VOLUME_NORMAL - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/cow/Initialize() udder = new() @@ -198,10 +206,14 @@ speak_chance = 2 turns_per_move = 2 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 1) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - attacktext = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" health = 3 maxHealth = 3 ventcrawler = VENTCRAWLER_ALWAYS @@ -210,7 +222,7 @@ mob_size = MOB_SIZE_TINY gold_core_spawnable = FRIENDLY_SPAWN - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/chick/Initialize() . = ..() @@ -249,10 +261,14 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 2) var/egg_type = /obj/item/reagent_containers/food/snacks/egg var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - attacktext = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" health = 15 maxHealth = 15 ventcrawler = VENTCRAWLER_ALWAYS @@ -268,7 +284,7 @@ gold_core_spawnable = FRIENDLY_SPAWN var/static/chicken_count = 0 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/chicken/Initialize() . = ..() @@ -342,10 +358,14 @@ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - attacktext = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" health = 25 maxHealth = 25 ventcrawler = VENTCRAWLER_ALWAYS @@ -358,6 +378,8 @@ gold_core_spawnable = FRIENDLY_SPAWN var/static/kiwi_count = 0 + footstep_type = FOOTSTEP_MOB_CLAW + /mob/living/simple_animal/kiwi/Destroy() --kiwi_count return ..() @@ -418,10 +440,14 @@ speak_chance = 2 turns_per_move = 2 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - attacktext = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" health = 10 maxHealth = 10 ventcrawler = VENTCRAWLER_ALWAYS @@ -430,6 +456,8 @@ mob_size = MOB_SIZE_TINY gold_core_spawnable = FRIENDLY_SPAWN + footstep_type = FOOTSTEP_MOB_CLAW + /mob/living/simple_animal/babyKiwi/Initialize() . = ..() pixel_x = rand(-6, 6) diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 95b082b733..4e4fd7ccfc 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -14,11 +14,14 @@ turns_per_move = 5 see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" gold_core_spawnable = FRIENDLY_SPAWN - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/pet/fox/ComponentInitialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/gondola.dm b/code/modules/mob/living/simple_animal/friendly/gondola.dm index 04d53e7d05..0cfea3548b 100644 --- a/code/modules/mob/living/simple_animal/friendly/gondola.dm +++ b/code/modules/mob/living/simple_animal/friendly/gondola.dm @@ -9,9 +9,12 @@ name = "gondola" real_name = "gondola" desc = "Gondola is the silent walker. Having no hands he embodies the Taoist principle of wu-wei (non-action) while his smiling facial expression shows his utter and complete acceptance of the world as it is. Its hide is extremely valuable." - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "bops" + response_disarm_simple = "bop" + response_harm_continuous = "kicks" + response_harm_simple = "kick" faction = list("gondola") turns_per_move = 10 icon = 'icons/mob/gondolas.dmi' diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index 9ae46f29e5..b9ff99b677 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -8,12 +8,16 @@ health = 5 maxHealth = 5 faction = list("Lizard") - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" melee_damage_lower = 1 melee_damage_upper = 2 - response_help = "pets" - response_disarm = "shoos" - response_harm = "stomps on" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "stomps on" + response_harm_simple = "stomp on" ventcrawler = VENTCRAWLER_ALWAYS density = FALSE pass_flags = PASSTABLE | PASSMOB diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 7f83bb9f9b..50d1e44d2a 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -15,9 +15,12 @@ maxHealth = 5 health = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "splats" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "splats" + response_harm_simple = "splat" density = FALSE ventcrawler = VENTCRAWLER_ALWAYS pass_flags = PASSTABLE | PASSGRILLE | PASSMOB @@ -103,9 +106,6 @@ GLOBAL_VAR(tom_existed) /mob/living/simple_animal/mouse/brown/Tom name = "Tom" desc = "Jerry the cat is not amused." - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "splats" gold_core_spawnable = NO_SPAWN /mob/living/simple_animal/mouse/brown/Tom/Initialize() diff --git a/code/modules/mob/living/simple_animal/friendly/panda.dm b/code/modules/mob/living/simple_animal/friendly/panda.dm index a7b6143ef5..7e523fea83 100644 --- a/code/modules/mob/living/simple_animal/friendly/panda.dm +++ b/code/modules/mob/living/simple_animal/friendly/panda.dm @@ -13,8 +13,11 @@ turns_per_move = 5 see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" gold_core_spawnable = FRIENDLY_SPAWN - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm index 9835840dbf..f92f4184b7 100644 --- a/code/modules/mob/living/simple_animal/friendly/penguin.dm +++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm @@ -1,9 +1,12 @@ //Penguins /mob/living/simple_animal/pet/penguin - response_help = "pets" - response_disarm = "bops" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "bops" + response_disarm_simple = "bop" + response_harm_continuous = "kicks" + response_harm_simple = "kick" speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!") speak_emote = list("squawks", "gakkers") emote_hear = list("squawk!", "gakkers!", "noots.","NOOTS!") @@ -15,7 +18,7 @@ turns_per_move = 10 icon = 'icons/mob/penguins.dmi' - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_BAREFOOT /mob/living/simple_animal/pet/penguin/emperor name = "Emperor penguin" diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm index 28063d6e52..83fe42a7a4 100644 --- a/code/modules/mob/living/simple_animal/friendly/sloth.dm +++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm @@ -11,9 +11,12 @@ speak_chance = 1 turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" mob_biotypes = MOB_ORGANIC|MOB_BEAST gold_core_spawnable = FRIENDLY_SPAWN melee_damage_lower = 18 @@ -22,7 +25,7 @@ maxHealth = 50 speed = 10 glide_size = 2 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/pet/fox/ComponentInitialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/snake.dm b/code/modules/mob/living/simple_animal/friendly/snake.dm index 7f75888649..4d20b927a6 100644 --- a/code/modules/mob/living/simple_animal/friendly/snake.dm +++ b/code/modules/mob/living/simple_animal/friendly/snake.dm @@ -19,12 +19,16 @@ speak_emote = list("hisses") health = 20 maxHealth = 20 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" melee_damage_lower = 5 melee_damage_upper = 6 - response_help = "pets" - response_disarm = "shoos" - response_harm = "steps on" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "steps on" + response_harm_simple = "step on" faction = list("hostile") ventcrawler = VENTCRAWLER_ALWAYS density = FALSE diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index d2794a3a78..9d94992747 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -13,9 +13,12 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians gender = NEUTER mob_biotypes = NONE bubble_icon = "guardian" - response_help = "passes through" - response_disarm = "flails at" - response_harm = "punches" + response_help_continuous = "passes through" + response_help_simple = "pass through" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" icon = 'icons/mob/guardian.dmi' icon_state = "magicbase" icon_living = "magicbase" @@ -29,7 +32,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians 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 maxbodytemp = INFINITY - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" maxHealth = INFINITY //The spirit itself is invincible health = INFINITY healable = FALSE //don't brusepack the guardian @@ -109,7 +113,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians icon_dead = "holocarp" speak_emote = list("gnashes") desc = "A mysterious fish that stands by its charge, ever vigilant." - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' recolorentiresprite = TRUE if(!recolorentiresprite) //we want this to proc before stand logs in, so the overlay isnt gone for some reason diff --git a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm index e507a4c831..e82d6cd16a 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/assassin.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/assassin.dm @@ -1,6 +1,7 @@ //Assassin /mob/living/simple_animal/hostile/guardian/assassin - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) playstyle_string = "As an assassin type you do medium damage and have no damage resistance, but can enter stealth, massively increasing the damage of your next attack and causing it to ignore armor. Stealth is broken when you attack or take damage." diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index 718bfd71af..97003a53e2 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -4,7 +4,8 @@ melee_damage_lower = 10 melee_damage_upper = 10 attack_sound = 'sound/items/welder.ogg' - attacktext = "ignites" + attack_verb_continuous = "ignites" + attack_verb_simple = "ignite" melee_damage_type = BURN damage_coeff = list(BRUTE = 0.7, BURN = 0.1, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) playstyle_string = "As a chaos type, you take 30% damage reduction to all but burn, which you are almost immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you." diff --git a/code/modules/mob/living/simple_animal/guardian/types/lightning.dm b/code/modules/mob/living/simple_animal/guardian/types/lightning.dm index 7b7651822a..a1552f6648 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/lightning.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/lightning.dm @@ -6,7 +6,8 @@ /mob/living/simple_animal/hostile/guardian/beam melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "shocks" + attack_verb_continuous = "shocks" + attack_verb_simple = "shock" melee_damage_type = BURN attack_sound = 'sound/machines/defib_zap.ogg' damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) diff --git a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm index 539ee9081b..1746936ba3 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm @@ -8,7 +8,8 @@ /mob/living/simple_animal/hostile/guardian/ranged a_intent = INTENT_HELP - friendly = "quietly assesses" + friendly_verb_continuous = "quietly assesses" + friendly_verb_simple = "quietly assess" melee_damage_lower = 10 melee_damage_upper = 10 damage_coeff = list(BRUTE = 0.9, BURN = 0.9, TOX = 0.9, CLONE = 0.9, STAMINA = 0, OXY = 0.9) diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 7b519e1ca1..21460b5c6b 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -1,7 +1,8 @@ //Healer /mob/living/simple_animal/hostile/guardian/healer a_intent = INTENT_HARM - friendly = "heals" + friendly_verb_continuous = "heals" + friendly_verb_simple = "heal" damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) playstyle_string = "As a support type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay." magic_fluff_string = "..And draw the CMO, a potent force of life... and death." diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 2045e194d2..7120ab6d0a 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -8,9 +8,12 @@ icon_gib = "syndicate_gib" gender = FEMALE threat = 1 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "shoves" + response_disarm_simple = "shove" + response_harm_continuous = "hits" + response_harm_simple = "hit" speed = 0 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 4, /obj/item/stack/sheet/animalhide/xeno = 1) @@ -20,7 +23,8 @@ obj_damage = 60 melee_damage_lower = 25 melee_damage_upper = 25 - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" speak_emote = list("hisses") bubble_icon = "alien" a_intent = INTENT_HARM @@ -37,7 +41,9 @@ death_sound = 'sound/voice/hiss6.ogg' deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..." - do_footstep = TRUE +/mob/living/simple_animal/hostile/alien/Initialize() + . = ..() + AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW) /mob/living/simple_animal/hostile/alien/drone name = "alien drone" @@ -80,6 +86,7 @@ icon_state = "alienq" icon_living = "alienq" icon_dead = "alienq_dead" + pixel_x = -16 threat = 8 health = 250 maxHealth = 250 @@ -162,7 +169,8 @@ melee_damage_upper = 0 threat = -1 a_intent = INTENT_HELP - friendly = "caresses" + friendly_verb_continuous = "caresses" + friendly_verb_simple = "caress" obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE gold_core_spawnable = HOSTILE_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm index f3ce343bfd..259c0bc721 100644 --- a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm @@ -13,14 +13,16 @@ maxbodytemp = INFINITY pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY - response_help = "pokes" - response_disarm = "shoos" - response_harm = "splats" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "splats" + response_harm_simple = "plat" speak_emote = list("chitters") mouse_opacity = 2 density = TRUE ventcrawler = VENTCRAWLER_ALWAYS - gold_core_spawnable = FRIENDLY_SPAWN verb_say = "chitters" verb_ask = "chitters inquisitively" verb_exclaim = "chitters loudly" diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index a77098cb80..0e864a1e37 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -17,9 +17,12 @@ turns_per_move = 5 see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" maxHealth = 60 health = 60 spacewalk = TRUE @@ -28,9 +31,11 @@ obj_damage = 60 melee_damage_lower = 20 melee_damage_upper = 30 - attacktext = "claws" + attack_verb_continuous = "claws" + attack_verb_simple = "claw" attack_sound = 'sound/weapons/bladeslice.ogg' - friendly = "bear hugs" + friendly_verb_continuous = "bear hugs" + friendly_verb_simple = "bear hug" //Space bears aren't affected by cold. 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) @@ -40,7 +45,7 @@ faction = list("russian") gold_core_spawnable = HOSTILE_SPAWN - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW //SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!! /mob/living/simple_animal/hostile/bear/Hudson @@ -111,12 +116,14 @@ mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Seve melee_damage_lower = 1 melee_damage_upper = 1 armour_penetration = 0 - response_harm = "takes a bite out of" + response_harm_continuous = "takes a bite out of" + response_harm_simple = "take a bite out of" attacked_sound = 'sound/items/eatfood.ogg' deathmessage = "loses its false life and collapses!" butcher_results = list(/obj/item/reagent_containers/food/snacks/butter = 6, /obj/item/reagent_containers/food/snacks/meat/slab = 3, /obj/item/organ/brain = 1, /obj/item/organ/heart = 1) attack_sound = 'sound/weapons/slap.ogg' - attacktext = "slaps" + attack_verb_continuous = "slaps" + attack_verb_simple = "slap" /mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage. if(stat) diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index f5454933c8..5f3d4f11c1 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -23,10 +23,14 @@ turns_per_move = 0 melee_damage_lower = 1 melee_damage_upper = 1 - attacktext = "stings" - response_help = "shoos" - response_disarm = "swats away" - response_harm = "squashes" + attack_verb_continuous = "stings" + attack_verb_simple = "sting" + response_help_continuous = "shoos" + response_help_simple = "shoo" + response_disarm_continuous = "swats away" + response_disarm_simple = "swat away" + response_harm_continuous = "squashes" + response_harm_simple = "squash" maxHealth = 10 health = 10 spacewalk = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm index dbb957a96b..b1a4f05e8c 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm @@ -7,6 +7,7 @@ status_flags = 0 a_intent = INTENT_HARM gender = NEUTER + has_field_of_vision = FALSE //You are a frikkin boss var/list/boss_abilities = list() //list of /datum/action/boss var/datum/boss_active_timed_battle/atb var/point_regen_delay = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm index 07572fff83..aef3fb714d 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm @@ -23,7 +23,7 @@ attack_sound = 'sound/hallucinations/growl1.ogg' var/list/copies = list() - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE //Summon Ability diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index ced56f0705..a56a8dcc29 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -12,9 +12,10 @@ speak_chance = 0 turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" emote_taunt = list("gnashes") taunt_chance = 30 speed = 0 @@ -25,7 +26,8 @@ obj_damage = 50 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' speak_emote = list("gnashes") //Space carp aren't affected by cold. diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm index 4e3375caf7..d85f75cbbd 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -8,9 +8,6 @@ icon_gib = "syndicate_gib" speak_chance = 0 turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" speed = 0 stat_attack = UNCONSCIOUS robust_searching = 1 @@ -19,7 +16,8 @@ harm_intent_damage = 5 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "slashes at" + attack_verb_continuous = "slashes at" + attack_verb_simple = "slash at" attack_sound = 'sound/weapons/circsawhit.ogg' a_intent = INTENT_HARM mob_biotypes = MOB_ORGANIC|MOB_HUMANOID diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm deleted file mode 100644 index bba37f94af..0000000000 --- a/code/modules/mob/living/simple_animal/hostile/creature.dm +++ /dev/null @@ -1,18 +0,0 @@ -/mob/living/simple_animal/hostile/creature - name = "creature" - desc = "A sanity-destroying otherthing." - icon_state = "otherthing" - icon_living = "otherthing" - icon_dead = "otherthing-dead" - health = 80 - maxHealth = 80 - obj_damage = 100 - melee_damage_lower = 25 - melee_damage_upper = 50 - attacktext = "chomps" - attack_sound = 'sound/weapons/bite.ogg' - faction = list("creature") - speak_emote = list("screams") - gold_core_spawnable = HOSTILE_SPAWN - 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 diff --git a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm index 6ca6eac0cc..48266e3e76 100644 --- a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm @@ -17,7 +17,8 @@ obj_damage = 20 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "staves" + attack_verb_continuous = "staves" + attack_verb_simple = "stave" a_intent = INTENT_HARM speak_emote = list("chants") attack_sound = 'sound/weapons/bladeslice.ogg' @@ -25,7 +26,7 @@ turns_per_move = 5 gold_core_spawnable = HOSTILE_SPAWN faction = list(ROLE_WIZARD) - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE weather_immunities = list("lava","ash") minbodytemp = 0 maxbodytemp = INFINITY diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index dbb9048ca4..75e8c55236 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -8,9 +8,10 @@ icon_gib = "" gender = NEUTER mob_biotypes = MOB_ORGANIC - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" emote_taunt = list("glares") taunt_chance = 25 maxHealth = 45 @@ -21,9 +22,11 @@ obj_damage = 60 melee_damage_lower = 20 melee_damage_upper = 25 - attacktext = "blinks at" + attack_verb_continuous = "blinks at" + attack_verb_simple = "blink at" attack_sound = 'sound/weapons/pierce.ogg' movement_type = FLYING faction = list("spooky") del_on_death = 1 + field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball. diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 7ac0ea2b44..4f8d2fef6c 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -9,9 +9,12 @@ gender = MALE speak_chance = 0 turns_per_move = 5 - response_help = "passes through" - response_disarm = "shoves" - response_harm = "hits" + response_help_continuous = "passes through" + response_help_simple = "pass through" + response_disarm_continuous = "shoves" + response_disarm_simple = "shove" + response_harm_continuous = "hits" + response_harm_simple = "hit" emote_taunt = list("wails") taunt_chance = 25 speed = 0 @@ -26,7 +29,8 @@ obj_damage = 50 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "grips" + attack_verb_continuous = "grips" + attack_verb_simple = "grip" attack_sound = 'sound/hallucinations/growl1.ogg' speak_emote = list("growls") @@ -36,7 +40,7 @@ faction = list("faithless") gold_core_spawnable = HOSTILE_SPAWN - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/faithless/AttackingTarget() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index f19aa0a2a7..a253ecfd96 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -30,9 +30,12 @@ turns_per_move = 5 see_in_dark = 10 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/spider = 2, /obj/item/reagent_containers/food/snacks/spiderleg = 8) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" maxHealth = 200 health = 200 obj_damage = 60 @@ -43,18 +46,19 @@ pass_flags = PASSTABLE move_to_delay = 6 ventcrawler = VENTCRAWLER_ALWAYS - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' unique_name = 1 gold_core_spawnable = HOSTILE_SPAWN see_in_dark = 4 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + footstep_type = FOOTSTEP_MOB_CLAW + has_field_of_vision = FALSE // 360° vision. var/playable_spider = FALSE var/datum/action/innate/spider/lay_web/lay_web var/directive = "" //Message passed down to children, to relay the creator's orders - do_footstep = TRUE - /mob/living/simple_animal/hostile/poison/giant_spider/Initialize() . = ..() lay_web = new diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm index db232c20c4..1dcb13aa9b 100644 --- a/code/modules/mob/living/simple_animal/hostile/goose.dm +++ b/code/modules/mob/living/simple_animal/hostile/goose.dm @@ -10,9 +10,12 @@ speak_chance = 0 turns_per_move = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" emote_taunt = list("hisses") taunt_chance = 30 speed = 0 @@ -21,7 +24,8 @@ harm_intent_damage = 5 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "pecks" + attack_verb_continuous = "pecks" + attack_verb_simple = "peck" attack_sound = "goose" speak_emote = list("honks") faction = list("neutral") diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm index 7c6f9e9c7b..f48eef083b 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm @@ -16,16 +16,20 @@ health = 220 loot = list(/obj/effect/gibspawner/generic) butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/gorilla = 4) - response_help = "prods" - response_disarm = "challenges" - response_harm = "thumps" + response_help_continuous = "prods" + response_help_simple = "prod" + response_disarm_continuous = "challenges" + response_disarm_simple = "challenge" + response_harm_continuous = "thumps" + response_harm_simple = "thump" speed = 1 melee_damage_lower = 15 melee_damage_upper = 18 damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, CLONE = 0, STAMINA = 0, OXY = 1.5) obj_damage = 20 environment_smash = ENVIRONMENT_SMASH_WALLS - attacktext = "pummels" + attack_verb_continuous = "pummels" + attack_verb_simple = "pummel" attack_sound = 'sound/weapons/punch1.ogg' dextrous = TRUE held_items = list(null, null) @@ -39,7 +43,7 @@ var/list/gorilla_overlays[GORILLA_TOTAL_LAYERS] var/oogas = 0 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_BAREFOOT // Gorillas like to dismember limbs from unconcious mobs. // Returns null when the target is not an unconcious carbon mob; a list of limbs (possibly empty) otherwise. diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 9d64b76198..501534237a 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -12,7 +12,8 @@ maxHealth = 50 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/weapons/bite.ogg' faction = list("creature") robust_searching = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 1cc675825f..b627bf67c2 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -16,7 +16,8 @@ healable = 0 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "saw" + attack_verb_continuous = "saw" + attack_verb_simple = "saw" attack_sound = 'sound/weapons/bladeslice.ogg' projectilesound = 'sound/weapons/gunshot.ogg' projectiletype = /obj/item/projectile/hivebotbullet @@ -30,7 +31,7 @@ loot = list(/obj/effect/decal/cleanable/robot_debris) blood_volume = 0 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/hostile/hivebot/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index 89303702f3..cab87010ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -10,7 +10,8 @@ melee_damage_lower = 5 melee_damage_upper = 5 a_intent = INTENT_HARM - attacktext = "gores" + attack_verb_continuous = "gores" + attack_verb_simple = "gore" maxHealth = 100 health = 100 speed = 0 @@ -20,6 +21,7 @@ var/multiply_chance = 0 //if we multiply on hit del_on_death = 1 deathmessage = "vanishes into thin air! It was a fake!" + has_field_of_vision = FALSE //not meant to be played anyway. /mob/living/simple_animal/hostile/illusion/Life() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm index c337344c90..c2b553aad7 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm @@ -7,9 +7,8 @@ environment_smash = ENVIRONMENT_SMASH_WALLS minbodytemp = 0 maxbodytemp = 450 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "strikes" + response_harm_continuous = "strikes" + response_harm_simple = "strike" status_flags = NONE a_intent = INTENT_HARM see_in_dark = 4 diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index 05c4007b6f..574811c968 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -27,7 +27,7 @@ var/hop_cooldown = 0 //Strictly for player controlled leapers var/projectile_ready = FALSE //Stopping AI leapers from firing whenever they want, and only doing it after a hop has finished instead - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_HEAVY /obj/item/projectile/leaper name = "leaper bubble" diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm index ae161d596d..40274c0029 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mega_arachnid.dm @@ -25,7 +25,7 @@ projectilesound = 'sound/weapons/pierce.ogg' alpha = 50 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_CLAW /mob/living/simple_animal/hostile/jungle/mega_arachnid/Life() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm index c05d14965e..6efa0cf468 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm @@ -32,7 +32,7 @@ var/attack_state = MOOK_ATTACK_NEUTRAL var/struck_target_leap = FALSE - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_BAREFOOT /mob/living/simple_animal/hostile/jungle/mook/CanPass(atom/movable/O) if(istype(O, /mob/living/simple_animal/hostile/jungle/mook)) diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm index e418cc4ab0..9cb65d7c30 100644 --- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm +++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm @@ -12,12 +12,16 @@ health = 30 see_in_dark = 3 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/killertomato = 2) - response_help = "prods" - response_disarm = "pushes aside" - response_harm = "smacks" + response_help_continuous = "prods" + response_help_simple = "prod" + response_disarm_continuous = "pushes aside" + response_disarm_simple = "push aside" + response_harm_continuous = "smacks" + response_harm_simple = "smack" melee_damage_lower = 8 melee_damage_upper = 12 - attacktext = "slams" + attack_verb_continuous = "slams" + attack_verb_simple = "slam" attack_sound = 'sound/weapons/punch1.ogg' ventcrawler = VENTCRAWLER_ALWAYS faction = list("plants") diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index fd278eb438..8c358fd625 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -54,7 +54,7 @@ Difficulty: Medium deathmessage = "falls to the ground, decaying into glowing particles." death_sound = "bodyfall" - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_HEAVY /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance guidance = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index d2680fbf61..fe6c2290c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -29,12 +29,14 @@ Difficulty: Hard threat = 35 health = 2500 maxHealth = 2500 - attacktext = "rends" + attack_verb_continuous = "rends" + attack_verb_simple = "rend" attack_sound = 'sound/magic/demon_attack1.ogg' icon_state = "bubblegum" icon_living = "bubblegum" icon_dead = "" - friendly = "stares down" + friendly_verb_continuous = "stares down" + friendly_verb_simple = "stare down" icon = 'icons/mob/lavaland/96x96megafauna.dmi' speak_emote = list("gurgles") armour_penetration = 40 @@ -55,7 +57,7 @@ Difficulty: Hard deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... " death_sound = 'sound/magic/enter_blood.ogg' - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_HEAVY /obj/item/gps/internal/bubblegum icon_state = null @@ -227,11 +229,13 @@ Difficulty: Hard icon_state = "bloodbrood" icon_living = "bloodbrood" icon_aggro = "bloodbrood" - attacktext = "pierces" + attack_verb_continuous = "pierces" + attack_verb_simple = "pierce" color = "#C80000" density = FALSE faction = list("mining", "boss") weather_immunities = list("lava","ash") + has_field_of_vision = FALSE /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter/CanPass(atom/movable/mover, turf/target) if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 73fb9d4e48..be3552822f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -27,12 +27,14 @@ Difficulty: Very Hard threat = 40 health = 2500 maxHealth = 2500 - attacktext = "judges" + attack_verb_continuous = "judges" + attack_verb_simple = "judge" attack_sound = 'sound/magic/clockwork/ratvar_attack.ogg' icon_state = "eva" icon_living = "eva" icon_dead = "dragon_dead" - friendly = "stares down" + friendly_verb_continuous = "stares down" + friendly_verb_simple = "stare down" icon = 'icons/mob/lavaland/96x96megafauna.dmi' speak_emote = list("roars") armour_penetration = 40 @@ -606,14 +608,18 @@ Difficulty: Very Hard icon_dead = "butterfly_dead" threat = -0.7 turns_per_move = 1 - response_help = "waves away" - response_disarm = "brushes aside" - response_harm = "disrupts" + response_help_continuous = "waves away" + response_help_simple = "wave away" + response_disarm_continuous = "brushes aside" + response_disarm_simple = "brush aside" + response_harm_continuous = "disrupts" + response_harm_simple = "disrupt" speak_emote = list("oscillates") maxHealth = 2 health = 2 harm_intent_damage = 1 - friendly = "mends" + friendly_verb_continuous = "mends" + friendly_verb_simple = "mend" density = FALSE movement_type = FLYING pass_flags = PASSTABLE | PASSGRILLE | PASSMOB diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 3d106021de..88e33ed91a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -10,7 +10,8 @@ Difficulty: Extremely Hard icon_state = "demonic_miner" icon_living = "demonic_miner" icon = 'icons/mob/icemoon/icemoon_monsters.dmi' - attacktext = "pummels" + attack_verb_continuous = "pummels" + attack_verb_simple = "pummel" attack_sound = 'sound/weapons/sonic_jackhammer.ogg' mob_biotypes = MOB_ORGANIC|MOB_HUMANOID light_color = "#E4C7C5" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index c59272214b..062a4c9a43 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -37,13 +37,15 @@ Difficulty: Medium health = 2500 maxHealth = 2500 spacewalk = TRUE - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/magic/demon_attack1.ogg' icon = 'icons/mob/lavaland/64x64megafauna.dmi' icon_state = "dragon" icon_living = "dragon" icon_dead = "dragon_dead" - friendly = "stares down" + friendly_verb_continuous = "stares down" + friendly_verb_simple = "stare down" speak_emote = list("roars") armour_penetration = 40 melee_damage_lower = 40 @@ -64,7 +66,7 @@ Difficulty: Medium death_sound = 'sound/magic/demon_dies.ogg' var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite/drake() - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_HEAVY /mob/living/simple_animal/hostile/megafauna/dragon/Initialize() smallsprite.Grant(src) @@ -81,7 +83,7 @@ Difficulty: Medium return FALSE return ..() -/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, mob/target, target_message) if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit return return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 477c2ce3aa..4ade831f95 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -40,11 +40,13 @@ Difficulty: Normal threat = 30 health = 2500 maxHealth = 2500 - attacktext = "clubs" + attack_verb_continuous = "clubs" + attack_verb_simple = "club" attack_sound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "hierophant" icon_living = "hierophant" - friendly = "stares down" + friendly_verb_continuous = "stares down" + friendly_verb_simple = "stare down" icon = 'icons/mob/lavaland/hierophant_new.dmi' faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house speak_emote = list("preaches") diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 62a09dff65..4da8a90b23 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -26,7 +26,8 @@ Difficulty: Medium icon_living = "legion" desc = "One of many." icon = 'icons/mob/lavaland/legion.dmi' - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/magic/demon_attack1.ogg' speak_emote = list("echoes") armour_penetration = 50 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 78987ebaa0..c406baf2a6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -27,6 +27,7 @@ mob_size = MOB_SIZE_LARGE layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1 + has_field_of_vision = FALSE //You are a frikkin boss /// Crusher loot dropped when fauna killed with a crusher var/list/crusher_loot var/medal_type diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 5ed163ae7e..ed189f052d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -11,7 +11,8 @@ Difficulty: Hard icon_living = "wendigo" icon_dead = "wendigo_dead" icon = 'icons/mob/icemoon/64x64megafauna.dmi' - attacktext = "claws" + attack_verb_continuous = "claws" + attack_verb_simple = "claw" attack_sound = 'sound/magic/demon_attack1.ogg' weather_immunities = list("snow") speak_emote = list("roars") diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 138d7f155e..5afe109550 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -5,9 +5,12 @@ icon_state = "crate" icon_living = "crate" - response_help = "touches" - response_disarm = "pushes" - response_harm = "hits" + response_help_continuous = "touches" + response_help_simple = "touch" + response_disarm_continuous = "pushes" + response_disarm_simple = "push" + response_harm_continuous = "hits" + response_harm_simple = "hit" speed = 0 maxHealth = 250 health = 250 @@ -18,7 +21,8 @@ harm_intent_damage = 5 melee_damage_lower = 8 melee_damage_upper = 12 - attacktext = "attacks" + attack_verb_continuous = "attacks" + attack_verb_simple = "attack" attack_sound = 'sound/weapons/punch1.ogg' emote_taunt = list("growls") speak_emote = list("creaks") @@ -34,7 +38,8 @@ // Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. /mob/living/simple_animal/hostile/mimic/crate - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" speak_emote = list("clatters") stop_automated_movement = 1 wander = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 4d20d4c7fb..b69a4b69cf 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -25,7 +25,8 @@ obj_damage = 60 melee_damage_lower = 12 melee_damage_upper = 12 - attacktext = "bites into" + attack_verb_continuous = "bites into" + attack_verb_simple = "bite into" a_intent = INTENT_HARM speak_emote = list("chitters") attack_sound = 'sound/weapons/bladeslice.ogg' @@ -72,7 +73,8 @@ throw_message = "bounces harmlessly off of" melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "impales" + attack_verb_continuous = "impales" + attack_verb_simple = "impale" a_intent = INTENT_HARM speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/bladeslice.ogg' @@ -82,6 +84,7 @@ crusher_loot = /obj/item/crusher_trophy/watcher_wing loot = list() butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1) + field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball. /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm index 652840f7e3..116082d571 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm @@ -16,7 +16,8 @@ melee_damage_lower = 10 melee_damage_upper = 10 melee_damage_type = BURN - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/effects/curseattack.ogg' throw_message = "passes through the smokey body of" obj_damage = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index 2114612fce..81b541dc7b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -21,6 +21,7 @@ layer = LARGE_MOB_LAYER sentience_type = SENTIENCE_BOSS hud_type = /datum/hud/lavaland_elite + has_field_of_vision = FALSE //You are a frikkin mini-boss var/chosen_attack = 1 var/list/attack_action_types = list() var/can_talk = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 68a0e81cc7..e662f4e525 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -31,9 +31,8 @@ melee_damage_lower = 30 melee_damage_upper = 30 armour_penetration = 30 - attacktext = "beats down on" - /*attack_verb_continuous = "beats down on" - attack_verb_simple = "beat down on"*/ + attack_verb_continuous = "beats down on" + attack_verb_simple = "beat down on" attack_sound = 'sound/weapons/punch1.ogg' throw_message = "does nothing to the rocky hide of the" speed = 2 @@ -172,9 +171,8 @@ health = 30 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "bashes against" - /*attack_verb_continuous = "bashes against" - attack_verb_simple = "bash against"*/ + attack_verb_continuous = "bashes against" + attack_verb_simple = "bash against" attack_sound = 'sound/weapons/punch1.ogg' throw_message = "does nothing to the rocky hide of the" speed = 2 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 884e3bb989..106cb20efc 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -29,9 +29,8 @@ health = 800 melee_damage_lower = 20 melee_damage_upper = 20 - attacktext = "preaches to" - /*attack_verb_continuous = "preaches to" - attack_verb_simple = "preach to"*/ + attack_verb_continuous = "preaches to" + attack_verb_simple = "preach to" attack_sound = 'sound/magic/clockwork/ratvar_attack.ogg' throw_message = "doesn't affect the purity of" speed = 4 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index c9011c5f5f..c2faa002bc 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -29,9 +29,8 @@ health = 800 melee_damage_lower = 30 melee_damage_upper = 30 - attacktext = "slashes its arms at" - /*attack_verb_continuous = "slashes its arms at" - attack_verb_simple = "slash your arms at"*/ + attack_verb_continuous = "slashes its arms at" + attack_verb_simple = "slash your arms at" attack_sound = 'sound/weapons/bladeslice.ogg' throw_message = "doesn't affect the sturdiness of" speed = 1 @@ -227,9 +226,8 @@ health = 80 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "bites at" - /*attack_verb_continuous = "bites at" - attack_verb_simple = "bite at"*/ + attack_verb_continuous = "bites at" + attack_verb_simple = "bite at" attack_sound = 'sound/effects/curse1.ogg' throw_message = "simply misses" speed = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm index 3276965fa2..ebbf032859 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/pandora.dm @@ -29,9 +29,8 @@ health = 800 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "smashes into the side of" - /*attack_verb_continuous = "smashes into the side of" - attack_verb_simple = "smash into the side of"*/ + attack_verb_continuous = "smashes into the side of" + attack_verb_simple = "smash into the side of" attack_sound = 'sound/weapons/sonic_jackhammer.ogg' throw_message = "merely dinks off of the" speed = 4 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm index c43e9a7461..4a3497055a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm @@ -13,14 +13,16 @@ vision_range = 2 aggro_vision_range = 9 move_to_delay = 5 - friendly = "harmlessly rolls into" + friendly_verb_continuous = "harmlessly rolls into" + friendly_verb_simple = "harmlessly roll into" maxHealth = 45 health = 45 gold_core_spawnable = HOSTILE_SPAWN harm_intent_damage = 5 melee_damage_lower = 0 melee_damage_upper = 0 - attacktext = "barrels into" + attack_verb_continuous = "barrels into" + attack_verb_simple = "barrel into" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HELP speak_emote = list("screeches") diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 3c8cf9025f..a61f1924c8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -14,7 +14,8 @@ move_to_delay = 10 ranged = 1 ranged_cooldown_time = 60 - friendly = "wails at" + friendly_verb_continuous = "wails at" + friendly_verb_simple = "wail at" speak_emote = list("bellows") speed = 3 maxHealth = 300 @@ -23,7 +24,8 @@ obj_damage = 100 melee_damage_lower = 18 melee_damage_upper = 18 - attacktext = "pulverizes" + attack_verb_continuous = "pulverizes" + attack_verb_simple = "pulverize" attack_sound = 'sound/weapons/punch1.ogg' throw_message = "does nothing to the rocky hide of the" vision_range = 4 @@ -35,7 +37,7 @@ var/pre_attack_icon = "Goliath_preattack" loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_HEAVY /mob/living/simple_animal/hostile/asteroid/goliath/Life() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index 39b66fbdc2..c9e650531c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -18,10 +18,14 @@ obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE move_to_delay = 15 - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "squishes" - friendly = "pinches" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "squishes" + response_harm_simple = "squish" + friendly_verb_continuous = "pinches" + friendly_verb_simple = "pinch" a_intent = INTENT_HELP ventcrawler = VENTCRAWLER_ALWAYS gold_core_spawnable = FRIENDLY_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index a7ce559d35..d21e39ef54 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -20,7 +20,8 @@ harm_intent_damage = 5 melee_damage_lower = 0 melee_damage_upper = 0 - attacktext = "lashes out at" + attack_verb_continuous = "lashes out at" + attack_verb_simple = "lash out at" speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "falls right through the strange body of the" @@ -67,7 +68,8 @@ icon_gib = "syndicate_gib" mouse_opacity = MOUSE_OPACITY_OPAQUE move_to_delay = 1 - friendly = "buzzes near" + friendly_verb_continuous = "buzzes near" + friendly_verb_simple = "buzz near" vision_range = 10 speed = 3 maxHealth = 1 @@ -76,7 +78,8 @@ harm_intent_damage = 5 melee_damage_lower = 2 melee_damage_upper = 2 - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "falls right through the strange body of the" @@ -107,7 +110,8 @@ obj_damage = 60 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "lashes out at" + attack_verb_continuous = "lashes out at" + attack_verb_simple = "lash out at" speak_emote = list("echoes") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "bounces harmlessly off of" @@ -173,14 +177,16 @@ icon_aggro = "legion_head" icon_dead = "legion_head" icon_gib = "syndicate_gib" - friendly = "buzzes near" + friendly_verb_continuous = "buzzes near" + friendly_verb_simple = "buzz near" vision_range = 10 maxHealth = 1 health = 5 harm_intent_damage = 5 melee_damage_lower = 12 melee_damage_upper = 12 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" speak_emote = list("echoes") attack_sound = 'sound/weapons/pierce.ogg' throw_message = "is shrugged off by" @@ -396,8 +402,6 @@ ears = /obj/item/radio/headset gloves = /obj/item/clothing/gloves/color/fyellow id = /obj/item/card/id/silver/reaper //looks cool and has a fancy name but only a 1% chance - back = /obj/item/storage/backpack - backpack_contents = list(/obj/item/stack/cable_coil = 12, /obj/item/assembly/flash = 1, /obj/item/storage/fancy/donut_box = 1, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, /obj/item/lighter = 1) if(prob(99)) id = /obj/item/card/id id_job = "Assisant" @@ -407,11 +411,14 @@ gloves = /obj/item/clothing/gloves/color/yellow if(prob(10)) back = /obj/item/twohanded/spear - backpack_contents = null + else if(prob(80)) //Now they dont always have a backpack + back = /obj/item/storage/backpack + backpack_contents = list(/obj/item/stack/cable_coil = 1, /obj/item/assembly/flash = 1, /obj/item/storage/fancy/donut_box = 1, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, /obj/item/lighter = 1) if(prob(90)) r_pocket = /obj/item/kitchen/knife if(prob(60)) l_pocket = /obj/item/soap/homemade + if("Beelegion") uniform = /obj/item/clothing/under/color/yellow suit = /obj/item/clothing/suit/hooded/bee_costume diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm index 88ee27fcc9..66241e3d75 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm @@ -23,7 +23,8 @@ obj_damage = 40 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "slices" + attack_verb_continuous = "slices" + attack_verb_simple = "slice" attack_sound = 'sound/weapons/bladeslice.ogg' vision_range = 7 aggro_vision_range = 7 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm index c8d5cf4b73..b62fb4a665 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm @@ -7,7 +7,8 @@ icon_dead = "ice_whelp_dead" mob_biotypes = MOB_ORGANIC|MOB_BEAST mouse_opacity = MOUSE_OPACITY_ICON - friendly = "stares down" + friendly_verb_continuous = "stares down" + friendly_verb_simple = "stare down" speak_emote = list("roars") speed = 30 move_to_delay = 30 @@ -19,7 +20,8 @@ armour_penetration = 20 melee_damage_lower = 20 melee_damage_upper = 20 - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/magic/demon_attack1.ogg' vision_range = 9 aggro_vision_range = 9 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index 6ad869afe6..c3e4f24c43 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -8,9 +8,8 @@ environment_smash = ENVIRONMENT_SMASH_WALLS minbodytemp = 0 maxbodytemp = INFINITY - response_help = "pokes" - response_disarm = "shoves" - response_harm = "strikes" + response_harm_continuous = "strikes" + response_harm_simple = "strike" status_flags = 0 a_intent = INTENT_HARM var/crusher_loot diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm index 0576d0ecfe..ac2ce37d3f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm @@ -7,7 +7,8 @@ icon_dead = "polarbear_dead" mob_biotypes = MOB_ORGANIC|MOB_BEAST mouse_opacity = MOUSE_OPACITY_ICON - friendly = "growls at" + friendly_verb_continuous = "growls at" + friendly_verb_simple = "growl at" speak_emote = list("growls") speed = 12 move_to_delay = 12 @@ -16,7 +17,8 @@ obj_damage = 40 melee_damage_lower = 25 melee_damage_upper = 25 - attacktext = "claws" + attack_verb_continuous = "claws" + attack_verb_simple = "claw" attack_sound = 'sound/weapons/bladeslice.ogg' vision_range = 2 // don't aggro unless you basically antagonize it, though they will kill you worse than a goliath will aggro_vision_range = 9 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm index 9f17421691..013a75be75 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm @@ -7,7 +7,8 @@ icon_dead = "whitewolf_dead" mob_biotypes = MOB_ORGANIC|MOB_BEAST mouse_opacity = MOUSE_OPACITY_ICON - friendly = "howls at" + friendly_verb_continuous = "howls at" + friendly_verb_simple = "howl at" speak_emote = list("howls") speed = 5 move_to_delay = 5 @@ -19,7 +20,8 @@ rapid_melee = 2 // every second attack dodging = TRUE dodge_prob = 50 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' vision_range = 7 aggro_vision_range = 7 diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index d023cf0dd8..1b13200729 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -9,15 +9,19 @@ maxHealth = 10 health = 10 butcher_results = list(/obj/item/reagent_containers/food/snacks/hugemushroomslice = 1) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "whacks" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "whacks" + response_harm_simple = "whack" harm_intent_damage = 5 obj_damage = 0 melee_damage_lower = 1 melee_damage_upper = 1 attack_same = 2 - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/weapons/bite.ogg' faction = list("mushroom") environment_smash = ENVIRONMENT_SMASH_NONE diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm index ed2a407b8e..8653c40cea 100644 --- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm +++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm @@ -9,9 +9,6 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speak_chance = 12 turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" speed = 0 stat_attack = UNCONSCIOUS robust_searching = 1 @@ -20,7 +17,8 @@ harm_intent_damage = 5 melee_damage_lower = 10 melee_damage_upper = 15 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier) @@ -31,7 +29,7 @@ speak = list("Stop resisting!", "I AM THE LAW!", "Face the wrath of the golden bolt!", "Stop breaking the law, asshole!") search_objects = 1 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/nanotrasen/Aggro() diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 1c8b171738..ca5d047326 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -11,7 +11,8 @@ melee_damage_lower = 25 melee_damage_upper = 50 threat = 2 - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' faction = list("creature") speak_emote = list("screams") @@ -27,7 +28,8 @@ icon_state = "mi-go" icon_living = "mi-go" icon_dead = "mi-go-dead" - attacktext = "lacerates" + attack_verb_continuous = "lacerates" + attack_verb_simple = "lacerate" speed = -0.5 var/static/list/migo_sounds deathmessage = "wails as its form turns into a pulpy mush." @@ -63,7 +65,8 @@ maxHealth = 100 melee_damage_lower = 5 melee_damage_upper = 10 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" deathmessage = "falls apart into a fine dust." /obj/structure/spawner/nether diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index d8737d1edc..0544ddc676 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -8,9 +8,8 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speak_chance = 0 turns_per_move = 5 - response_help = "pushes" - response_disarm = "shoves" - response_harm = "hits" + response_help_continuous = "pushes" + response_help_simple = "push" threat = 3 speed = 0 maxHealth = 115 @@ -19,7 +18,8 @@ harm_intent_damage = 5 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) @@ -39,11 +39,12 @@ melee_damage_lower = 30 melee_damage_upper = 30 armour_penetration = 35 - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/blade1.ogg' var/obj/effect/light_emitter/red_energy_sword/sord - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/pirate/melee/space name = "Space Pirate Swashbuckler" diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index cc17759cc6..9045ccef51 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -7,9 +7,12 @@ icon_gib = "bat_dead" turns_per_move = 1 blood_volume = 250 - response_help = "brushes aside" - response_disarm = "flails at" - response_harm = "hits" + response_help_continuous = "brushes aside" + response_help_simple = "brush aside" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "hits" + response_harm_simple = "hit" mob_biotypes = MOB_ORGANIC|MOB_BEAST speak_chance = 0 maxHealth = 15 @@ -19,7 +22,8 @@ harm_intent_damage = 6 melee_damage_lower = 6 melee_damage_upper = 5 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1) pass_flags = PASSTABLE faction = list("hostile") @@ -47,5 +51,6 @@ icon_gib = "secbat_dead" desc = "A fruit bat with a tiny little security hat who is ready to inject cuteness into any security operation." emote_see = list("is ready to law down the law.", "flaps about with an air of authority.") - response_help = "respects the authority of" + response_help_continuous = "respects the authority of" + response_help_simple = "respect the authority of" gold_core_spawnable = FRIENDLY_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index c94046329b..35f2817028 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -8,8 +8,10 @@ icon_gib = "clown_gib" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID turns_per_move = 5 - response_disarm = "gently pushes aside" - response_harm = "robusts" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "robusts" + response_harm_simple = "robust" speak = list("HONK", "Honk!", "Welcome to clown planet!") emote_see = list("honks", "squeaks") speak_chance = 1 @@ -30,6 +32,7 @@ minbodytemp = 270 maxbodytemp = 370 unsuitable_atmos_damage = 10 + footstep_type = FOOTSTEP_MOB_SHOE var/banana_time = 0 // If there's no time set it won't spawn. var/banana_type = /obj/item/grown/bananapeel var/attack_reagent @@ -69,8 +72,10 @@ icon_state = "lube" icon_living = "lube" turns_per_move = 1 - response_help = "dips a finger into" - response_disarm = "gently scoops and pours aside" + response_help_continuous = "dips a finger into" + response_help_simple = "dip a finger into" + response_disarm_continuous = "gently scoops and pours aside" + response_disarm_simple = "gently scoop and pour aside" emote_see = list("bubbles", "oozes") loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/particle_effect/foam) @@ -83,8 +88,10 @@ desc = "A fusion of clown and banana DNA birthed from a botany experiment gone wrong." icon_state = "banana tree" icon_living = "banana tree" - response_disarm = "peels" - response_harm = "peels" + response_disarm_continuous = "peels" + response_disarm_simple = "peel" + response_harm_continuous = "peels" + response_harm_simple = "peel" turns_per_move = 1 speak = list("HONK", "Honk!", "YA-HONK!!!") emote_see = list("honks", "bites into the banana", "plucks a banana off its head", "photosynthesizes") @@ -104,7 +111,8 @@ harm_intent_damage = 1 melee_damage_lower = 1 melee_damage_upper = 1 - attacktext = "cheers up" + attack_verb_continuous = "cheers up" + attack_verb_simple = "cheer up" loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana/bluespace) banana_type = /obj/item/grown/bananapeel attack_reagent = /datum/reagent/consumable/laughter @@ -114,9 +122,12 @@ desc = "A being forged out of the pure essence of pranking, cursed into existence by a cruel maker." icon_state = "fleshclown" icon_living = "fleshclown" - response_help = "reluctantly pokes" - response_disarm = "sinks his hands into the spongy flesh of" - response_harm = "cleanses the world of" + response_help_continuous = "reluctantly pokes" + response_help_simple = "reluctantly poke" + response_disarm_continuous = "sinks his hands into the spongy flesh of" + response_disarm_simple = "sink your hands into the spongy flesh of" + response_harm_continuous = "cleanses the world of" + response_harm_simple = "cleanse the world of" speak = list("HONK", "Honk!", "I didn't ask for this", "I feel constant and horrible pain", "YA-HONK!!!", "this body is a merciless and unforgiving prison", "I was born out of mirthful pranking but I live in suffering") emote_see = list("honks", "sweats", "jiggles", "contemplates its existence") speak_chance = 5 @@ -126,7 +137,8 @@ health = 140 speed = -5 melee_damage_upper = 15 - attacktext = "limply slaps" + attack_verb_continuous = "limply slaps" + attack_verb_simple = "limply slap" obj_damage = 5 loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap) @@ -137,9 +149,12 @@ icon_living = "long face" move_resist = INFINITY turns_per_move = 10 - response_help = "tries to awkwardly hug" - response_disarm = "pushes the unwieldy frame of" - response_harm = "tries to shut up" + response_help_continuous = "tries to awkwardly hug" + response_help_simple = "try to awkwardly hug" + response_disarm_continuous = "pushes the unwieldy frame of" + response_disarm_simple = "push the unwieldy frame of" + response_harm_continuous = "tries to shut up" + response_harm_simple = "try to shut up" speak = list("YA-HONK!!!") emote_see = list("honks", "squeaks") speak_chance = 60 @@ -149,7 +164,8 @@ speed = 10 harm_intent_damage = 5 melee_damage_lower = 5 - attacktext = "YA-HONKs" + attack_verb_continuous = "YA-HONKs" + attack_verb_simple = "YA-HONK" loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap) /mob/living/simple_animal/hostile/retaliate/clown/clownhulk @@ -158,9 +174,12 @@ icon_state = "honkhulk" icon_living = "honkhulk" move_resist = INFINITY - response_help = "tries desperately to appease" - response_disarm = "foolishly pushes" - response_harm = "angers" + response_help_continuous = "tries desperately to appease" + response_help_simple = "tries desperately to appease" + response_disarm_continuous = "foolishly pushes" + response_disarm_simple = "foolishly push" + response_harm_continuous = "angers" + response_harm_simple = "anger" speak = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!") emote_see = list("honks", "sweats", "grunts") speak_chance = 5 @@ -171,7 +190,8 @@ harm_intent_damage = 15 melee_damage_lower = 15 melee_damage_upper = 20 - attacktext = "pummels" + attack_verb_continuous = "pummels" + attack_verb_simple = "pummel" obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_WALLS loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap) @@ -181,16 +201,20 @@ desc = "A real lunkhead who somehow gets all the girls." icon_state = "chlown" icon_living = "chlown" - response_help = "submits to" - response_disarm = "tries to assert dominance over" - response_harm = "makes a weak beta attack at" + response_help_continuous = "submits to" + response_help_simple = "submit to" + response_disarm_continuous = "tries to assert dominance over" + response_disarm_simple = "try to assert dominance over" + response_harm_continuous = "makes a weak beta attack at" + response_harm_simple = "make a weak beta attack at" speak = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?") emote_see = list("asserts his dominance", "emasculates everyone implicitly") maxHealth = 500 health = 500 speed = -2 armour_penetration = 20 - attacktext = "steals the girlfriend of" + attack_verb_continuous = "steals the girlfriend of" + attack_verb_simple = "steal the girlfriend of" attack_sound = 'sound/items/airhorn2.ogg' loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap) @@ -199,8 +223,10 @@ desc = "A slender wiry figure of alchemical origin." icon_state = "honkmunculus" icon_living = "honkmunculus" - response_help = "skeptically pokes" - response_disarm = "pushes the unwieldy frame of" + response_help_continuous = "skeptically pokes" + response_help_simple = "skeptically poke" + response_disarm_continuous = "pushes the unwieldy frame of" + response_disarm_simple = "push the unwieldy frame of" speak = list("honk") emote_see = list("squirms", "writhes") speak_chance = 1 @@ -210,7 +236,8 @@ harm_intent_damage = 5 melee_damage_lower = 5 melee_damage_upper = 10 - attacktext = "ferociously mauls" + attack_verb_continuous = "ferociously mauls" + attack_verb_simple = "ferociously maul" environment_smash = ENVIRONMENT_SMASH_NONE loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap) attack_reagent = /datum/reagent/peaceborg_confuse @@ -220,8 +247,10 @@ desc = "An ancient being born of arcane honking." icon_state = "destroyer" icon_living = "destroyer" - response_disarm = "bounces off of" - response_harm = "bounces off of" + response_disarm_continuous = "bounces off of" + response_disarm_simple = "bounce off of" + response_harm_continuous = "bounces off of" + response_harm_simple = "bounce off ot" speak = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!") maxHealth = 400 health = 400 @@ -231,7 +260,8 @@ melee_damage_upper = 40 armour_penetration = 30 stat_attack = UNCONSCIOUS - attacktext = "acts out divine vengeance on" + attack_verb_continuous = "acts out divine vengeance on" + attack_verb_simple = "act out divine vengeance on" obj_damage = 50 environment_smash = ENVIRONMENT_SMASH_RWALLS loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap) @@ -243,9 +273,12 @@ icon_living = "mutant" move_resist = INFINITY turns_per_move = 10 - response_help = "reluctantly sinks a finger into" - response_disarm = "squishes into" - response_harm = "squishes into" + response_help_continuous = "reluctantly sinks a finger into" + response_help_simple = "reluctantly sink a finger into" + response_disarm_continuous = "squishes into" + response_disarm_simple = "squish into" + response_harm_continuous = "squishes into" + response_harm_simple = "squish into" speak = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK") emote_see = list("squirms", "writhes", "pulsates", "froths", "oozes") speak_chance = 10 @@ -256,7 +289,8 @@ harm_intent_damage = 10 melee_damage_lower = 10 melee_damage_upper = 20 - attacktext = "awkwardly flails at" + attack_verb_continuous = "awkwardly flails at" + attack_verb_simple = "awkwardly flail at" loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human) /mob/living/simple_animal/hostile/retaliate/clown/mutant/blob @@ -269,6 +303,7 @@ health = 130 mob_size = MOB_SIZE_LARGE speed = 20 - attacktext = "bounces off of" + attack_verb_continuous = "bounces off of" + attack_verb_simple = "bounce off of" loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human) attack_reagent = /datum/reagent/toxin/mindbreaker diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm index ef51d8621b..8424a0a576 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm @@ -13,10 +13,14 @@ health = 15 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "bites" - response_help = "pets" - response_disarm = "pokes" - response_harm = "splats" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "pokes" + response_disarm_simple = "poke" + response_harm_continuous = "splats" + response_harm_simple = "splat" density = FALSE ventcrawler = VENTCRAWLER_ALWAYS faction = list("hostile") diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index 48d16f63f3..2c94739180 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -7,9 +7,12 @@ mob_biotypes = MOB_SPIRIT speak_chance = 0 turns_per_move = 5 - response_help = "passes through" - response_disarm = "shoves" - response_harm = "hits" + response_help_continuous = "passes through" + response_help_simple = "pass through" + response_disarm_continuous = "shoves" + response_disarm_simple = "shove" + response_harm_continuous = "hits" + response_harm_simple = "hit" a_intent = INTENT_HARM healable = 0 speed = 0 @@ -20,7 +23,8 @@ melee_damage_upper = 15 del_on_death = 1 emote_see = list("weeps silently", "groans", "mumbles") - attacktext = "grips" + attack_verb_continuous = "grips" + attack_verb_simple = "grip" attack_sound = 'sound/hallucinations/growl1.ogg' speak_emote = list("weeps") deathmessage = "wails, disintegrating into a pile of ectoplasm!" @@ -32,6 +36,7 @@ pressure_resistance = 300 gold_core_spawnable = NO_SPAWN //too spooky for science blood_volume = 0 + has_field_of_vision = FALSE var/ghost_hair_style var/ghost_hair_color var/mutable_appearance/ghost_hair diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm index 29b0c0b701..ebeb2d28ec 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm @@ -8,9 +8,12 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID gender = MALE turns_per_move = 5 - response_help = "pokes" - response_disarm = "gently pushes aside" - response_harm = "punches" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "punches" + response_harm_simple = "punch" a_intent = INTENT_HARM maxHealth = 100 health = 100 @@ -18,13 +21,14 @@ harm_intent_damage = 8 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "hits" + attack_verb_continuous = "hits" + attack_verb_simple = "hit" attack_sound = 'sound/weapons/punch1.ogg' obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE del_on_death = 0 - - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE + has_field_of_vision = FALSE //Legacy gameplay experience. Also they only have one dir visually. /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace //this should be in a different file name = "Nanotrasen Private Security Officer" @@ -35,9 +39,12 @@ icon_dead = null icon_gib = "syndicate_gib" turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" + response_help_continuous = "pokes" + response_help_simple = "poke" + response_disarm_continuous = "shoves" + response_disarm_simple = "shove" + response_harm_continuous = "hits" + response_harm_simple = "hit" speed = 0 stat_attack = UNCONSCIOUS robust_searching = 1 @@ -47,7 +54,8 @@ harm_intent_damage = 5 melee_damage_lower = 10 melee_damage_upper = 15 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' faction = list("nanotrasenprivate") a_intent = INTENT_HARM diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index 9c3e3e0b92..f7a46658c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -9,9 +9,6 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speak_chance = 0 turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" speed = 0 threat = 1 maxHealth = 100 @@ -19,7 +16,8 @@ harm_intent_damage = 5 melee_damage_lower = 15 melee_damage_upper = 15 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM loot = list(/obj/effect/mob_spawn/human/corpse/russian, @@ -30,7 +28,7 @@ status_flags = CANPUSH del_on_death = 1 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/russian/ranged diff --git a/code/modules/mob/living/simple_animal/hostile/sharks.dm b/code/modules/mob/living/simple_animal/hostile/sharks.dm index 4008334a57..1263a23d26 100644 --- a/code/modules/mob/living/simple_animal/hostile/sharks.dm +++ b/code/modules/mob/living/simple_animal/hostile/sharks.dm @@ -12,9 +12,12 @@ speak_chance = 0 turns_per_move = 3 butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 3) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "hits" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" speed = 0 threat = 1 maxHealth = 75 @@ -22,7 +25,8 @@ harm_intent_damage = 18 melee_damage_lower = 18 melee_damage_upper = 18 - attacktext = "maims" + attack_verb_continuous = "maims" + attack_verb_simple = "maim" attack_sound = 'sound/weapons/bite.ogg' gold_core_spawnable = 1 //Space shark aren't affected by cold. @@ -82,7 +86,8 @@ harm_intent_damage = 0 melee_damage_lower = 0 melee_damage_upper = 0 - attacktext = "violently hugs" + attack_verb_continuous = "violently hugs" + attack_verb_simple = "violently hug" vision_range = 0 /mob/living/simple_animal/hostile/shark/kawaii/death() diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index df71701bb7..f3138a773c 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -22,7 +22,8 @@ minbodytemp = 0 maxbodytemp = 1500 healable = 0 //they're skeletons how would bruise packs help them?? - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/hallucinations/growl1.ogg' 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) unsuitable_atmos_damage = 10 @@ -36,7 +37,7 @@ del_on_death = 1 loot = list(/obj/effect/decal/remains/human) - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/skeleton/eskimo name = "undead eskimo" @@ -104,7 +105,8 @@ melee_damage_lower = 15 melee_damage_upper = 20 light_color = LIGHT_COLOR_PURPLE - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/hallucinations/growl1.ogg' deathmessage = "collapses into a pile of bones, their suit dissolving among the plasma!" loot = list(/obj/effect/decal/remains/plasma) @@ -120,7 +122,8 @@ harm_intent_damage = 15 melee_damage_lower = 20 melee_damage_upper = 25 - attacktext = "blasts" + attack_verb_continuous = "blasts" + attack_verb_simple = "blast" attack_sound = 'sound/weapons/sonic_jackhammer.ogg' loot = list(/obj/effect/decal/remains/plasma, /obj/item/pickaxe/drill/jackhammer) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 8c622c7f29..23304a2ef3 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -11,9 +11,10 @@ a_intent = INTENT_HARM mob_biotypes = MOB_HUMANOID threat = 3 - response_help = "touches" - response_disarm = "pushes" - + response_help_continuous = "touches" + response_help_simple = "touch" + response_disarm_continuous = "pushes" + response_disarm_simple = "push" speed = -1 maxHealth = 50000 health = 50000 @@ -24,7 +25,8 @@ obj_damage = 100 melee_damage_lower = 68 melee_damage_upper = 83 - attacktext = "claws" + attack_verb_continuous = "claws" + attack_verb_simple = "claw" attack_sound = 'sound/hallucinations/growl1.ogg' 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) @@ -125,14 +127,10 @@ // This loop will, at most, loop twice. for(var/atom/check in check_list) - for(var/mob/living/M in viewers(world.view + 1, check) - src) + for(var/mob/living/M in fov_viewers(world.view + 1, check) - src) if(M.client && CanAttack(M) && !M.silicon_privileges) if(!M.eye_blind) return M - for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you - if(M.occupant && M.occupant.client) - if(!M.occupant.eye_blind) - return M.occupant return null // Cannot talk diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm index 24bf5e9ea9..2edcc4021a 100644 --- a/code/modules/mob/living/simple_animal/hostile/stickman.dm +++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm @@ -10,9 +10,6 @@ gender = MALE speak_chance = 0 turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" speed = 0 blood_volume = 0 stat_attack = UNCONSCIOUS @@ -24,7 +21,8 @@ obj_damage = 0 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 8c4e19774d..9a362b680d 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -25,9 +25,6 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speak_chance = 0 turns_per_move = 5 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" threat = 1 speed = 0 stat_attack = UNCONSCIOUS @@ -37,7 +34,8 @@ harm_intent_damage = 5 melee_damage_lower = 10 melee_damage_upper = 10 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier) @@ -50,7 +48,7 @@ dodging = TRUE rapid_melee = 2 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE ///////////////Melee//////////// @@ -82,7 +80,8 @@ icon_state = "syndicate_knife" icon_living = "syndicate_knife" loot = list(/obj/effect/gibspawner/human) - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' status_flags = 0 @@ -113,7 +112,8 @@ melee_damage_upper = 30 icon_state = "syndicate_sword" icon_living = "syndicate_sword" - attacktext = "slashes" + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" attack_sound = 'sound/weapons/blade1.ogg' armour_penetration = 35 light_color = LIGHT_COLOR_RED @@ -292,7 +292,8 @@ melee_damage_upper = 15 obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE - attacktext = "cuts" + attack_verb_continuous = "cuts" + attack_verb_simple = "cut" attack_sound = 'sound/weapons/bladeslice.ogg' faction = list(ROLE_SYNDICATE) 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) diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index bc932666f6..3aa3c9e566 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -10,9 +10,12 @@ threat = 1 speak_chance = 0 turns_per_move = 5 - response_help = "brushes" - response_disarm = "pushes" - response_harm = "hits" + response_help_continuous = "brushes" + response_help_simple = "brush" + response_disarm_continuous = "pushes" + response_disarm_simple = "push" + response_harm_continuous = "hits" + response_harm_simple = "hit" speed = 1 maxHealth = 250 health = 250 @@ -23,7 +26,8 @@ harm_intent_damage = 5 melee_damage_lower = 8 melee_damage_upper = 12 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' speak_emote = list("pines") emote_taunt = list("growls") diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm index 15d641299d..57fb6f829d 100644 --- a/code/modules/mob/living/simple_animal/hostile/wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm @@ -8,9 +8,6 @@ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speak_chance = 0 turns_per_move = 3 - response_help = "pokes" - response_disarm = "shoves" - response_harm = "hits" threat = 3 speed = 0 maxHealth = 100 @@ -18,7 +15,8 @@ harm_intent_damage = 5 melee_damage_lower = 5 melee_damage_upper = 5 - attacktext = "punches" + attack_verb_continuous = "punches" + attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' a_intent = INTENT_HARM atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) @@ -38,7 +36,7 @@ var/next_cast = 0 - do_footstep = TRUE + footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/wizard/Initialize() . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm index 8878f17893..5c881a7b0d 100644 --- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm +++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm @@ -12,7 +12,8 @@ mouse_opacity = MOUSE_OPACITY_ICON move_to_delay = 5 threat = 1 - friendly = "floats near" + friendly_verb_continuous = "floats near" + friendly_verb_simple = "float near" speak_emote = list("puffs") vision_range = 5 speed = 0 @@ -23,7 +24,8 @@ obj_damage = 0 melee_damage_lower = 0 melee_damage_upper = 0 - attacktext = "chomps" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" attack_sound = 'sound/weapons/punch1.ogg' throw_message = "is avoided by the" vision_range = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index 503f5c121e..6e4cbac022 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -13,7 +13,8 @@ harm_intent_damage = 5 melee_damage_lower = 21 melee_damage_upper = 21 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/hallucinations/growl1.ogg' a_intent = INTENT_HARM 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) @@ -73,7 +74,8 @@ harm_intent_damage = 5 melee_damage_lower = 21 melee_damage_upper = 21 - attacktext = "bites" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" attack_sound = 'sound/hallucinations/growl1.ogg' a_intent = INTENT_HARM 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) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 9ad9a121ca..e8d6411c01 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -50,13 +50,18 @@ melee_damage_upper = 10 melee_damage_lower = 5 - response_help = "pets" - response_disarm = "gently moves aside" - response_harm = "swats" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently moves aside" + response_disarm_simple = "gently move aside" + response_harm_continuous = "swats" + response_harm_simple = "swat" stop_automated_movement = 1 a_intent = INTENT_HARM //parrots now start "aggressive" since only player parrots will nuzzle. - attacktext = "chomps" - friendly = "grooms" + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" + friendly_verb_continuous = "grooms" + friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL movement_type = FLYING gold_core_spawnable = FRIENDLY_SPAWN @@ -575,7 +580,12 @@ parrot_state = PARROT_WANDER return - attacktext = pick("claws at", "chomps") + if(prob(50)) + attack_verb_continuous = "claws at" + attack_verb_simple = "claw_at" + else + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" L.attack_animal(src)//Time for the hurt to begin! //Otherwise, fly towards the mob! else diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 6aa7f8b401..75182b85e5 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -13,13 +13,17 @@ healable = 0 speak_emote = list("hisses") emote_hear = list("wails.","screeches.") - response_help = "puts their hand through" - response_disarm = "flails at" - response_harm = "punches" + response_help_continuous = "puts their hand through" + response_help_simple = "put your hand through" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" speak_chance = 1 melee_damage_lower = 5 melee_damage_upper = 12 - attacktext = "metaphysically strikes" + attack_verb_continuous = "metaphysically strikes" + attack_verb_simple = "metaphysically strike" minbodytemp = 0 maxbodytemp = INFINITY 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) @@ -32,6 +36,7 @@ del_on_death = TRUE initial_language_holder = /datum/language_holder/construct blood_volume = 0 + has_field_of_vision = FALSE //we are a spoopy ghost /mob/living/simple_animal/shade/death() deathmessage = "lets out a contented sigh as [p_their()] form unwinds." diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index def6327461..3491fd2f95 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -4,95 +4,141 @@ health = 20 maxHealth = 20 gender = PLURAL //placeholder - blood_volume = 550 //How much blud it has for bloodsucking + ///How much blud it has for bloodsucking + blood_volume = 550 status_flags = CANPUSH var/icon_living = "" - var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this. - var/icon_gib = null //We only try to show a gibbing animation if this exists. + ///icon when the animal is dead. Don't use animated icons for this. + var/icon_dead = "" + ///We only try to show a gibbing animation if this exists. + var/icon_gib = null var/list/speak = list() - var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable. + ///Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable. + var/list/speak_emote = list() var/speak_chance = 0 - var/list/emote_hear = list() //Hearable emotes - var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps + ///Hearable emotes + var/list/emote_hear = list() + ///Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps. + var/list/emote_see = list() var/turns_per_move = 1 var/turns_since_move = 0 - var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals. - var/wander = 1 // Does the mob wander around when idle? - var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it. + ///Use this to temporarely stop random movement or to if you write special movement code for animals. + var/stop_automated_movement = 0 + ///Does the mob wander around when idle? + var/wander = 1 + ///When set to 1 this stops the animal from moving when someone is pulling it. + var/stop_automated_movement_when_pulled = 1 - //Interaction - var/response_help = "pokes" - var/response_disarm = "shoves" - var/response_harm = "hits" + ///When someone interacts with the simple animal. + ///Help-intent verb in present continuous tense. + var/response_help_continuous = "pokes" + ///Help-intent verb in present simple tense. + var/response_help_simple = "poke" + ///Disarm-intent verb in present continuous tense. + var/response_disarm_continuous = "shoves" + ///Disarm-intent verb in present simple tense. + var/response_disarm_simple = "shove" + ///Harm-intent verb in present continuous tense. + var/response_harm_continuous = "hits" + ///Harm-intent verb in present simple tense. + var/response_harm_simple = "hit" var/harm_intent_damage = 3 - var/force_threshold = 0 //Minimum force required to deal any damage + ///Minimum force required to deal any damage. + var/force_threshold = 0 - //Temperature effect + ///Temperature effect. var/minbodytemp = 250 var/maxbodytemp = 350 - //Healable by medical stacks? Defaults to yes. + ///Healable by medical stacks? Defaults to yes. var/healable = 1 - //Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage + ///Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum - var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above + ///This damage is taken when atmos doesn't fit all the requirements above. + var/unsuitable_atmos_damage = 2 - //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly + ///LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly. var/melee_damage_lower = 0 var/melee_damage_upper = 0 - var/obj_damage = 0 //how much damage this simple animal does to objects, if any - var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value - var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage. - var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source - var/attacktext = "attacks" + ///How much damage this simple animal does to objects, if any. + var/obj_damage = 0 + ///How much armour they ignore, as a flat reduction from the targets armour value. + var/armour_penetration = 0 + ///Damage type of a simple mob's melee attack, should it do damage. + var/melee_damage_type = BRUTE + /// 1 for full damage , 0 for none , -1 for 1:1 heal from that source. + var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + ///Attacking verb in present continuous tense. + var/attack_verb_continuous = "attacks" + ///Attacking verb in present simple tense. + var/attack_verb_simple = "attack" var/attack_sound = null - var/friendly = "nuzzles" //If the mob does no damage with it's attack - var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls + ///Attacking, but without damage, verb in present continuous tense. + var/friendly_verb_continuous = "nuzzles" + ///Attacking, but without damage, verb in present simple tense. + var/friendly_verb_simple = "nuzzle" + ///Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls. + var/environment_smash = ENVIRONMENT_SMASH_NONE - var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster + ///LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster. + var/speed = 1 - //Hot simple_animal baby making vars + ///Hot simple_animal baby making vars. var/list/childtype = null var/next_scan_time = 0 - var/animal_species //Sorry, no spider+corgi buttbabies. + ///Sorry, no spider+corgi buttbabies. + var/animal_species - //simple_animal access - var/obj/item/card/id/access_card = null //innate access uses an internal ID card - var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against - var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood + ///Innate access uses an internal ID card. + var/obj/item/card/id/access_card = null + ///In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to TRUE, so we have something to check against. + var/buffed = FALSE + ///If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood. + var/gold_core_spawnable = NO_SPAWN var/datum/component/spawner/nest - var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions + ///Sentience type, for slime potions. + var/sentience_type = SENTIENCE_ORGANIC - var/list/loot = list() //list of things spawned at mob's loc when it dies - var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses + ///list of things spawned at mob's loc when it dies. + var/list/loot = list() + ///causes mob to be deleted on death, useful for mobs that spawn lootable corpses. + var/del_on_death = FALSE var/deathmessage = "" - var/death_sound = null //The sound played on death + ///The sound played on death. + var/death_sound = null var/allow_movement_on_non_turfs = FALSE - var/attacked_sound = "punch" //Played when someone punches the creature + ///Played when someone punches the creature. + var/attacked_sound = "punch" - var/dextrous = FALSE //If the creature has, and can use, hands + ///If the creature has, and can use, hands. + var/dextrous = FALSE var/dextrous_hud_type = /datum/hud/dextrous - var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players) - var/can_have_ai = TRUE //once we have become sentient, we can never go back + ///The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players). + var/AIStatus = AI_ON + ///once we have become sentient, we can never go back. + var/can_have_ai = TRUE - var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. + ///convenience var for forcibly waking up an idling AI on next check. + var/shouldwakeup = FALSE - //domestication + ///Domestication. var/tame = 0 - var/my_z // I don't want to confuse this with client registered_z + ///I don't want to confuse this with client registered_z. + var/my_z - var/do_footstep = FALSE + ///What kind of footstep this mob should have. Null if it shouldn't have any. + var/footstep_type /mob/living/simple_animal/Initialize() . = ..() @@ -106,6 +152,8 @@ update_simplemob_varspeed() if(dextrous) AddComponent(/datum/component/personal_crafting) + if(footstep_type) + AddComponent(/datum/component/footstep, footstep_type) /mob/living/simple_animal/Destroy() GLOB.simple_animals[AIStatus] -= src @@ -122,10 +170,6 @@ return ..() -/mob/living/simple_animal/initialize_footstep() - if(do_footstep) - ..() - /mob/living/simple_animal/updatehealth() ..() health = clamp(health, 0, maxHealth) diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 0c7f126ad5..d93993bf1f 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -28,7 +28,7 @@ return 0 var/list/choices = list() - for(var/mob/living/C in view(1,src)) + for(var/mob/living/C in fov_view(1,src)) if(C!=src && Adjacent(C)) choices += C diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 1c5916a249..0ef5cabc91 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -12,9 +12,12 @@ harm_intent_damage = 5 icon_living = "grey baby slime" icon_dead = "grey baby slime dead" - response_help = "pets" - response_disarm = "shoos" - response_harm = "stomps on" + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "shoos" + response_disarm_simple = "shoo" + response_harm_continuous = "stomps on" + response_harm_simple = "stomp on" emote_see = list("jiggles", "bounces in place") speak_emote = list("blorbles") bubble_icon = "slime" @@ -64,8 +67,6 @@ var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime var/force_stasis = FALSE - do_footstep = TRUE - var/static/regex/slime_name_regex = new("\\w+ (baby|adult) slime \\(\\d+\\)") ///////////TIME FOR SUBSPECIES @@ -103,6 +104,7 @@ create_reagents(100, NONE, NO_REAGENTS_VALUE) set_colour(new_colour) . = ..() + AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 7.5) /mob/living/simple_animal/slime/Destroy() for (var/A in actions) diff --git a/code/modules/mob/living/update_icons.dm b/code/modules/mob/living/update_icons.dm index 8bf0dc98a9..f8d5d7e0ba 100644 --- a/code/modules/mob/living/update_icons.dm +++ b/code/modules/mob/living/update_icons.dm @@ -2,7 +2,6 @@ /mob/living/update_transform() var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/final_pixel_y = pixel_y - var/final_dir = dir var/changed = 0 if(lying != lying_prev && rotate_on_lying) changed++ @@ -14,7 +13,7 @@ pixel_y = get_standard_pixel_y_offset() final_pixel_y = get_standard_pixel_y_offset(lying) if(dir & (EAST|WEST)) //Facing east or west - final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass + setDir(pick(NORTH, SOUTH)) //So you fall on your side rather than your face or ass if(resize != RESIZE_DEFAULT_SIZE) changed++ @@ -22,5 +21,5 @@ resize = RESIZE_DEFAULT_SIZE if(changed) - animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT) - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life(). + animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT) + floating_need_update = TRUE diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index c266bbddd3..b7546becd8 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -55,3 +55,5 @@ log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP) SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) + if(has_field_of_vision && CONFIG_GET(flag/use_field_of_vision)) + LoadComponent(/datum/component/field_of_vision, field_of_vision_type) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 6e4bd534af..0f92ce7c33 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -125,8 +125,10 @@ * * blind_message (optional) is what blind people will hear e.g. "You hear something!" * * vision_distance (optional) define how many tiles away the message can be seen. * * ignored_mobs (optional) doesn't show any message to any given mob in the list. + * * target (optional) is the other mob involved with the visible message. For example, the attacker in many combat messages. + * * target_message (optional) is what the target mob will see e.g. "[src] does something to you!" */ -/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs) +/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, mob/target, target_message) var/turf/T = get_turf(src) if(!T) return @@ -136,7 +138,19 @@ if(!islist(ignored_mobs)) ignored_mobs = list(ignored_mobs) hearers -= ignored_mobs - if(self_message) + + if(target_message && target && istype(target) && target.client) + hearers -= target + //This entire if/else chain could be in two lines but isn't for readibilties sake. + var/msg = target_message + if(target.see_invisibleSomething is there but you can't see it!") + return var/list/result = A.examine(src) to_chat(src, result.Join("\n")) - SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) //same as above //note: ghosts can point, this is intended //visible_message will handle invisibility properly //overridden here and in /mob/dead/observer for different point span classes and sanity checks -/mob/verb/pointed(atom/A as mob|obj|turf in view()) +/mob/verb/pointed(atom/A as mob|obj|turf in fov_view()) set name = "Point To" set category = "Object" diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 825f015ef4..9947c8ca1e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -12,6 +12,9 @@ vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace. + /// What receives our keyboard input. src by default. + var/datum/focus + var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE var/datum/mind/mind var/list/datum/action/actions = list() @@ -130,3 +133,17 @@ var/siliconaccesstoggle = FALSE var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted. + + var/has_field_of_vision = FALSE + var/field_of_vision_type = FOV_90_DEGREES + + + ///////TYPING INDICATORS/////// + /// Set to true if we want to show typing indicators. + var/typing_indicator_enabled = FALSE + /// Default icon_state of our typing indicator. Currently only supports paths (because anything else is, as of time of typing this, unnecesary. + var/typing_indicator_state = /obj/effect/overlay/typing_indicator + /// The timer that will remove our indicator for early aborts (like when an user finishes their message) + var/typing_indicator_timerid + /// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays. + var/typing_indicator_current diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 6531df5e68..2bcfd47344 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -100,7 +100,8 @@ if(mob.throwing) mob.throwing.finalize(FALSE) - if(L.pulling && !(L.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) + var/atom/movable/AM = L.pulling + if(AM && AM.density && !(L.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && !ismob(AM)) L.setDir(turn(L.dir, 180)) SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index f348829b71..e2b3aee35d 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -1,12 +1,53 @@ //Speech verbs. -/mob/verb/say_verb(message as text) - set name = "Say" +// the _keybind verbs uses "as text" versus "as text|null" to force a popup when pressed by a keybind. +/mob/verb/say_typing_indicator() + set name = "say_indicator" + set hidden = TRUE set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "say") as text|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return say_verb(message) + +/mob/verb/say_verb(message as text) + set name = "say" + set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return - if(message) - say(message) + clear_typing_indicator() // clear it immediately! + say(message) + +/mob/verb/me_typing_indicator() + set name = "me_indicator" + set hidden = TRUE + set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "me") as message|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return me_verb(message) + +/mob/verb/me_verb(message as message) + set name = "me" + set category = "IC" + if(!length(message)) + return + if(GLOB.say_disabled) //This is here to try to identify lag problems + to_chat(usr, "Speech is currently admin-disabled.") + return + + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + clear_typing_indicator() // clear it immediately! + + usr.emote("me",1,message,TRUE) /mob/say_mod(input, message_mode) var/customsayverb = findtext(input, "*") @@ -16,9 +57,17 @@ else return ..() +/mob/proc/whisper_keybind() + var/message = input(src, "", "whisper") as text|null + if(!length(message)) + return + return whisper_verb(message) + /mob/verb/whisper_verb(message as text) set name = "Whisper" set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return @@ -27,18 +76,6 @@ /mob/proc/whisper(message, datum/language/language=null) say(message, language) //only living mobs actually whisper, everything else just talks -/mob/verb/me_verb(message as message) - set name = "Me" - set category = "IC" - - if(GLOB.say_disabled) //This is here to try to identify lag problems - to_chat(usr, "Speech is currently admin-disabled.") - return - - message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) - - usr.emote("me",1,message,TRUE) - /mob/proc/say_dead(var/message) var/name = real_name var/alt_name = "" diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 377bb1c5fc..44dc3e2a05 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -23,7 +23,6 @@ proc/get_top_level_mob(var/mob/S) message = null mob_type_blacklist_typecache = list(/mob/living/brain) - /datum/emote/living/subtle/proc/check_invalid(mob/user, input) if(stop_bad_mime.Find(input, 1, 1)) to_chat(user, "Invalid emote.") @@ -130,6 +129,12 @@ proc/get_top_level_mob(var/mob/S) user.visible_message(message=message,self_message=message,vision_distance=1, ignored_mobs = GLOB.dead_mob_list) ///////////////// VERB CODE +/mob/living/proc/subtle_keybind() + var/message = input(src, "", "subtle") as text|null + if(!length(message)) + return + return subtle(message) + /mob/living/verb/subtle() set name = "Subtle" set category = "IC" diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index cf86e962bd..6be1afb5de 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -88,18 +88,20 @@ /mob/proc/add_eyeblur() if(!client) return - var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen - var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen - GW.add_filter("blurry_eyes", 2, EYE_BLUR(clamp(eye_blurry*0.1,0.6,3))) - F.add_filter("blurry_eyes", 2, EYE_BLUR(clamp(eye_blurry*0.1,0.6,3))) + var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"], + hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) + for(var/A in screens) + var/obj/screen/plane_master/P = A + P.add_filter("blurry_eyes", 2, EYE_BLUR(clamp(eye_blurry*0.1,0.6,3))) /mob/proc/remove_eyeblur() if(!client) return - var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen - var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen - GW.remove_filter("blurry_eyes") - F.remove_filter("blurry_eyes") + var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"], + hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) + for(var/A in screens) + var/obj/screen/plane_master/P = A + P.remove_filter("blurry_eyes") ///Adjust the drugginess of a mob /mob/proc/adjust_drugginess(amount) diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm new file mode 100644 index 0000000000..f28cbe4385 --- /dev/null +++ b/code/modules/mob/typing_indicator.dm @@ -0,0 +1,47 @@ +/// state = overlay/image/object/type/whatever add_overlay will accept +GLOBAL_LIST_EMPTY(typing_indicator_overlays) + +/// Fetches the typing indicator we'll use from GLOB.typing_indicator_overlays +/mob/proc/get_indicator_overlay(state) + . = GLOB.typing_indicator_overlays[state] + if(.) + return + // doesn't exist, make it and cache it + if(ispath(state)) + . = GLOB.typing_indicator_overlays[state] = state + // We only support paths for now because anything else isn't necessary yet. + +/// Gets the state we will use for typing indicators. Defaults to src.typing_indicator_state +/mob/proc/get_typing_indicator_icon_state() + return typing_indicator_state + +/** + * Displays typing indicator. + * @param timeout_override - Sets how long until this will disappear on its own without the user finishing their message or logging out. Defaults to src.typing_indicator_timeout + * @param state_override - Sets the state that we will fetch. Defaults to src.get_typing_indicator_icon_state() + * @param force - shows even if src.typing_indcator_enabled is FALSE. + */ +/mob/proc/display_typing_indicator(timeout_override = TYPING_INDICATOR_TIMEOUT, state_override = get_typing_indicator_icon_state(), force = FALSE) + if((!typing_indicator_enabled && !force) || typing_indicator_current) + return + typing_indicator_current = state_override + add_overlay(state_override) + typing_indicator_timerid = addtimer(CALLBACK(src, .proc/clear_typing_indicator), timeout_override, TIMER_STOPPABLE) + +/** + * Removes typing indicator. + */ +/mob/proc/clear_typing_indicator() + cut_overlay(typing_indicator_current) + typing_indicator_current = null + if(typing_indicator_timerid) + deltimer(typing_indicator_timerid) + typing_indicator_timerid = null + +/// Default typing indicator +/obj/effect/overlay/typing_indicator + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + icon = 'icons/mob/talk.dmi' + icon_state = "normal_typing" + appearance_flags = RESET_COLOR | TILE_BOUND | PIXEL_SCALE + layer = ABOVE_FLY_LAYER diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index aa60966591..d20fc4c6c0 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -24,7 +24,8 @@ variable = TRUE /datum/movespeed_modifier/damage_slowdown_flying - movetypes = FLOATING + movetypes = FLYING + blacklisted_movetypes = FLOATING variable = TRUE /datum/movespeed_modifier/equipment_speedmod diff --git a/code/modules/newscaster/newscaster_machine.dm b/code/modules/newscaster/newscaster_machine.dm index 95a24817a0..cb2d49fc64 100644 --- a/code/modules/newscaster/newscaster_machine.dm +++ b/code/modules/newscaster/newscaster_machine.dm @@ -12,6 +12,7 @@ GLOBAL_LIST_EMPTY(allCasters) desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!" icon = 'icons/obj/terminals.dmi' icon_state = "newscaster_normal" + plane = ABOVE_WALL_PLANE verb_say = "beeps" verb_ask = "beeps" verb_exclaim = "beeps" diff --git a/code/modules/paperwork/paper_premade.dm b/code/modules/paperwork/paper_premade.dm index 2d03a17e0a..23c8d47323 100644 --- a/code/modules/paperwork/paper_premade.dm +++ b/code/modules/paperwork/paper_premade.dm @@ -54,7 +54,7 @@ /obj/item/paper/guides/cogstation/job_changes name = "MEMO: Job Changes" - info = "To ensure minimal employee downtime, please take note of the following changes to select professions that Cogstation specifically requires:
\n
\n- Chemists are to have basic Research accessand an encryption key for the Science channel.
\n- Roboticists are to have basic Medical and Morgue access.
\n- Engineers and Atmospheric Technicians are to have Warehouse and Mining access.
\n- The Cook should not have Morgue access
\n- The Clown and Mime are to have Maintenance access. This is necessary due to the location of their offices.
\n
\nGenerated by Organic Resources Bot #2053" + info = "To ensure minimal employee downtime, please take note of the following changes to select professions that CogStation specifically requires:
\n
\n- Scientists are to have access to chemistry in order to reach the MedSci router.
\n
\n- Chemists should at the very least be provided with an encryption key for the Science channel, if not basic access to the Research department at large.
\n- Roboticists are to have basic Medical and Morgue access.
\n- Engineers and Atmospheric Technicians are to have Warehouse and Mining access.
\n- The Cook should not have Morgue access
\n- The Clown and Mime are to have Maintenance access. This is necessary due to the location of their offices.
\n
\nGenerated by Organic Resources Bot #2053" /obj/item/paper/guides/cogstation/letter_sec name = "To future Security personnel" @@ -86,7 +86,11 @@ /obj/item/paper/guides/cogstation/letter_eng name = "To future Engineering staff:" - info = "I'm not gonna sugarcoat this. Compared to other departments, you might have your work cut out for you. CogStation is an entirely different beast than your standard Box, but everyone's still gonna expect you to keep the place running.
\n
\n If there's any good news, it's your time to shine if you know how to run a thermo-electric generator. That's what this station runs on, and CentCom isn't planning on changing that. If it's absolutely critical you might be able to run a singularity or tesla engine east of mining, but it won't have any sort of shielding out there.
\n
\nThe air system's different too. It's multiple small networks instead of a single big one, with air hookups across the station. Fortunately it's not that complicated, but it comes at the expense of being able to filter out and reuse specific gases. Besides, you'll probably be busy enough with the engine and general upkeep anyway.
\n
\nThe disposal network in contrast is significantly more complicated, yet more capable. I've already elaborated on it, so I'll let you find and read my write-up for that. As for the routing system, it's just begging to get hit by a stray meteor so consider other utilities a higher priority.
\n
\nGood luck. You're gonna need it.
\n
\n-C. Donnelly
Architectural Analyst" + info = "I'm not gonna sugarcoat this. Compared to other departments, you might have your work cut out for you. CogStation is an entirely different beast than your standard Box, but everyone's still gonna expect you to keep the place running.
\n
\n If there's any good news, it's your time to shine if you know how to run a thermo-electric generator. That's what this station runs on, and that isn't likely to change anytime soon. If it's absolutely critical you might be able to run a singularity or tesla engine east of mining, but it won't have any sort of shielding out there.
\n
\nYou still have three solar arrays to work with, two of them being on each end of the starboard side. The port side array will need you to either get access from a head of staff or security, unless you want to spacewalk around the whole station. Don't be afraid to ask the latter - they're there for you, after all. As for other utilities the air system is a bit different than you'd expect, but fortunately you should have the atmos techs this station needed a long time ago. The disposal network is significantly more complicated, yet more capable. I've already elaborated on it, so I'll let you find and read my write-up for that. As for the routing system, it's just begging to get hit by a stray meteor so consider other utilities a higher priority.
\n
\nGood luck. You're gonna need it.
\n
\n-C. Donnelly
Architectural Analyst" + +/obj/item/paper/guides/cogstation/letter_atmos + name = "To future Atmospheric Technicians:" + info = "If the place that this station used to call home still hired atmos techs, odds are we could've gotten this place up and running a lot sooner. Alas, the past is in the past and the hard work's already been done. You still have a job to do, but it shouldn't be much different from other stations in this sector. That being said, be aware of the following:
\n
\n - If you haven't already noticed, the atmospherics department is separate from the rest of the station. You'll either need to spacewalk or take a transit tube to reach it, but it still connects to the station's air system at large.
\n
\n- Seeing as the TEG already uses the standard red and blue for it's heating/cooling loops, the scrubber pipes are ORANGE. The main air supply pipes are a purpleish-blue - HOWEVER, these aren't the only air pipes you'll see. We've decided to reuse existing lines from the old air hookup system - these pipes are CYAN and serve to supply air to specific areas. There's also a VIOLET line to help keep the TEG stable.
\n
\nNanotrasen's invested a considerable amount into updating this system, so even if Murphy's Law is alive and well in this sector, the air system isn't one of the things that should fail. If a section of the station is having air problems, check the old air hookups FIRST. Your problem could be as simple as a 'greytider' turning a valve or a clown hooking up a laughing gas canister.
\n
\n-C. Donnelly
Architectural Analyst" /obj/item/paper/guides/cogstation/letter_chief name = "To the future Chief Engineer:" @@ -112,6 +116,10 @@ name = "To the future Research Director" info = "Apologies if you were expecting a letter from the station's Research Director, but just prior to translocation we found out they were a BLF operative. I wouldn't trust a single word they wrote and while I'm not a scientist, something tells me your department will have the easiest time adjusting to this station.
\n
\nYou should have everything you need - this is a research facility after all. It's just a matter of finding it, which shouldn't be too hard. Folks like you are why we're out in deep space, after all!
\n-Louis Cannon
\nFormer Head of Security" +/obj/item/paper/fluff/cogstation/letter_arrd + name = "To the future Research Director" + info = "Listen, I doubt I need to tell you to how to do your job. From what I've heard this station is getting a state-of-the-art xenobiology lab after it gets translocated, and I don't know the first thing about what you guys do about those slimes. However, there's one thing I do know and it's that your station will have botanists.
\n
\nIt's crucial you give them everything they need, so long as they agree to maintain as many apiaries as humanely possible. I know it sounds ridiculous, but it's the ONLY way to keep the floor cluwnes at bay. If you don't know what a floor cluwne is, trust me when I say you do NOT want to find out!
\nJesse P.
\nFormer CogStation RD" + /obj/item/paper/fluff/cogstation/letter_cap name = "Captain's Log" info = "So I guess some of the other heads have decided to leave little notes for future employees here. Heartwarming, but the most important thing I figure I can leave you is the truth. Nevermind the Syndicate, the xenomorphs, the apocalyptic death cults I hear are a thing way out there - I'm convinced we are our own worst enemy.
\n
\nDon't believe me? Maybe you can ask Chief Engineer Earp. Oh right, he vaporized himself trying to produce enough power to keep the lights on in Space China for a week, despite only needing a sliver of that to run this place as intended. Or maybe you can ask Head of Security Cannon, who executed our Research Director in plain sight of everyone. Even if he was in the right, the final frontier isn't the goddamn wild west! Hell, maybe you can ask one of your 'staff assistants', although in my experience the only ones they seem to want to help is themselves.
\n
\nOf course, the REAL problems are with the higher-ups that stationed us on this deathtrap before deciding to send it your way, but there's only so much I can say and get away with it, for instance that they only sent this station since they could care less if it was a total loss. By the time you read this, I'll already be long gone. Maybe it'll be a different story with your crew, but between you and me, I wouldn't hold my breath...unless they fuck up the air system.
\n
\nDom Kahn
Former Captain of Nanotrasen CogStation" @@ -128,6 +136,18 @@ name = "Mysterious Note" info = "ThE rInGmAsTeR dOeSn'T rUn ThE cIrCus... HONK!!!" +/obj/item/paper/fluff/cogstation/secsolars + name = "A heads up:" + info = "I'm hoping you guys are aware of the access changes this station requires, but one thing they might have forgot to mention is that one of the station's solar arrays and air hookups are wedged squarely behind your department. Engineering might need to come through your department to access them.
\n
\nWhile I can imagine potential concerns, there shouldn't be any problems if both sides are transparent and communicative. The engineer is most likely there to do their job of keeping the station running, and will only need to pass through your department office and interrogation room (or alternatively, the bridge). You're free to get the doors for them and/or watch them work if it helps put your mind at ease. If they loiter or otherwise act suspiciously then you might want to have a word with them.
\n
\n-C. Donnelly
Architectural Analyst" + +/obj/item/paper/fluff/cogstation/eva + name = "MEMO: Spacesuits" + info = "As a Head of Personnel, you may be familiar with crew members requesting EVA access, particularly when there is an absence of credible threats on the station. While it is your decision to grant or deny access unless overriden by your superior(s), you should be aware of an abundance of spacesuits on this station. While intended for emergencies, these suits are cheaper to replace. You may find it beneficial to direct aspiring 'space explorers' towards finding one of these suits instead, although it is advised you order replacement suits in advance through the cargo department.
\n
\n-Generated by Organic Resources Bot #2053" + +/obj/item/paper/fluff/cogstation/chemists + name = "Re: Scientists?!" + info = "Scientists should have access to the chemistry lab. This is intentional as opposed to some sort of oversight - after all, they need to reach the medsci router somehow.
\n
\nIf anything you should see this as a blessing, as you won't need to sideline whatever it is you're doing to get them what they need. Your focus should remain on predominantly medical goods, just like other stations in this sector.
\n
\n- Dr. Halley" + /obj/item/paper/fluff/cogstation/mime name = "Au futur Mime" info = "Toutes mes excuses pour toute mauvaise grammaire, je ne suis pas un haut-parleur naturel Français et a dû utiliser NanoTranslate. Bien que vous puissiez être mécontent de l’emplacement de votre bureau, s’il vous plaît comprendre que c’était le seul endroit où nous pourrions le mettre sans problèmes de sécurité et/ou CentClown se plaindre à ce sujet. Nous nous excusons également pour l’absence d’une zone de performance dédiée, mais nous espérons que vous accorder un accès à l’entretien compensera.
\n
\n-C. Donnelly
\n
\nAnalyste Architectural" diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm index 67559c0381..11ad81ebf0 100644 --- a/code/modules/photography/photos/frame.dm +++ b/code/modules/photography/photos/frame.dm @@ -40,6 +40,7 @@ /obj/item/wallframe/picture/examine(mob/user) if(user.is_holding(src) && displayed) displayed.show(user) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) return list() return ..() @@ -109,6 +110,7 @@ /obj/structure/sign/picture_frame/examine(mob/user) if(in_range(src, user) && framed) framed.show(user) + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) return list() return ..() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index b3c94d4f43..0fb53501f9 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -48,7 +48,7 @@ /obj/machinery/power/apc name = "area power controller" desc = "A control terminal for the area's electrical systems." - + plane = ABOVE_WALL_PLANE icon_state = "apc0" use_power = NO_POWER_USE req_access = null diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index c8563c653f..0d674a2f77 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -39,6 +39,7 @@ By design, d1 is the smallest direction and d2 is the highest icon = 'icons/obj/power_cond/cables.dmi' icon_state = "0-1" level = 1 //is underfloor + plane = ABOVE_WALL_PLANE layer = WIRE_LAYER //Above hidden pipes, GAS_PIPE_HIDDEN_LAYER anchored = TRUE obj_flags = CAN_BE_HIT | ON_BLUEPRINTS diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index d2ffc216ba..d7513cf572 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -39,9 +39,9 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne if(prob(20)) set_broken() -/obj/machinery/gravity_generator/tesla_act(power, tesla_flags) +/obj/machinery/gravity_generator/zap_act(power, zap_flags) ..() - if(tesla_flags & TESLA_MACHINE_EXPLOSIVE) + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over /obj/machinery/gravity_generator/update_icon_state() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 181df7b07c..344d41071d 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -314,7 +314,7 @@ . = ..() SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(on && status == LIGHT_OK) - SSvis_overlays.add_vis_overlay(src, overlayicon, base_state, EMISSIVE_LAYER, EMISSIVE_PLANE, dir, clamp(light_power*250, 30, 200)) + SSvis_overlays.add_vis_overlay(src, overlayicon, base_state, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE, dir, clamp(light_power*250, 30, 200)) // update the icon_state and luminosity of the light depending on its state @@ -687,9 +687,9 @@ on = TRUE update() -/obj/machinery/light/tesla_act(power, tesla_flags) - if(tesla_flags & TESLA_MACHINE_EXPLOSIVE) - explosion(src,0,0,0,flame_range = 5, adminlog = 0) +/obj/machinery/light/zap_act(power, zap_flags) + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) + explosion(src,0,0,0,flame_range = 5, adminlog = FALSE) qdel(src) else return ..() diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index afbeef30a1..b558031fab 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -97,6 +97,7 @@ /obj/machinery/power/rtg/abductor/fire_act(exposed_temperature, exposed_volume) overload() -/obj/machinery/power/rtg/abductor/tesla_act() - ..() //extend the zap - overload() +/obj/machinery/power/rtg/abductor/zap_act(power, zap_flags, shocked_objects) + . = ..() //extend the zap + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) + overload() diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index ed3a098dae..8bf20fddc6 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -127,7 +127,7 @@ /obj/singularity/narsie/mezzer() - for(var/mob/living/carbon/M in viewers(consume_range, src)) + for(var/mob/living/carbon/M in fov_viewers(consume_range, src)) if(M.stat == CONSCIOUS) if(!iscultist(M)) to_chat(M, "You feel conscious thought crumble away in an instant as you gaze upon [src.name]...") diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 28e9194eef..1350c36348 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -433,7 +433,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) env.merge(removed) air_update_turf() - for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them. + for(var/mob/living/carbon/human/l in fov_viewers(HALLUCINATION_RANGE(power), src)) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) var/D = sqrt(1 / max(1, get_dist(l, src))) l.hallucination += power * config_hallucination_power * D @@ -559,14 +559,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) dust_mob(user, cause = "alien attack") /obj/machinery/power/supermatter_crystal/attack_animal(mob/living/simple_animal/S) - var/murder - if(!S.melee_damage_upper && !S.melee_damage_lower) - murder = S.friendly - else - murder = S.attacktext dust_mob(S, \ - "[S] unwisely [murder] [src], and [S.p_their()] body burns brilliantly before flashing into ash!", \ - "You unwisely touch [src], and your vision glows brightly as your body crumbles to dust. Oops.", \ + "[S] unwisely [S.attack_verb_continuous] [src], and [S.p_their()] body burns brilliantly before flashing into ash!", \ + "You unwisely [S.attack_verb_simple] [src], and your vision glows brightly as your body crumbles to dust. Oops.", \ "simple animal attack") /obj/machinery/power/supermatter_crystal/attack_robot(mob/user) @@ -666,9 +661,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //Some poor sod got eaten, go ahead and irradiate people nearby. radiation_pulse(src, 3000, 2, TRUE) + var/list/viewers = fov_viewers(world.view, src) for(var/mob/living/L in range(10)) investigate_log("has irradiated [key_name(L)] after consuming [AM].", INVESTIGATE_SUPERMATTER) - if(L in view()) + if(L in viewers) L.show_message("As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.", MSG_VISUAL,\ "The unearthly ringing subsides and you notice you have new radiation burns.", MSG_AUDIBLE) else diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 64d317b385..eb80548441 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -73,7 +73,7 @@ return ..() -/obj/machinery/power/tesla_coil/tesla_act(power, tesla_flags, shocked_targets) +/obj/machinery/power/tesla_coil/zap_act(power, zap_flags, shocked_targets) if(anchored && !panel_open) obj_flags |= BEING_SHOCKED //don't lose arc power when it's not connected to anything @@ -81,17 +81,17 @@ var/power_produced = powernet ? power / power_loss : power add_avail(power_produced*input_power_multiplier) flick("coilhit", src) - playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_produced, tesla_flags, shocked_targets) var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG) if(D) D.adjust_money(min(power_produced, 1)) if(istype(linked_techweb)) linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 1)) // x4 coils = ~240/m point bonus for R&D addtimer(CALLBACK(src, .proc/reset_shocked), 10) - tesla_buckle_check(power) + zap_buckle_check(power) + playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) + return power_produced else - ..() + . = ..() /obj/machinery/power/tesla_coil/proc/zap() if((last_zap + zap_cooldown) > world.time || !powernet) @@ -102,8 +102,8 @@ var/power = (powernet.avail/2) add_load(power) playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 10, power/(coeff/2), TESLA_FUSION_FLAGS) - tesla_buckle_check(power/(coeff/2)) + tesla_zap(src, 10, power/(coeff/2), ZAP_FUSION_FLAGS) + zap_buckle_check(power/(coeff/2)) // Tesla R&D researcher /obj/machinery/power/tesla_coil/research @@ -113,23 +113,23 @@ circuit = /obj/item/circuitboard/machine/tesla_coil/research power_loss = 20 // something something, high voltage + resistance -/obj/machinery/power/tesla_coil/research/tesla_act(power, tesla_flags, shocked_things) +/obj/machinery/power/tesla_coil/research/zap_act(power, zap_flags, shocked_targets) if(anchored && !panel_open) obj_flags |= BEING_SHOCKED var/power_produced = powernet ? power / power_loss : power add_avail(power_produced*input_power_multiplier) flick("rpcoilhit", src) - playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 5, power_produced, tesla_flags, shocked_things) var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG) if(D) D.adjust_money(min(power_produced, 3)) if(istype(linked_techweb)) linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 3)) // x4 coils with a pulse per second or so = ~720/m point bonus for R&D addtimer(CALLBACK(src, .proc/reset_shocked), 10) - tesla_buckle_check(power) + zap_buckle_check(power) + playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) + return power_produced else - ..() + . = ..() /obj/machinery/power/tesla_coil/research/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20) . = ..() @@ -180,9 +180,10 @@ return ..() -/obj/machinery/power/grounding_rod/tesla_act(var/power) +/obj/machinery/power/grounding_rod/zap_act(var/power) if(anchored && !panel_open) flick("grounding_rodhit", src) - tesla_buckle_check(power) + zap_buckle_check(power) + return 0 else - ..() + . = ..() diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index e98fe3c88e..06e5d27f6d 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -1,5 +1,14 @@ #define TESLA_DEFAULT_POWER 1738260 #define TESLA_MINI_POWER 869130 +//Zap constants, speeds up targeting +#define BIKE (COIL + 1) +#define COIL (ROD + 1) +#define ROD (RIDE + 1) +#define RIDE (LIVING + 1) +#define LIVING (MACHINERY + 1) +#define MACHINERY (BLOB + 1) +#define BLOB (STRUCTURE + 1) +#define STRUCTURE (1) /obj/singularity/energy_ball name = "energy ball" @@ -32,6 +41,9 @@ /obj/singularity/energy_ball/ex_act(severity, target) return +/obj/singularity/energy_ball/consume(severity, target) + return + /obj/singularity/energy_ball/Destroy() if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) var/obj/singularity/energy_ball/EB = orbiting.parent @@ -39,7 +51,7 @@ for(var/ball in orbiting_balls) var/obj/singularity/energy_ball/EB = ball - qdel(EB) + QDEL_NULL(EB) . = ..() @@ -55,12 +67,12 @@ move_the_basket_ball(4 + orbiting_balls.len * 1.5) - playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 30) + playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, TRUE, extrarange = 30) pixel_x = 0 pixel_y = 0 - tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE) + tesla_zap(src, 7, TESLA_DEFAULT_POWER) pixel_x = -32 pixel_y = -32 @@ -73,7 +85,7 @@ /obj/singularity/energy_ball/examine(mob/user) . = ..() if(orbiting_balls.len) - . += "The amount of orbiting mini-balls is [orbiting_balls.len]." + . += "There are [orbiting_balls.len] mini-balls orbiting it." /obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount) @@ -96,7 +108,7 @@ energy_to_lower = energy_to_raise - 20 energy_to_raise = energy_to_raise * 1.25 - playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 30) + playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, TRUE, extrarange = 30) addtimer(CALLBACK(src, .proc/new_mini_ball), 100) else if(energy < energy_to_lower && orbiting_balls.len) @@ -132,22 +144,19 @@ /obj/singularity/energy_ball/attack_tk(mob/user) if(iscarbon(user)) var/mob/living/carbon/C = user - log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a tesla ball.") to_chat(C, "That was a shockingly dumb idea.") - C.visible_message("A bright flare of lightning is seen from [C]'s head, shortly before you hear a sickening sizzling!") var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs - rip_u.Remove() + C.ghostize(0) qdel(rip_u) - return - return ..() + C.death() /obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target) if (istype(target)) target.orbiting_balls += src GLOB.poi_list -= src target.dissipate_strength = target.orbiting_balls.len - . = ..() + /obj/singularity/energy_ball/stop_orbit() if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball)) var/obj/singularity/energy_ball/orbitingball = orbiting.parent @@ -171,20 +180,19 @@ var/mob/living/carbon/C = A C.dust() -/proc/tesla_zap(atom/source, zap_range = 3, power, tesla_flags = TESLA_DEFAULT_FLAGS, list/shocked_targets) +/proc/tesla_zap(atom/source, zap_range = 3, power, zap_flags = ZAP_DEFAULT_FLAGS, list/shocked_targets) + if(QDELETED(source)) + return . = source.dir if(power < 1000) return - var/closest_dist = 0 - var/closest_atom - var/obj/machinery/power/tesla_coil/closest_tesla_coil - var/obj/machinery/power/grounding_rod/closest_grounding_rod - var/mob/living/closest_mob - var/obj/machinery/closest_machine - var/obj/structure/closest_structure - var/obj/structure/blob/closest_blob - var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure)) + /* + THIS IS SO FUCKING UGLY AND I HATE IT, but I can't make it nice without making it slower, check*N rather then n. So we're stuck with it. + */ + var/atom/closest_atom + var/closest_type = 0 + var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure, /obj/vehicle/ridden)) var/static/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics, /obj/machinery/power/emitter, /obj/machinery/field/generator, @@ -205,112 +213,133 @@ /obj/machinery/gateway, /obj/structure/lattice, /obj/structure/grille, - /obj/machinery/the_singularitygen/tesla, /obj/structure/frame/machine)) - for(var/A in typecache_filter_multi_list_exclusion(oview(source, zap_range+2), things_to_shock, blacklisted_tesla_types)) - if(!(tesla_flags & TESLA_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A)) + //Ok so we are making an assumption here. We assume that view() still calculates from the center out. + //This means that if we find an object we can assume it is the closest one of its type. This is somewhat of a speed increase. + //This also means we have no need to track distance, as the doview() proc does it all for us. + + //Darkness fucks oview up hard. I've tried dview() but it doesn't seem to work + //I hate existance + for(var/a in typecache_filter_multi_list_exclusion(oview(zap_range+2, source), things_to_shock, blacklisted_tesla_types)) + var/atom/A = a + if(!(zap_flags & ZAP_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A)) continue + if(closest_type >= BIKE) + break - if(istype(A, /obj/machinery/power/tesla_coil)) - var/dist = get_dist(source, A) - var/obj/machinery/power/tesla_coil/C = A - if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(C.obj_flags & BEING_SHOCKED)) - closest_dist = dist - + else if(istype(A, /obj/vehicle/ridden/bicycle))//God's not on our side cause he hates idiots. + var/obj/vehicle/ridden/bicycle/B = A + if(!(B.obj_flags & BEING_SHOCKED) && B.can_buckle)//Gee goof thanks for the boolean //we use both of these to save on istype and typecasting overhead later on //while still allowing common code to run before hand - closest_tesla_coil = C - closest_atom = C + closest_type = BIKE + closest_atom = B - - else if(closest_tesla_coil) + else if(closest_type >= COIL) continue //no need checking these other things - else if(istype(A, /obj/machinery/power/grounding_rod)) - var/dist = get_dist(source, A)-2 - if(dist <= zap_range && (dist < closest_dist || !closest_grounding_rod)) - closest_grounding_rod = A - closest_atom = A - closest_dist = dist + else if(istype(A, /obj/machinery/power/tesla_coil)) + var/obj/machinery/power/tesla_coil/C = A + if(!(C.obj_flags & BEING_SHOCKED)) + closest_type = COIL + closest_atom = C - else if(closest_grounding_rod) + else if(closest_type >= ROD) + continue + + else if(istype(A, /obj/machinery/power/grounding_rod)) + closest_type = ROD + closest_atom = A + + else if(closest_type >= RIDE) + continue + + else if(istype(A,/obj/vehicle/ridden)) + var/obj/vehicle/ridden/R = A + if(R.can_buckle && !(R.obj_flags & BEING_SHOCKED)) + closest_type = RIDE + closest_atom = A + + else if(closest_type >= LIVING) continue else if(isliving(A)) - var/dist = get_dist(source, A) var/mob/living/L = A - if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.flags_1 & TESLA_IGNORE_1)) - closest_mob = L + if(L.stat != DEAD && !(HAS_TRAIT(L, TRAIT_TESLA_SHOCKIMMUNE)) && !(L.flags_1 & SHOCKED_1)) + closest_type = LIVING closest_atom = A - closest_dist = dist - else if(closest_mob) + else if(closest_type >= MACHINERY) continue else if(ismachinery(A)) var/obj/machinery/M = A - var/dist = get_dist(source, A) - if(dist <= zap_range && (dist < closest_dist || !closest_machine) && !(M.obj_flags & BEING_SHOCKED)) - closest_machine = M + if(!(M.obj_flags & BEING_SHOCKED)) + closest_type = MACHINERY closest_atom = A - closest_dist = dist - else if(closest_mob) + else if(closest_type >= BLOB) continue else if(istype(A, /obj/structure/blob)) var/obj/structure/blob/B = A - var/dist = get_dist(source, A) - if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(B.obj_flags & BEING_SHOCKED)) - closest_blob = B + if(!(B.obj_flags & BEING_SHOCKED)) + closest_type = BLOB closest_atom = A - closest_dist = dist - else if(closest_blob) + else if(closest_type >= STRUCTURE) continue else if(isstructure(A)) var/obj/structure/S = A - var/dist = get_dist(source, A) - if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(S.obj_flags & BEING_SHOCKED)) - closest_structure = S + if(!(S.obj_flags & BEING_SHOCKED)) + closest_type = STRUCTURE closest_atom = A - closest_dist = dist //Alright, we've done our loop, now lets see if was anything interesting in range - if(closest_atom) - //common stuff - source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY) - if(!(tesla_flags & TESLA_ALLOW_DUPLICATES)) - LAZYSET(shocked_targets, closest_atom, TRUE) - var/zapdir = get_dir(source, closest_atom) - if(zapdir) - . = zapdir + if(!closest_atom) + return + //common stuff + source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY) + if(!(zap_flags & ZAP_ALLOW_DUPLICATES)) + LAZYSET(shocked_targets, closest_atom, TRUE) + var/zapdir = get_dir(source, closest_atom) + if(zapdir) + . = zapdir - //per type stuff: - if(closest_tesla_coil) - closest_tesla_coil.tesla_act(power, tesla_flags, shocked_targets) + var/next_range = 3 + if(closest_type == COIL) + next_range = 5 - else if(closest_grounding_rod) - closest_grounding_rod.tesla_act(power, tesla_flags, shocked_targets) - - else if(closest_mob) - var/shock_damage = (tesla_flags & TESLA_MOB_DAMAGE)? (min(round(power/600), 90) + rand(-5, 5)) : 0 - closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((tesla_flags & TESLA_MOB_STUN) ? NONE : SHOCK_NOSTUN)) + if(closest_type == LIVING) + var/mob/living/closest_mob = closest_atom + closest_mob.set_shocked() + addtimer(CALLBACK(closest_mob, /mob/living/proc/reset_shocked), 10) + var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/600), 90) + rand(-5, 5)) : 0 + closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((zap_flags & ZAP_MOB_STUN) ? NONE : SHOCK_NOSTUN)) if(issilicon(closest_mob)) var/mob/living/silicon/S = closest_mob - if((tesla_flags & TESLA_MOB_STUN) && (tesla_flags & TESLA_MOB_DAMAGE)) + if((zap_flags & ZAP_MOB_STUN) && (zap_flags & ZAP_MOB_DAMAGE)) S.emp_act(EMP_LIGHT) - tesla_zap(S, 7, power / 1.5, tesla_flags, shocked_targets) // metallic folks bounce it further + next_range = 7 // metallic folks bounce it further else - tesla_zap(closest_mob, 5, power / 1.5, tesla_flags, shocked_targets) + next_range = 5 + power /= 1.5 - else if(closest_machine) - closest_machine.tesla_act(power, tesla_flags, shocked_targets) + else + power = closest_atom.zap_act(power, zap_flags, shocked_targets) + if(prob(20))//I know I know + tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets) + tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets) + else + tesla_zap(closest_atom, next_range, power, zap_flags, shocked_targets) - else if(closest_blob) - closest_blob.tesla_act(power, tesla_flags, shocked_targets) - - else if(closest_structure) - closest_structure.tesla_act(power, tesla_flags, shocked_targets) +#undef BIKE +#undef COIL +#undef ROD +#undef RIDE +#undef LIVING +#undef MACHINERY +#undef BLOB +#undef STRUCTURE diff --git a/code/modules/power/tesla/generator.dm b/code/modules/power/tesla/generator.dm index 53d7010806..260f4128bc 100644 --- a/code/modules/power/tesla/generator.dm +++ b/code/modules/power/tesla/generator.dm @@ -5,6 +5,6 @@ icon_state = "TheSingGen" creation_type = /obj/singularity/energy_ball -/obj/machinery/the_singularitygen/tesla/tesla_act(power, tesla_flags) - if(tesla_flags & TESLA_MACHINE_EXPLOSIVE) +/obj/machinery/the_singularitygen/tesla/zap_act(power, zap_flags) + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) energy += power diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm index 848163d658..1a6786524c 100644 --- a/code/modules/projectiles/ammunition/_firing.dm +++ b/code/modules/projectiles/ammunition/_firing.dm @@ -31,6 +31,10 @@ else BB.def_zone = user.zone_selected BB.suppressed = quiet + + if(isgun(fired_from)) + var/obj/item/gun/G = fired_from + BB.damage *= G.projectile_damage_multiplier if(reagents && BB.reagents) reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 9c1a23174e..cf9e606ffc 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -76,6 +76,9 @@ var/datum/action/item_action/toggle_scope_zoom/azoom var/dualwield_spread_mult = 1 //dualwield spread multiplier + + /// Just 'slightly' snowflakey way to modify projectile damage for projectiles fired from this gun. + var/projectile_damage_multiplier = 1 /obj/item/gun/Initialize() . = ..() diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm index 3f3d2c6f47..4bd7d34fe2 100644 --- a/code/modules/projectiles/guns/ballistic/bow.dm +++ b/code/modules/projectiles/guns/ballistic/bow.dm @@ -59,7 +59,7 @@ /obj/item/gun/ballistic/bow/pipe name = "pipe bow" - desc = "Some sort of pipe made projectile weapon made of a silk string and lots of bending. Used to fire arrows." + desc = "Some sort of pipe made projectile weapon made of a durathread string and lots of bending. Used to fire arrows." icon_state = "pipebow" item_state = "pipebow" force = 0 diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm index 2439cee429..1afbdeae25 100644 --- a/code/modules/projectiles/projectile/energy/tesla.dm +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -3,7 +3,7 @@ icon_state = "tesla_projectile" impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser var/chain - var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE + var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE var/zap_range = 3 var/power = 10000 @@ -15,7 +15,7 @@ /obj/item/projectile/energy/tesla/on_hit(atom/target) . = ..() - tesla_zap(target, zap_range, power, tesla_flags) + tesla_zap(target, zap_range, power, zap_flags) qdel(src) /obj/item/projectile/energy/tesla/Destroy() diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index ff6340bcdb..dbb1497367 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -437,9 +437,9 @@ speed = 0.3 flag = "magic" - var/tesla_power = 20000 - var/tesla_range = 15 - var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_MOB_STUN | TESLA_OBJ_DAMAGE + var/zap_power = 20000 + var/zap_range = 15 + var/zap_flags = ZAP_MOB_DAMAGE | ZAP_MOB_STUN | ZAP_OBJ_DAMAGE var/chain var/mob/living/caster @@ -456,7 +456,7 @@ visible_message("[src] fizzles on contact with [target]!") qdel(src) return BULLET_ACT_BLOCK - tesla_zap(src, tesla_range, tesla_power, tesla_flags) + tesla_zap(src, zap_range, zap_power, zap_flags) qdel(src) /obj/item/projectile/magic/aoe/lightning/Destroy() diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm index 3aa85c085f..19fd13857a 100644 --- a/code/modules/projectiles/projectile/special/hallucination.dm +++ b/code/modules/projectiles/projectile/special/hallucination.dm @@ -50,7 +50,7 @@ if(M == hal_target) to_chat(hal_target, "[M] is hit by \a [src] in the chest!") hal_apply_effect() - else if(M in view(hal_target)) + else if(M in hal_target.fov_view()) to_chat(hal_target, "[M] is hit by \a [src] in the chest!!") if(damage_type == BRUTE) var/splatter_dir = dir diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index f4c06f39cc..38aafc665f 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -535,7 +535,7 @@ add_reagent(P, cached_results[P]*multiplier, null, chem_temp) - var/list/seen = viewers(4, get_turf(my_atom))//Sound and sight checkers + var/list/seen = fov_viewers(4, get_turf(my_atom))//Sound and sight checkers var/iconhtml = icon2html(cached_my_atom, seen) if(cached_my_atom) if(!ismob(cached_my_atom)) // No bubbling mobs @@ -617,10 +617,7 @@ handle_reactions() update_total() //Reaction sounds and words - var/list/seen = viewers(5, get_turf(my_atom)) - var/iconhtml = icon2html(my_atom, seen) - for(var/mob/M in seen) - to_chat(M, "[iconhtml] [C.mix_message]") + my_atom.visible_message("[icon2html(my_atom, viewers(DEFAULT_MESSAGE_RANGE, src))] [C.mix_message]") /datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier) var/datum/chemical_reaction/C = selected_reaction diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 6da592a56c..09ba0762cf 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -510,12 +510,10 @@ /datum/reagent/consumable/peachjuice ) emagged_reagents = list( - /datum/reagent/consumable/ethanol/thirteenloko, - /datum/reagent/consumable/ethanol/changelingsting, - /datum/reagent/consumable/ethanol/whiskey_cola, /datum/reagent/toxin/mindbreaker, /datum/reagent/toxin/staminatoxin, - /datum/reagent/medicine/cryoxadone + /datum/reagent/medicine/cryoxadone, + /datum/reagent/iron ) /obj/machinery/chem_dispenser/drinks/fullupgrade //fully ugpraded stock parts, emagged @@ -570,11 +568,12 @@ upgrade_reagents2 = null upgrade_reagents3 = null emagged_reagents = list( - /datum/reagent/iron, /datum/reagent/consumable/ethanol/alexander, /datum/reagent/consumable/clownstears, /datum/reagent/toxin/minttoxin, - /datum/reagent/consumable/ethanol/atomicbomb + /datum/reagent/consumable/ethanol/atomicbomb, + /datum/reagent/consumable/ethanol/thirteenloko, + /datum/reagent/consumable/ethanol/changelingsting ) /obj/machinery/chem_dispenser/drinks/beer/fullupgrade //fully ugpraded stock parts, emagged diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index a6f5468c74..4a4bbdb546 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -170,7 +170,7 @@ if(!A.mutable) return if(A) - var/new_name = sanitize_name(html_encode(params["name"])) + var/new_name = sanitize_name(html_encode(trim(params["name"], 50))) if(!new_name || ..()) return A.AssignName(new_name) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 67ff61610d..50d94a637e 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -227,6 +227,18 @@ playsound(M, "sparks", 50, 1) ..() +/datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/L) + . = ..() + if(!istype(L)) + return + L.physiology.siemens_coeff *= 2 + +/datum/reagent/teslium/on_mob_end_metabolize(mob/living/carbon/human/L) + . = ..() + if(!istype(L)) + return + L.physiology.siemens_coeff *= 0.5 + /datum/reagent/teslium/energized_jelly name = "Energized Jelly" description = "Electrically-charged jelly. Boosts jellypeople's nervous system, but only shocks other lifeforms." diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 141367c9d9..3ba883a2c7 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -765,7 +765,9 @@ /datum/reagent/toxin/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) if(current_cycle >= 20 && current_cycle%20 == 0) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) + var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], + M.hud_used.plane_masters["[LIGHTING_PLANE]"], M.hud_used.plane_masters["[WALL_PLANE]"], + M.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) var/rotation = min(round(current_cycle/20), 89) // By this point the player is probably puking and quitting anyway for(var/whole_screen in screens) animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) @@ -793,15 +795,17 @@ /* if(M.hud_used) if(current_cycle >= 5 && current_cycle % 3 == 0) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) - var/matrix/skew = matrix() + var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], + M.hud_used.plane_masters["[LIGHTING_PLANE]"], M.hud_used.plane_masters["[WALL_PLANE]"], + M.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]) var/matrix/skew = matrix() var/intensity = 8 skew.set_skew(rand(-intensity,intensity), rand(-intensity,intensity)) var/matrix/newmatrix = skew if(prob(33)) // 1/3rd of the time, let's make it stack with the previous matrix! Mwhahahaha! - var/obj/screen/plane_master/PM = M.hud_used.plane_masters["[GAME_PLANE]"] - newmatrix = skew * PM.transform + for(var/whole_screen in screens) + var/obj/screen/plane_master/PM = whole_screen + newmatrix = skew * PM.transform for(var/whole_screen in screens) animate(whole_screen, transform = newmatrix, time = 5, easing = QUAD_EASING, loop = -1) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index ce1940994d..618ac256e2 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -440,9 +440,8 @@ mob_react = FALSE /datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, multiplier) - var/location = get_turf(holder.my_atom) - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out foam!") + var/turf/location = get_turf(holder.my_atom) + location.visible_message("The solution spews out foam!") var/datum/effect_system/foam_spread/s = new() s.set_up(multiplier*2, location, holder) s.start() @@ -457,11 +456,8 @@ mob_react = FALSE /datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, multiplier) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metallic foam!") - + var/turf/location = get_turf(holder.my_atom) + location.visible_message("The solution spews out a metallic foam!") var/datum/effect_system/foam_spread/metal/s = new() s.set_up(multiplier*5, location, holder, 1) s.start() @@ -488,9 +484,8 @@ mob_react = FALSE /datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, multiplier) - var/location = get_turf(holder.my_atom) - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metallic foam!") + var/turf/location = get_turf(holder.my_atom) + location.visible_message("The solution spews out metallic foam!") var/datum/effect_system/foam_spread/metal/s = new() s.set_up(multiplier*5, location, holder, 2) s.start() diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 8782d65f76..1d06aaacde 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -429,7 +429,7 @@ noexplosion = TRUE mix_message = "The teslium starts to spark as electricity arcs away from it!" mix_sound = 'sound/machines/defib_zap.ogg' - var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN + var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN /datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, multiplier) var/T1 = multiplier * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison. @@ -437,15 +437,15 @@ var/T3 = multiplier * 120 sleep(5) if(multiplier >= 75) - tesla_zap(holder.my_atom, 7, T1, tesla_flags) + tesla_zap(holder.my_atom, 7, T1, zap_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) sleep(15) if(multiplier >= 40) - tesla_zap(holder.my_atom, 7, T2, tesla_flags) + tesla_zap(holder.my_atom, 7, T2, zap_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) sleep(15) if(multiplier >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast. - tesla_zap(holder.my_atom, 7, T3, tesla_flags) + tesla_zap(holder.my_atom, 7, T3, zap_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) ..() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index f326b94e44..fbdbb5f656 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -160,11 +160,8 @@ /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) reagents.expose_temperature(1000) if(container_flags & TEMP_WEAK) - var/list/seen = viewers(5, get_turf(src)) - var/iconhtml = icon2html(src, seen) - for(var/mob/H in seen) - to_chat(H, "[iconhtml] \The [src]'s melts from the temperature!") - playsound(get_turf(src), 'sound/FermiChem/heatmelt.ogg', 80, 1) + visible_message("[icon2html(src, viewers(DEFAULT_MESSAGE_RANGE, src))] [src]'s melts from the temperature!") + playsound(src, 'sound/FermiChem/heatmelt.ogg', 80, 1) qdel(src) ..() @@ -184,7 +181,7 @@ if((reagents.pH < 1.5) || (reagents.pH > 12.5)) START_PROCESSING(SSobj, src) else if((reagents.pH < -3) || (reagents.pH > 17)) - visible_message("[icon2html(src, viewers(src))] \The [src] is damaged by the super pH and begins to deform!") + visible_message("[icon2html(src, viewers(DEFAULT_MESSAGE_RANGE, src))] \The [src] is damaged by the super pH and begins to deform!") reagents.pH = clamp(reagents.pH, -3, 17) container_HP -= 1 @@ -221,15 +218,11 @@ container_HP -= damage - var/list/seen = viewers(5, get_turf(src)) - var/iconhtml = icon2html(src, seen) - var/damage_percent = ((container_HP / initial(container_HP)*100)) switch(damage_percent) if(-INFINITY to 0) - for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [src]'s melts [cause]!") - playsound(get_turf(src), 'sound/FermiChem/acidmelt.ogg', 80, 1) + visible_message("[icon2html(src, viewers(DEFAULT_MESSAGE_RANGE, src))] [src]'s melts [cause]!") + playsound(src, 'sound/FermiChem/acidmelt.ogg', 80, 1) SSblackbox.record_feedback("tally", "fermi_chem", 1, "Times beakers have melted") STOP_PROCESSING(SSobj, src) qdel(src) @@ -246,5 +239,4 @@ update_icon() if(prob(25)) - for(var/mob/M in seen) - to_chat(M, "[iconhtml] \The [src]'s is damaged by [cause] and begins to deform!") + visible_message("[icon2html(src, viewers(DEFAULT_MESSAGE_RANGE, src))] [src]'s is damaged by [cause] and begins to deform!") diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index e6fa18ba9c..36e3b0d47e 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -72,9 +72,8 @@ to_chat(user, "[target] is full.") return - to_chat(user, "You dissolve [src] in [target].") - for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius - to_chat(O, "[user] slips something into [target]!") + user.visible_message("[user] slips something into [target]!", + "You dissolve [src] in [target].", vision_distance = 2) reagents.trans_to(target, reagents.total_volume) qdel(src) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 54ec327fdb..9ef08590a8 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -120,9 +120,10 @@ /obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume) boom() -/obj/structure/reagent_dispensers/fueltank/tesla_act() +/obj/structure/reagent_dispensers/fueltank/zap_act(power, zap_flags, shocked_objects) ..() //extend the zap - boom() + if(ZAP_OBJ_DAMAGE & zap_flags) + boom() /obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P) . = ..() @@ -169,6 +170,7 @@ name = "pepper spray refiller" desc = "Contains condensed capsaicin for use in law \"enforcement.\"" icon_state = "pepper" + plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE reagent_id = /datum/reagent/consumable/condensedcapsaicin @@ -182,6 +184,7 @@ name = "virus food dispenser" desc = "A dispenser of low-potency virus mutagenic." icon_state = "virus_food" + plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE reagent_id = /datum/reagent/consumable/virus_food diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index aed2310a7f..45d3d9da25 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -14,6 +14,7 @@ max_integrity = 200 armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes + plane = ABOVE_WALL_PLANE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE var/dpdir = NONE // bitmask of pipe directions var/initialize_dirs = NONE // bitflags of pipe directions added on init, see \code\_DEFINES\pipe_construction.dm diff --git a/code/modules/research/designs/autobotter_designs.dm b/code/modules/research/designs/autobotter_designs.dm index eab7423b91..c2ff7c953b 100644 --- a/code/modules/research/designs/autobotter_designs.dm +++ b/code/modules/research/designs/autobotter_designs.dm @@ -14,7 +14,7 @@ /datum/design/bottle materials = list(/datum/material/glass = 1200) build_type = AUTOBOTTLER - category = list("Storge") + category = list("Storage") /datum/design/bottle/wine name = "Bottle Design (Wine)" @@ -331,4 +331,4 @@ id = "greenroad" reagents_list = list(/datum/reagent/consumable/vitfro = 50, /datum/reagent/consumable/ethanol/rum = 30, /datum/reagent/ash = 10) category = list("Beers") - build_path = /obj/item/export/bottle/greenroad \ No newline at end of file + build_path = /obj/item/export/bottle/greenroad diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm index f6c31a9808..330dfb8f8a 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -139,7 +139,7 @@ id = "tool_box" build_type = AUTOLATHE materials = list(MAT_CATEGORY_RIGID = 500) - build_path = /obj/item/storage/toolbox + build_path = /obj/item/storage/toolbox/greyscale category = list("initial","Tools") /datum/design/spraycan diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 5405b82848..69bf039428 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -238,7 +238,7 @@ /datum/design/bodybag name = "Body Bag" - desc = "A normal body bag used for storge of dead crew." + desc = "A normal body bag used for storage of dead crew." id = "bodybag" build_type = PROTOLATHE materials = list(/datum/material/plastic = 4000) diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 93168e17c7..07679fe1ce 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -91,7 +91,7 @@ /datum/design/mag_oldsmg name = "WT-550 Semi-Auto SMG Magazine (4.6x30mm)" - desc = "A 20 round magazine for the out of date security WT-550 Semi-Auto SMG." + desc = "A 32 round magazine for the out of date security WT-550 Semi-Auto SMG." id = "mag_oldsmg" build_type = PROTOLATHE materials = list(/datum/material/iron = 4000) @@ -101,7 +101,7 @@ /datum/design/mag_oldsmg/ap_mag name = "WT-550 Semi-Auto SMG Armour Piercing Magazine (4.6x30mm AP)" - desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." + desc = "A 32 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." id = "mag_oldsmg_ap" materials = list(/datum/material/iron = 6000, /datum/material/silver = 600) build_path = /obj/item/ammo_box/magazine/wt550m9/wtap @@ -109,7 +109,7 @@ /datum/design/mag_oldsmg/ic_mag name = "WT-550 Semi-Auto SMG Incendiary Magazine (4.6x30mm IC)" - desc = "A 20 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." + desc = "A 32 round armour piercing magazine for the out of date security WT-550 Semi-Auto SMG." id = "mag_oldsmg_ic" materials = list(/datum/material/iron = 6000, /datum/material/silver = 600, /datum/material/glass = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic @@ -117,7 +117,7 @@ /datum/design/mag_oldsmg/tx_mag name = "WT-550 Semi-Auto SMG Uranium Magazine (4.6x30mm TX)" - desc = "A 20 round uranium tipped magazine for the out of date security WT-550 Semi-Auto SMG." + desc = "A 32 round uranium tipped magazine for the out of date security WT-550 Semi-Auto SMG." id = "mag_oldsmg_tx" materials = list(/datum/material/iron = 6000, /datum/material/silver = 600, /datum/material/uranium = 2000) build_path = /obj/item/ammo_box/magazine/wt550m9/wttx @@ -125,7 +125,7 @@ /datum/design/mag_oldsmg/rubber_mag name = "WT-550 Semi-Auto SMG rubberbullets Magazine (4.6x30mm rubber)" - desc = "A 20 round rubber shots magazine for the out of date security WT-550 Semi-Auto SMG" + desc = "A 32 round rubber shots magazine for the out of date security WT-550 Semi-Auto SMG" id = "mag_oldsmg_rubber" materials = list(/datum/material/iron = 6000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtrubber diff --git a/code/modules/ruins/spaceruin_code/clericsden.dm b/code/modules/ruins/spaceruin_code/clericsden.dm index 67e071b274..7d1fda6740 100644 --- a/code/modules/ruins/spaceruin_code/clericsden.dm +++ b/code/modules/ruins/spaceruin_code/clericsden.dm @@ -27,7 +27,8 @@ melee_damage_lower = 8 melee_damage_upper = 10 retreat_distance = 4 //AI proteons will rapidly move in and out of combat to avoid conflict, but will still target and follow you. - attacktext = "pinches" + attack_verb_continuous = "pinches" + attack_verb_simple = "pinch" environment_smash = ENVIRONMENT_SMASH_WALLS attack_sound = 'sound/weapons/punch2.ogg' playstyle_string = "You are a Proteon. Your abilities in combat are outmatched by most combat constructs, but you are still fast and nimble. Run metal and supplies, and cooperate with your fellow cultists." diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index d01a6de8ed..43dba451dd 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -9,6 +9,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) desc = "This device is used to trigger station functions, which require more than one ID card to authenticate." icon = 'icons/obj/monitors.dmi' icon_state = "auth_off" + plane = ABOVE_WALL_PLANE use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm index 1a904b1076..8fab4a221d 100644 --- a/code/modules/spells/spell_types/aimed.dm +++ b/code/modules/spells/spell_types/aimed.dm @@ -101,7 +101,7 @@ base_icon_state = "lightning" sound = 'sound/magic/lightningbolt.ogg' active = FALSE - projectile_var_overrides = list("tesla_range" = 15, "tesla_power" = 20000, "tesla_flags" = TESLA_MOB_DAMAGE) + projectile_var_overrides = list("zap_range" = 15, "zap_power" = 20000, "zap_flags" = ZAP_MOB_DAMAGE) active_msg = "You energize your hand with arcane lightning!" deactive_msg = "You let the energy flow out of your hands back into yourself..." projectile_type = /obj/item/projectile/magic/aoe/lightning diff --git a/code/modules/surgery/advanced/bioware/nerve_grounding.dm b/code/modules/surgery/advanced/bioware/nerve_grounding.dm index 99902ff6d6..eb70a838a4 100644 --- a/code/modules/surgery/advanced/bioware/nerve_grounding.dm +++ b/code/modules/surgery/advanced/bioware/nerve_grounding.dm @@ -32,13 +32,11 @@ name = "Grounded Nerves" desc = "Nerves form a safe path for electricity to traverse, protecting the body from electric shocks." mod_type = BIOWARE_NERVES - var/prev_coeff /datum/bioware/grounded_nerves/on_gain() ..() - prev_coeff = owner.physiology.siemens_coeff - owner.physiology.siemens_coeff = 0 + ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves") /datum/bioware/grounded_nerves/on_lose() ..() - owner.physiology.siemens_coeff = prev_coeff + REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves") diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index f574b0aea3..e287b38ca1 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -57,10 +57,11 @@ surgery.step_in_progress = FALSE return FALSE if(tool) - speed_mod = tool.toolspeed + speed_mod = tool.toolspeed //faster tools mean faster surgeries, but also less experience. if(user.mind) - speed_mod = user.mind.skill_holder.action_skills_mod(/datum/skill/numerical/surgery, speed_mod, THRESHOLD_COMPETENT, FALSE) - if(do_after(user, time * speed_mod, target = target)) + speed_mod = user.mind.action_skill_mod(/datum/skill/numerical/surgery, speed_mod, THRESHOLD_UNTRAINED, FALSE) + var/delay = time * speed_mod + if(do_after(user, delay, target = target)) var/prob_chance = 100 if(implement_type) //this means it isn't a require hand or any item step. prob_chance = implements[implement_type] @@ -68,7 +69,10 @@ if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail) if(success(user, target, target_zone, tool, surgery)) - user.mind?.skill_holder.auto_gain_experience(/datum/skill/numerical/surgery, SKILL_GAIN_SURGERY_PER_STEP) + var/multi = (delay/SKILL_GAIN_DELAY_DIVISOR) + if(repeatable) + multi *= 0.5 //Spammable surgeries award less experience. + user.mind?.auto_gain_experience(/datum/skill/numerical/surgery, SKILL_GAIN_SURGERY_PER_STEP * multi) advance = TRUE else if(failure(user, target, target_zone, tool, surgery)) diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm index 70252cfb49..a74c9bbab2 100644 --- a/code/modules/tgs/core/core.dm +++ b/code/modules/tgs/core/core.dm @@ -1,11 +1,17 @@ /world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) var/current_api = TGS_READ_GLOBAL(tgs) if(current_api) - TGS_ERROR_LOG("TgsNew(): TGS API datum already set ([current_api])! Was TgsNew() called more than once?") + TGS_ERROR_LOG("API datum already set (\ref[current_api] ([current_api]))! Was TgsNew() called more than once?") + return + + if(!(minimum_required_security_level in list(TGS_SECURITY_ULTRASAFE, TGS_SECURITY_SAFE, TGS_SECURITY_TRUSTED))) + TGS_ERROR_LOG("Invalid minimum_required_security_level: [minimum_required_security_level]!") return #ifdef TGS_V3_API - minimum_required_security_level = TGS_SECURITY_TRUSTED + if(minimum_required_security_level != TGS_SECURITY_TRUSTED) + TGS_WARNING_LOG("V3 DMAPI requires trusted security!") + minimum_required_security_level = TGS_SECURITY_TRUSTED #endif var/raw_parameter = world.params[TGS_VERSION_PARAMETER] if(!raw_parameter) @@ -13,7 +19,7 @@ var/datum/tgs_version/version = new(raw_parameter) if(!version.Valid(FALSE)) - TGS_ERROR_LOG("Failed to validate TGS version parameter: [raw_parameter]!") + TGS_ERROR_LOG("Failed to validate DMAPI version parameter: [raw_parameter]!") return var/api_datum @@ -21,18 +27,21 @@ if(3) #ifndef TGS_V3_API TGS_ERROR_LOG("Detected V3 API but TGS_V3_API isn't defined!") + return #else - switch(version.major) + switch(version.minor) if(2) api_datum = /datum/tgs_api/v3210 #endif if(4) - switch(version.major) + switch(version.minor) if(0) api_datum = /datum/tgs_api/v4 + if(5) + api_datum = /datum/tgs_api/v5 var/datum/tgs_version/max_api_version = TgsMaximumAPIVersion(); - if(version.suite != null && version.major != null && version.minor != null && version.patch != null && version.deprefixed_parameter > max_api_version.deprefixed_parameter) + if(version.suite != null && version.minor != null && version.patch != null && version.deprecated_patch != null && version.deprefixed_parameter > max_api_version.deprefixed_parameter) TGS_ERROR_LOG("Detected unknown API version! Defaulting to latest. Update the DMAPI to fix this problem.") api_datum = /datum/tgs_api/latest @@ -41,20 +50,25 @@ return TGS_INFO_LOG("Activating API for version [version.deprefixed_parameter]") - var/datum/tgs_api/new_api = new api_datum(version) + + if(event_handler && !istype(event_handler)) + TGS_ERROR_LOG("Invalid parameter for event_handler: [event_handler]") + event_handler = null + + var/datum/tgs_api/new_api = new api_datum(event_handler, version) TGS_WRITE_GLOBAL(tgs, new_api) - var/result = new_api.OnWorldNew(event_handler, minimum_required_security_level) + var/result = new_api.OnWorldNew(minimum_required_security_level) if(!result || result == TGS_UNIMPLEMENTED) TGS_WRITE_GLOBAL(tgs, null) TGS_ERROR_LOG("Failed to activate API!") /world/TgsMaximumAPIVersion() - return new /datum/tgs_version("4.0.x.x") + return new /datum/tgs_version("5.x.x") /world/TgsMinimumAPIVersion() - return new /datum/tgs_version("3.2.0.0") + return new /datum/tgs_version("3.2.x") /world/TgsInitializationComplete() var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) @@ -88,6 +102,11 @@ if(api) return api.version +/world/TgsApiVersion() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + return api.ApiVersion() + /world/TgsInstanceName() var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) if(api) diff --git a/code/modules/tgs/core/datum.dm b/code/modules/tgs/core/datum.dm index fb2508059a..ccc75fe344 100644 --- a/code/modules/tgs/core/datum.dm +++ b/code/modules/tgs/core/datum.dm @@ -2,13 +2,15 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null) /datum/tgs_api var/datum/tgs_version/version + var/datum/tgs_event_handler/event_handler -/datum/tgs_api/New(datum/tgs_version/version) +/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version) . = ..() + src.event_handler = event_handler src.version = version /datum/tgs_api/latest - parent_type = /datum/tgs_api/v4 + parent_type = /datum/tgs_api/v5 TGS_PROTECT_DATUM(/datum/tgs_api) diff --git a/code/modules/tgs/core/tgs_version.dm b/code/modules/tgs/core/tgs_version.dm index b97745611f..a5dae1241a 100644 --- a/code/modules/tgs/core/tgs_version.dm +++ b/code/modules/tgs/core/tgs_version.dm @@ -5,11 +5,11 @@ suite = text2num(version_bits[1]) if(version_bits.len > 1) - major = text2num(version_bits[2]) + minor = text2num(version_bits[2]) if(version_bits.len > 2) - minor = text2num(version_bits[3]) + patch = text2num(version_bits[3]) if(version_bits.len == 4) - patch = text2num(version_bits[4]) + deprecated_patch = text2num(version_bits[4]) /datum/tgs_version/proc/Valid(allow_wildcards = FALSE) if(suite == null) @@ -19,4 +19,10 @@ return !Wildcard() /datum/tgs_version/Wildcard() - return major == null || minor == null || patch == null + return minor == null || patch == null + +/datum/tgs_version/Equals(datum/tgs_version/other_version) + if(!istype(other_version)) + return FALSE + + return suite == other_version.suite && minor == other_version.minor && patch == other_version.patch && deprecated_patch == other_version.deprecated_patch diff --git a/code/modules/tgs/includes.dm b/code/modules/tgs/includes.dm index 247f1fda5d..b3c1728f34 100644 --- a/code/modules/tgs/includes.dm +++ b/code/modules/tgs/includes.dm @@ -2,9 +2,43 @@ #include "core\core.dm" #include "core\datum.dm" #include "core\tgs_version.dm" + #ifdef TGS_V3_API #include "v3210\api.dm" #include "v3210\commands.dm" #endif + #include "v4\api.dm" #include "v4\commands.dm" + +#include "v5\_defines.dm" +#include "v5\api.dm" +#include "v5\commands.dm" +#include "v5\undef.dm" + +/* +The MIT License + +Copyright (c) 2017 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/tgs/v3210/api.dm b/code/modules/tgs/v3210/api.dm index c536995b04..0fc0076c8b 100644 --- a/code/modules/tgs/v3210/api.dm +++ b/code/modules/tgs/v3210/api.dm @@ -39,7 +39,7 @@ var/warned_custom_commands = FALSE /datum/tgs_api/v3210/ApiVersion() - return "3.2.1.0" + return new /datum/tgs_version("3.2.1.0") /datum/tgs_api/v3210/proc/trim_left(text) for (var/i = 1 to length(text)) @@ -56,7 +56,7 @@ /datum/tgs_api/v3210/proc/file2list(filename) return splittext(trim_left(trim_right(file2text(filename))), "\n") -/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level) //don't use event handling in this version +/datum/tgs_api/v3210/OnWorldNew(minimum_required_security_level) . = FALSE comms_key = world.params[SERVICE_WORLD_PARAM] @@ -76,7 +76,8 @@ TGS_ERROR_LOG("This API version is only supported on Windows. Not running on Windows. Aborting initialization!") return ListServiceCustomCommands(TRUE) - ExportService("[SERVICE_REQUEST_API_VERSION] [ApiVersion()]", TRUE) + var/datum/tgs_version/api_version = ApiVersion() + ExportService("[SERVICE_REQUEST_API_VERSION] [api_version.deprefixed_parameter]", TRUE) return TRUE //nothing to do for v3 @@ -166,7 +167,8 @@ /datum/tgs_api/v3210/Revision() if(!warned_revison) - TGS_ERROR_LOG("Use of TgsRevision on [ApiVersion()] origin_commit only points to master!") + var/datum/tgs_version/api_version = ApiVersion() + TGS_ERROR_LOG("Use of TgsRevision on [api_version.deprefixed_parameter] origin_commit only points to master!") warned_revison = TRUE var/datum/tgs_revision_information/ri = new ri.commit = commit diff --git a/code/modules/tgs/v3210/commands.dm b/code/modules/tgs/v3210/commands.dm index e5bc6f4895..5046631981 100644 --- a/code/modules/tgs/v3210/commands.dm +++ b/code/modules/tgs/v3210/commands.dm @@ -19,7 +19,7 @@ TGS_ERROR_LOG("Custom command [command_name] can't be used as it is empty or contains illegal characters!") warned_command_names[command_name] = TRUE continue - + if(command_name_types[command_name]) if(warnings_only) TGS_ERROR_LOG("Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!") @@ -55,24 +55,24 @@ The MIT License Copyright (c) 2017 Jordan Brown -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ diff --git a/code/modules/tgs/v4/api.dm b/code/modules/tgs/v4/api.dm index b61cddbeba..ba18aab688 100644 --- a/code/modules/tgs/v4/api.dm +++ b/code/modules/tgs/v4/api.dm @@ -43,15 +43,13 @@ var/list/cached_test_merges var/datum/tgs_revision_information/cached_revision - var/datum/tgs_event_handler/event_handler - var/export_lock = FALSE var/list/last_interop_response /datum/tgs_api/v4/ApiVersion() - return "4.0.0.0" + return new /datum/tgs_version("4.0.0.0") -/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level) +/datum/tgs_api/v4/OnWorldNew(minimum_required_security_level) json_path = world.params[TGS4_PARAM_INFO_JSON] if(!json_path) TGS_ERROR_LOG("Missing [TGS4_PARAM_INFO_JSON] world parameter!") @@ -76,7 +74,6 @@ security_level = cached_json["securityLevel"] chat_channels_json_path = cached_json["chatChannelsJson"] chat_commands_json_path = cached_json["chatCommandsJson"] - src.event_handler = event_handler instance_name = cached_json["instanceName"] ListCustomCommands() diff --git a/code/modules/tgs/v4/commands.dm b/code/modules/tgs/v4/commands.dm index af21a86fb6..1d9951bc04 100644 --- a/code/modules/tgs/v4/commands.dm +++ b/code/modules/tgs/v4/commands.dm @@ -46,24 +46,24 @@ The MIT License Copyright (c) 2017 Jordan Brown -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm new file mode 100644 index 0000000000..2baf3e12d7 --- /dev/null +++ b/code/modules/tgs/v5/_defines.dm @@ -0,0 +1,124 @@ +#define DMAPI5_PARAM_SERVER_PORT "tgs_port" +#define DMAPI5_PARAM_ACCESS_IDENTIFIER "tgs_key" + +#define DMAPI5_BRIDGE_DATA "data" +#define DMAPI5_TOPIC_DATA "tgs_data" + +#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0 +#define DMAPI5_BRIDGE_COMMAND_STARTUP 1 +#define DMAPI5_BRIDGE_COMMAND_PRIME 2 +#define DMAPI5_BRIDGE_COMMAND_REBOOT 3 +#define DMAPI5_BRIDGE_COMMAND_KILL 4 +#define DMAPI5_BRIDGE_COMMAND_CHAT_SEND 5 + +#define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier" +#define DMAPI5_RESPONSE_ERROR_MESSAGE "errorMessage" + +#define DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE "commandType" +#define DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT "currentPort" +#define DMAPI5_BRIDGE_PARAMETER_VERSION "version" +#define DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE "chatMessage" +#define DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS "customCommands" +#define DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL "minimumSecurityLevel" + +#define DMAPI5_BRIDGE_RESPONSE_NEW_PORT "newPort" +#define DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION "runtimeInformation" + +#define DMAPI5_CHAT_MESSAGE_TEXT "text" +#define DMAPI5_CHAT_MESSAGE_CHANNEL_IDS "channelIds" + +#define DMAPI5_RUNTIME_INFORMATION_ACCESS_IDENTIFIER "accessIdentifier" +#define DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION "serverVersion" +#define DMAPI5_RUNTIME_INFORMATION_SERVER_PORT "serverPort" +#define DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY "apiValidateOnly" +#define DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME "instanceName" +#define DMAPI5_RUNTIME_INFORMATION_REVISION "revision" +#define DMAPI5_RUNTIME_INFORMATION_TEST_MERGES "testMerges" +#define DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL "securityLevel" + +#define DMAPI5_CHAT_UPDATE_CHANNELS "channels" + +#define DMAPI5_TEST_MERGE_TIME_MERGED "timeMerged" +#define DMAPI5_TEST_MERGE_REVISION "revision" +#define DMAPI5_TEST_MERGE_TITLE_AT_MERGE "titleAtMerge" +#define DMAPI5_TEST_MERGE_BODY_AT_MERGE "bodyAtMerge" +#define DMAPI5_TEST_MERGE_URL "url" +#define DMAPI5_TEST_MERGE_AUTHOR "author" +#define DMAPI5_TEST_MERGE_NUMBER "number" +#define DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION "pullRequestRevision" +#define DMAPI5_TEST_MERGE_COMMENT "comment" + +#define DMAPI5_CHAT_COMMAND_NAME "name" +#define DMAPI5_CHAT_COMMAND_PARAMS "params" +#define DMAPI5_CHAT_COMMAND_USER "user" + +#define DMAPI5_EVENT_NOTIFICATION_TYPE "type" +#define DMAPI5_EVENT_NOTIFICATION_PARAMETERS "parameters" + +#define DMAPI5_TOPIC_COMMAND_CHAT_COMMAND 0 +#define DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION 1 +#define DMAPI5_TOPIC_COMMAND_CHANGE_PORT 2 +#define DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE 3 +#define DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED 4 +#define DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE 5 +#define DMAPI5_TOPIC_COMMAND_SERVER_PORT_UPDATE 6 +#define DMAPI5_TOPIC_COMMAND_HEARTBEAT 7 +#define DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH 8 + +#define DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE "commandType" +#define DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND "chatCommand" +#define DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION "eventNotification" +#define DMAPI5_TOPIC_PARAMETER_NEW_PORT "newPort" +#define DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE "newRebootState" +#define DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME "newInstanceName" +#define DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE "chatUpdate" +#define DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION "newServerVersion" + +#define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE "commandResponseMessage" +#define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses" + +#define DMAPI5_REVISION_INFORMATION_COMMIT_SHA "commitSha" +#define DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA "originCommitSha" + +#define DMAPI5_CHAT_USER_ID "id" +#define DMAPI5_CHAT_USER_FRIENDLY_NAME "friendlyName" +#define DMAPI5_CHAT_USER_MENTION "mention" +#define DMAPI5_CHAT_USER_CHANNEL "channel" + +#define DMAPI5_CHAT_CHANNEL_ID "id" +#define DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME "friendlyName" +#define DMAPI5_CHAT_CHANNEL_CONNECTION_NAME "connectionName" +#define DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL "isAdminChannel" +#define DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL "isPrivateChannel" +#define DMAPI5_CHAT_CHANNEL_TAG "tag" + +#define DMAPI5_CUSTOM_CHAT_COMMAND_NAME "name" +#define DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT "helpText" +#define DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY "adminOnly" + +/* +The MIT License + +Copyright (c) 2020 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm new file mode 100644 index 0000000000..eedefb2877 --- /dev/null +++ b/code/modules/tgs/v5/api.dm @@ -0,0 +1,372 @@ +/datum/tgs_api/v5 + var/server_port + var/access_identifier + + var/instance_name + var/security_level + + var/reboot_mode = TGS_REBOOT_MODE_NORMAL + + var/list/intercepted_message_queue + + var/list/custom_commands + + var/list/test_merges + var/datum/tgs_revision_information/revision + var/list/chat_channels + +/datum/tgs_api/v5/ApiVersion() + return new /datum/tgs_version("5.1.1") + +/datum/tgs_api/v5/OnWorldNew(minimum_required_security_level) + server_port = world.params[DMAPI5_PARAM_SERVER_PORT] + access_identifier = world.params[DMAPI5_PARAM_ACCESS_IDENTIFIER] + + var/datum/tgs_version/api_version = ApiVersion() + version = null + var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands())) + if(!istype(bridge_response)) + TGS_ERROR_LOG("Failed initial bridge request!") + return FALSE + + var/list/runtime_information = bridge_response[DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION] + if(!istype(runtime_information)) + TGS_ERROR_LOG("Failed to decode runtime information from bridge response: [json_encode(bridge_response)]!") + return FALSE + + if(runtime_information[DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY]) + TGS_INFO_LOG("DMAPI validation, exiting...") + del(world) + + version = new /datum/tgs_version(runtime_information[DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION]) + security_level = runtime_information[DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL] + instance_name = runtime_information[DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME] + + var/list/revisionData = runtime_information[DMAPI5_RUNTIME_INFORMATION_REVISION] + if(istype(revisionData)) + revision = new + revision.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA] + revision.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA] + else + TGS_ERROR_LOG("Failed to decode [DMAPI5_RUNTIME_INFORMATION_REVISION] from runtime information!") + + test_merges = list() + var/list/test_merge_json = runtime_information[DMAPI5_RUNTIME_INFORMATION_TEST_MERGES] + if(istype(test_merge_json)) + for(var/entry in test_merge_json) + var/datum/tgs_revision_information/test_merge/tm = new + tm.number = entry[DMAPI5_TEST_MERGE_NUMBER] + + var/list/revInfo = entry[DMAPI5_TEST_MERGE_REVISION] + if(revInfo) + tm.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA] + tm.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA] + else + TGS_WARNING_LOG("Failed to decode [DMAPI5_TEST_MERGE_REVISION] from test merge #[tm.number]!") + + tm.time_merged = text2num(entry[DMAPI5_TEST_MERGE_TIME_MERGED]) + tm.title = entry[DMAPI5_TEST_MERGE_TITLE_AT_MERGE] + tm.body = entry[DMAPI5_TEST_MERGE_BODY_AT_MERGE] + tm.url = entry[DMAPI5_TEST_MERGE_URL] + tm.author = entry[DMAPI5_TEST_MERGE_AUTHOR] + tm.pull_request_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION] + tm.comment = entry[DMAPI5_TEST_MERGE_COMMENT] + + test_merges += tm + else + TGS_WARNING_LOG("Failed to decode [DMAPI5_RUNTIME_INFORMATION_TEST_MERGES] from runtime information!") + + chat_channels = list() + DecodeChannels(runtime_information) + + return TRUE + +/datum/tgs_api/v5/proc/RequireInitialBridgeResponse() + while(!version) + sleep(1) + +/datum/tgs_api/v5/OnInitializationComplete() + Bridge(DMAPI5_BRIDGE_COMMAND_PRIME) + + var/tgs4_secret_sleep_offline_sauce = 29051994 + var/old_sleep_offline = world.sleep_offline + world.sleep_offline = tgs4_secret_sleep_offline_sauce + sleep(1) + if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it + world.sleep_offline = old_sleep_offline + +/datum/tgs_api/v5/proc/TopicResponse(error_message = null) + var/list/response = list() + response[DMAPI5_RESPONSE_ERROR_MESSAGE] = error_message + + return json_encode(response) + +/datum/tgs_api/v5/OnTopic(T) + var/list/params = params2list(T) + var/json = params[DMAPI5_TOPIC_DATA] + if(!json) + return FALSE //continue world/Topic + + var/list/topic_parameters = json_decode(json) + if(!topic_parameters) + return TopicResponse("Invalid topic parameters json!"); + + var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER] + if(their_sCK != access_identifier) + return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] from: [json]!"); + + var/command = topic_parameters[DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE] + if(!isnum(command)) + return TopicResponse("Failed to decode [DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE] from: [json]!") + + switch(command) + if(DMAPI5_TOPIC_COMMAND_CHAT_COMMAND) + var/result = HandleCustomCommand(topic_parameters[DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND]) + if(!result) + result = TopicResponse("Error running chat command!") + return result + if(DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION) + intercepted_message_queue = list() + var/list/event_notification = topic_parameters[DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION] + if(!istype(event_notification)) + return TopicResponse("Invalid [DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]!") + + var/event_type = event_notification[DMAPI5_EVENT_NOTIFICATION_TYPE] + if(!isnum(event_type)) + return TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_TYPE]!") + + var/list/event_parameters = event_notification[DMAPI5_EVENT_NOTIFICATION_PARAMETERS] + if(event_parameters && !istype(event_parameters)) + return TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_PARAMETERS]!") + + var/list/event_call = list(event_type) + if(event_parameters) + event_call += event_parameters + + if(event_handler != null) + event_handler.HandleEvent(arglist(event_call)) + + var/list/response = list() + response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue + intercepted_message_queue = null + return json_encode(response) + if(DMAPI5_TOPIC_COMMAND_CHANGE_PORT) + var/new_port = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT] + if (!isnum(new_port) || !(new_port > 0)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_PORT]]") + + if(event_handler != null) + event_handler.HandleEvent(TGS_EVENT_PORT_SWAP, new_port) + + //the topic still completes, miraculously + //I honestly didn't believe byond could do it without exploding + if(!world.OpenPort(new_port)) + return TopicResponse("Port change failed!") + + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE) + var/new_reboot_mode = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE] + if(!isnum(new_reboot_mode)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE]!") + + if(event_handler != null) + event_handler.HandleEvent(TGS_EVENT_REBOOT_MODE_CHANGE, reboot_mode, new_reboot_mode) + + reboot_mode = new_reboot_mode + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED) + var/new_instance_name = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME] + if(!istext(new_instance_name)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME]!") + + if(event_handler != null) + event_handler.HandleEvent(TGS_EVENT_INSTANCE_RENAMED, new_instance_name) + + instance_name = new_instance_name + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE) + var/list/chat_update_json = topic_parameters[DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE] + if(!istype(chat_update_json)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]!") + + DecodeChannels(chat_update_json) + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_SERVER_PORT_UPDATE) + var/new_port = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT] + if (!isnum(new_port) || !(new_port > 0)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_PORT]]") + + server_port = new_port + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_HEARTBEAT) + return TopicResponse() + if(DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH) + var/new_version_string = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION] + if (!istext(new_version_string)) + return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION]]") + + var/datum/tgs_version/new_version = new(new_version_string) + if (event_handler) + event_handler.HandleEvent(TGS_EVENT_WATCHDOG_REATTACH, new_version) + + version = new_version + + return TopicResponse() + + return TopicResponse("Unknown command: [command]") + +/datum/tgs_api/v5/proc/Bridge(command, list/data) + if(!data) + data = list() + + data[DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE] = command + data[DMAPI5_PARAMETER_ACCESS_IDENTIFIER] = access_identifier + + var/json = json_encode(data) + var/encoded_json = url_encode(json) + + // This is an infinite sleep until we get a response + var/export_response = world.Export("http://127.0.0.1:[server_port]/Bridge?[DMAPI5_BRIDGE_DATA]=[encoded_json]") + if(!export_response) + TGS_ERROR_LOG("Failed export request: [json]") + return + + var/response_json = file2text(export_response["CONTENT"]) + if(!response_json) + TGS_ERROR_LOG("Failed export request, missing content!") + return + + var/list/bridge_response = json_decode(response_json) + if(!bridge_response) + TGS_ERROR_LOG("Failed export request, bad json: [response_json]") + return + + var/error = bridge_response[DMAPI5_RESPONSE_ERROR_MESSAGE] + if(error) + TGS_ERROR_LOG("Failed export request, bad request: [error]") + return + + return bridge_response + +/datum/tgs_api/v5/OnReboot() + var/list/result = Bridge(DMAPI5_BRIDGE_COMMAND_REBOOT) + if(!result) + return + + //okay so the standard TGS4 proceedure is: right before rebooting change the port to whatever was sent to us in the above json's data parameter + + var/port = result[DMAPI5_BRIDGE_RESPONSE_NEW_PORT] + if(!isnum(port)) + return //this is valid, server may just want use to reboot + + if(port == 0) + //to byond 0 means any port and "none" means close vOv + port = "none" + + if(!world.OpenPort(port)) + TGS_ERROR_LOG("Unable to set port to [port]!") + +/datum/tgs_api/v5/InstanceName() + RequireInitialBridgeResponse() + return instance_name + +/datum/tgs_api/v5/TestMerges() + RequireInitialBridgeResponse() + return test_merges + +/datum/tgs_api/v5/EndProcess() + Bridge(DMAPI5_BRIDGE_COMMAND_KILL) + +/datum/tgs_api/v5/Revision() + RequireInitialBridgeResponse() + return revision + +/datum/tgs_api/v5/ChatBroadcast(message, list/channels) + if(!length(channels)) + channels = ChatChannelInfo() + + var/list/ids = list() + for(var/I in channels) + var/datum/tgs_chat_channel/channel = I + ids += channel.id + + message = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = ids) + if(intercepted_message_queue) + intercepted_message_queue += list(message) + else + Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message)) + +/datum/tgs_api/v5/ChatTargetedBroadcast(message, admin_only) + var/list/channels = list() + for(var/I in ChatChannelInfo()) + var/datum/tgs_chat_channel/channel = I + if (!channel.is_private_channel && ((channel.is_admin_channel && admin_only) || (!channel.is_admin_channel && !admin_only))) + channels += channel.id + message = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = channels) + if(intercepted_message_queue) + intercepted_message_queue += list(message) + else + Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message)) + +/datum/tgs_api/v5/ChatPrivateMessage(message, datum/tgs_chat_user/user) + message = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = list(user.channel.id)) + if(intercepted_message_queue) + intercepted_message_queue += list(message) + else + Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message)) + +/datum/tgs_api/v5/ChatChannelInfo() + RequireInitialBridgeResponse() + return chat_channels + +/datum/tgs_api/v5/proc/DecodeChannels(chat_update_json) + var/list/chat_channels_json = chat_update_json[DMAPI5_CHAT_UPDATE_CHANNELS] + if(istype(chat_channels_json)) + chat_channels.Cut() + for(var/channel_json in chat_channels_json) + var/datum/tgs_chat_channel/channel = DecodeChannel(channel_json) + if(channel) + chat_channels += channel + else + TGS_WARNING_LOG("Failed to decode [DMAPI5_CHAT_UPDATE_CHANNELS] from channel update!") + +/datum/tgs_api/v5/proc/DecodeChannel(channel_json) + var/datum/tgs_chat_channel/channel = new + channel.id = channel_json[DMAPI5_CHAT_CHANNEL_ID] + channel.friendly_name = channel_json[DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME] + channel.connection_name = channel_json[DMAPI5_CHAT_CHANNEL_CONNECTION_NAME] + channel.is_admin_channel = channel_json[DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL] + channel.is_private_channel = channel_json[DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL] + channel.custom_tag = channel_json[DMAPI5_CHAT_CHANNEL_TAG] + return channel + +/datum/tgs_api/v5/SecurityLevel() + RequireInitialBridgeResponse() + return security_level + +/* +The MIT License + +Copyright (c) 2020 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/tgs/v5/commands.dm b/code/modules/tgs/v5/commands.dm new file mode 100644 index 0000000000..2775157656 --- /dev/null +++ b/code/modules/tgs/v5/commands.dm @@ -0,0 +1,68 @@ +/datum/tgs_api/v5/proc/ListCustomCommands() + var/results = list() + custom_commands = list() + for(var/I in typesof(/datum/tgs_chat_command) - /datum/tgs_chat_command) + var/datum/tgs_chat_command/stc = new I + var/command_name = stc.name + if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\"")) + TGS_WARNING_LOG("Custom command [command_name] ([I]) can't be used as it is empty or contains illegal characters!") + continue + + if(results[command_name]) + var/datum/other = custom_commands[command_name] + TGS_WARNING_LOG("Custom commands [other.type] and [I] have the same name (\"[command_name]\"), only [other.type] will be available!") + continue + results += list(list(DMAPI5_CUSTOM_CHAT_COMMAND_NAME = command_name, DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT = stc.help_text, DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY = stc.admin_only)) + custom_commands[command_name] = stc + + return results + +/datum/tgs_api/v5/proc/HandleCustomCommand(list/command_json) + var/command = command_json[DMAPI5_CHAT_COMMAND_NAME] + var/user = command_json[DMAPI5_CHAT_COMMAND_USER] + var/params = command_json[DMAPI5_CHAT_COMMAND_PARAMS] + + var/datum/tgs_chat_user/u = new + u.id = user[DMAPI5_CHAT_USER_ID] + u.friendly_name = user[DMAPI5_CHAT_USER_FRIENDLY_NAME] + u.mention = user[DMAPI5_CHAT_USER_MENTION] + u.channel = DecodeChannel(user[DMAPI5_CHAT_USER_CHANNEL]) + + var/datum/tgs_chat_command/sc = custom_commands[command] + if(sc) + var/text_response = sc.Run(u, params) + var/list/topic_response = list() + if(!istext(text_response)) + TGS_ERROR_LOG("Custom command [command] should return a string! Got: \"[text_response]\"") + text_response = null + topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = text_response + return json_encode(topic_response) + return TopicResponse("Unknown custom chat command: [command]!") + +/* + +The MIT License + +Copyright (c) 2020 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/tgs/v5/undef.dm b/code/modules/tgs/v5/undef.dm new file mode 100644 index 0000000000..b27e3abe95 --- /dev/null +++ b/code/modules/tgs/v5/undef.dm @@ -0,0 +1,124 @@ +#undef DMAPI5_PARAM_SERVER_PORT +#undef DMAPI5_PARAM_ACCESS_IDENTIFIER + +#undef DMAPI5_BRIDGE_DATA +#undef DMAPI5_TOPIC_DATA + +#undef DMAPI5_BRIDGE_COMMAND_PORT_UPDATE +#undef DMAPI5_BRIDGE_COMMAND_STARTUP +#undef DMAPI5_BRIDGE_COMMAND_PRIME +#undef DMAPI5_BRIDGE_COMMAND_REBOOT +#undef DMAPI5_BRIDGE_COMMAND_KILL +#undef DMAPI5_BRIDGE_COMMAND_CHAT_SEND + +#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER +#undef DMAPI5_RESPONSE_ERROR_MESSAGE + +#undef DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE +#undef DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT +#undef DMAPI5_BRIDGE_PARAMETER_VERSION +#undef DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE +#undef DMAPI5_BRIDGE_PARAMETER_CUSTOM_COMMANDS +#undef DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL + +#undef DMAPI5_BRIDGE_RESPONSE_NEW_PORT +#undef DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION + +#undef DMAPI5_CHAT_MESSAGE_TEXT +#undef DMAPI5_CHAT_MESSAGE_CHANNEL_IDS + +#undef DMAPI5_RUNTIME_INFORMATION_ACCESS_IDENTIFIER +#undef DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION +#undef DMAPI5_RUNTIME_INFORMATION_SERVER_PORT +#undef DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY +#undef DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME +#undef DMAPI5_RUNTIME_INFORMATION_REVISION +#undef DMAPI5_RUNTIME_INFORMATION_TEST_MERGES +#undef DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL + +#undef DMAPI5_CHAT_UPDATE_CHANNELS + +#undef DMAPI5_TEST_MERGE_TIME_MERGED +#undef DMAPI5_TEST_MERGE_REVISION +#undef DMAPI5_TEST_MERGE_TITLE_AT_MERGE +#undef DMAPI5_TEST_MERGE_BODY_AT_MERGE +#undef DMAPI5_TEST_MERGE_URL +#undef DMAPI5_TEST_MERGE_AUTHOR +#undef DMAPI5_TEST_MERGE_NUMBER +#undef DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION +#undef DMAPI5_TEST_MERGE_COMMENT + +#undef DMAPI5_CHAT_COMMAND_NAME +#undef DMAPI5_CHAT_COMMAND_PARAMS +#undef DMAPI5_CHAT_COMMAND_USER + +#undef DMAPI5_EVENT_NOTIFICATION_TYPE +#undef DMAPI5_EVENT_NOTIFICATION_PARAMETERS + +#undef DMAPI5_TOPIC_COMMAND_CHAT_COMMAND +#undef DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION +#undef DMAPI5_TOPIC_COMMAND_CHANGE_PORT +#undef DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE +#undef DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED +#undef DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE +#undef DMAPI5_TOPIC_COMMAND_SERVER_PORT_UPDATE +#undef DMAPI5_TOPIC_COMMAND_HEARTBEAT +#undef DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH + +#undef DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE +#undef DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND +#undef DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION +#undef DMAPI5_TOPIC_PARAMETER_NEW_PORT +#undef DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE +#undef DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME +#undef DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE +#undef DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION + +#undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE +#undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES + +#undef DMAPI5_REVISION_INFORMATION_COMMIT_SHA +#undef DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA + +#undef DMAPI5_CHAT_USER_ID +#undef DMAPI5_CHAT_USER_FRIENDLY_NAME +#undef DMAPI5_CHAT_USER_MENTION +#undef DMAPI5_CHAT_USER_CHANNEL + +#undef DMAPI5_CHAT_CHANNEL_ID +#undef DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME +#undef DMAPI5_CHAT_CHANNEL_CONNECTION_NAME +#undef DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL +#undef DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL +#undef DMAPI5_CHAT_CHANNEL_TAG + +#undef DMAPI5_CUSTOM_CHAT_COMMAND_NAME +#undef DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT +#undef DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY + +/* +The MIT License + +Copyright (c) 2020 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index d4fa226a90..2d20fd0b7b 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -280,4 +280,6 @@ item = /obj/item/suspiciousphone cost = 7 restricted = TRUE + limited_stock = 1 */ + diff --git a/code/modules/vehicles/bicycle.dm b/code/modules/vehicles/bicycle.dm index 84e0fcbefc..3784f4d459 100644 --- a/code/modules/vehicles/bicycle.dm +++ b/code/modules/vehicles/bicycle.dm @@ -24,10 +24,12 @@ buckled_mob.stop_sound_channel(CHANNEL_BICYCLE) . =..() -/obj/vehicle/ridden/bicycle/tesla_act() // :::^^^))) +/obj/vehicle/ridden/bicycle/zap_act(zap_str, zap_flags, shocked_targets) // :::^^^))) + //This didn't work for 3 years because none ever tested it I hate life name = "fried bicycle" desc = "Well spent." color = rgb(63, 23, 4) can_buckle = FALSE + . = ..() for(var/m in buckled_mobs) unbuckle_mob(m,1) diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index 4f3970dd37..f71d9367d3 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -77,3 +77,7 @@ if(!force && occupant_amount() >= max_occupants) return FALSE return ..() + +/obj/vehicle/ridden/zap_act(zap_str, zap_flags, shocked_targets) + zap_buckle_check(zap_str) + . = ..() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index fc81e2ec00..edaab8b982 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,5 +1,6 @@ /obj/vehicle/sealed var/enter_delay = 20 + flags_1 = BLOCK_FACE_ATOM_1 /obj/vehicle/sealed/generate_actions() . = ..() @@ -51,7 +52,7 @@ if(randomstep) var/turf/target_turf = get_step(exit_location(M), pick(GLOB.cardinals)) M.throw_at(target_turf, 5, 10) - + if(!silent) M.visible_message("[M] drops out of \the [src]!") return TRUE @@ -102,7 +103,13 @@ if(iscarbon(i)) var/mob/living/carbon/C = i C.DefaultCombatKnockdown(40) - - + + /obj/vehicle/sealed/AllowDrop() return FALSE + +/obj/vehicle/sealed/setDir(newdir) + . = ..() + for(var/k in occupants) + var/mob/M = k + M.setDir(newdir) diff --git a/code/modules/vending/dinnerware.dm b/code/modules/vending/dinnerware.dm index e780104b1e..521e76b5e2 100644 --- a/code/modules/vending/dinnerware.dm +++ b/code/modules/vending/dinnerware.dm @@ -20,12 +20,10 @@ /obj/item/reagent_containers/food/condiment/saltshaker = 5, /obj/item/reagent_containers/food/condiment/peppermill = 5) contraband = list( - /obj/item/reagent_containers/food/snacks/cube/monkey= 1, /obj/item/kitchen/knife/butcher = 2, /obj/item/reagent_containers/syringe = 3) premium = list( - /obj/item/reagent_containers/food/condiment/enzyme = 1, - /obj/item/reagent_containers/glass/bottle/cryoxadone = 2) // Bartender can literally make this with upgraded parts, or it gets stolen from medical. + /obj/item/reagent_containers/food/condiment/enzyme = 1) armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) refill_canister = /obj/item/vending_refill/dinnerware resistance_flags = FIRE_PROOF @@ -35,4 +33,4 @@ cost_multiplier_per_dept = list(ACCOUNT_SRV = 0) /obj/item/vending_refill/dinnerware - icon_state = "refill_cook" \ No newline at end of file + icon_state = "refill_cook" diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index f8759bd8f4..df1e5eaba8 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -27,6 +27,7 @@ /obj/item/seeds/orange = 3, /obj/item/seeds/peach = 3, /obj/item/seeds/peanutseed = 3, + /obj/item/seeds/peas = 3, /obj/item/seeds/pineapple = 3, /obj/item/seeds/potato = 3, /obj/item/seeds/poppy = 3, diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm index 685f8d76bb..03d0bbba45 100644 --- a/code/modules/vore/eating/belly_obj.dm +++ b/code/modules/vore/eating/belly_obj.dm @@ -542,7 +542,7 @@ if (!(R in contents)) return // User is not in this belly - R.setClickCooldown(50) + R.changeNext_move(CLICK_CD_BREAKOUT*0.5) if(owner.stat) //If owner is stat (dead, KO) we can actually escape to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)") diff --git a/code/modules/vore/eating/living.dm b/code/modules/vore/eating/living.dm index 33f8d78300..a7cc316cc3 100644 --- a/code/modules/vore/eating/living.dm +++ b/code/modules/vore/eating/living.dm @@ -358,6 +358,9 @@ if(incapacitated(ignore_restraints = TRUE)) to_chat(src, "You can't do that while incapacitated.") return + if(next_move > world.time) + to_chat(src, "You can't do that so fast, slow down.") + return var/list/choices for(var/mob/living/L in view(1)) @@ -372,7 +375,7 @@ if(QDELETED(tasted) || (tasted.ckey && !(tasted.client?.prefs.vore_flags & LICKABLE)) || !Adjacent(tasted) || incapacitated(ignore_restraints = TRUE)) return - setClickCooldown(100) + changeNext_move(CLICK_CD_MELEE) visible_message("[src] licks [tasted]!","You lick [tasted]. They taste rather like [tasted.get_taste_message()].","Slurp!") diff --git a/config/game_options.txt b/config/game_options.txt index 2d326493bb..f65c1bfff5 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -658,4 +658,8 @@ THRESHOLD_BODY_SIZE_SLOWDOWN 0.85 BODY_SIZE_SLOWDOWN_MULTIPLIER 0.25 ## Allows players to set a hexadecimal color of their choice as skin tone, on top of the standard ones. -ALLOW_CUSTOM_SKINTONES \ No newline at end of file +ALLOW_CUSTOM_SKINTONES + +## Enables the FoV component, which hides objects and mobs behind the parent from their sight, unless they turn around, duh. +## Camera mobs, AIs, ghosts and some other are of course exempt from this. This also doesn't influence simplemob AI, for the best. +#USE_FIELD_OF_VISION \ No newline at end of file diff --git a/icons/misc/field_of_vision.dmi b/icons/misc/field_of_vision.dmi new file mode 100644 index 0000000000..015cecd88c Binary files /dev/null and b/icons/misc/field_of_vision.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 78073222ca..86dec62a41 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi index b717b33c61..e126629b77 100644 Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ diff --git a/icons/mob/inhands/equipment/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi index 24bb824f1d..850bbaa043 100644 Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi index 31d84f480c..d4db35b9b2 100644 Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ diff --git a/icons/mob/talk.dmi b/icons/mob/talk.dmi index 05fe6f5623..0a56321037 100644 Binary files a/icons/mob/talk.dmi and b/icons/mob/talk.dmi differ diff --git a/icons/obj/artstuff.dmi b/icons/obj/artstuff.dmi index ea24341f5e..14970b76ef 100644 Binary files a/icons/obj/artstuff.dmi and b/icons/obj/artstuff.dmi differ diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi index 7ed9244ea4..f66767292c 100644 Binary files a/icons/obj/decals.dmi and b/icons/obj/decals.dmi differ diff --git a/icons/obj/hydroponics/growing_vegetables.dmi b/icons/obj/hydroponics/growing_vegetables.dmi index 63cf069186..b426b8f6de 100644 Binary files a/icons/obj/hydroponics/growing_vegetables.dmi and b/icons/obj/hydroponics/growing_vegetables.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi index c7c31581f3..fd9d310c73 100644 Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi index 62843e3f54..15b7e2b96c 100644 Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/improvised.dmi b/icons/obj/improvised.dmi index b90e3cb3bb..5c2c2a1f1b 100644 Binary files a/icons/obj/improvised.dmi and b/icons/obj/improvised.dmi differ diff --git a/icons/obj/shields.dmi b/icons/obj/shields.dmi index ed528d4a5a..c8b1110e1a 100644 Binary files a/icons/obj/shields.dmi and b/icons/obj/shields.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 04a78af061..8d68336754 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -54,6 +54,7 @@ window "mainwindow" size = 640x440 anchor1 = none anchor2 = none + background-color = #242424 is-default = true saved-params = "pos;size;is-minimized;is-maximized" icon = 'icons\\ss13_64.png' @@ -61,60 +62,23 @@ window "mainwindow" menu = "menu" elem "split" type = CHILD - pos = 3,0 - size = 634x417 + pos = 0,0 + size = 637x440 anchor1 = 0,0 anchor2 = 100,100 + background-color = #272727 saved-params = "splitter" left = "mapwindow" right = "infowindow" is-vert = true - elem "input" - type = INPUT - pos = 3,420 - size = 517x20 - anchor1 = 0,100 - anchor2 = 100,100 - background-color = #d3b5b5 - is-default = true - border = sunken - saved-params = "command" - elem "saybutton" - type = BUTTON - pos = 600,420 - size = 40x20 - anchor1 = 100,100 - anchor2 = none - saved-params = "is-checked" - text = "Chat" - command = ".winset \"saybutton.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"\"saybutton.is-checked=true ? mebutton.is-checked=false\"\"saybutton.is-checked=true ? oocbutton.is-checked=false\"" - button-type = pushbox - elem "oocbutton" - type = BUTTON - pos = 520,420 - size = 40x20 - anchor1 = 100,100 - anchor2 = none - saved-params = "is-checked" - text = "OOC" - command = ".winset \"oocbutton.is-checked=true ? input.command=\"!ooc \\\"\" : input.command=\"\"oocbutton.is-checked=true ? mebutton.is-checked=false\"\"oocbutton.is-checked=true ? saybutton.is-checked=false\"" - button-type = pushbox - elem "mebutton" - type = BUTTON - pos = 560,420 - size = 40x20 - anchor1 = 100,100 - anchor2 = none - saved-params = "is-checked" - text = "Me" - command = ".winset \"mebutton.is-checked=true ? input.command=\"!me \\\"\" : input.command=\"\"mebutton.is-checked=true ? saybutton.is-checked=false\"\"mebutton.is-checked=true ? oocbutton.is-checked=false\"" - button-type = pushbox + splitter = 75 elem "asset_cache_browser" type = BROWSER pos = 0,0 size = 200x200 anchor1 = none anchor2 = none + background-color = #272727 is-visible = false saved-params = "" elem "tooltip" @@ -123,6 +87,7 @@ window "mainwindow" size = 999x999 anchor1 = none anchor2 = none + background-color = #272727 is-visible = false saved-params = "" @@ -134,11 +99,11 @@ window "mapwindow" anchor1 = none anchor2 = none background-color = none - saved-params = "" + saved-params = "pos;size;is-minimized;is-maximized" statusbar = false is-pane = true - outer-size = 1090x1192 - inner-size = 1068x1136 + outer-size = 684x617 + inner-size = 662x561 elem "map" type = MAP pos = 0,0 @@ -159,6 +124,7 @@ window "infowindow" size = 640x480 anchor1 = none anchor2 = none + background-color = #242424 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "info" @@ -167,6 +133,7 @@ window "infowindow" size = 640x445 anchor1 = 0,0 anchor2 = 100,100 + background-color = #272727 saved-params = "splitter" left = "statwindow" right = "outputwindow" @@ -177,6 +144,8 @@ window "infowindow" size = 104x20 anchor1 = 3,0 anchor2 = 19,0 + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Changelog" command = "changelog" @@ -186,6 +155,8 @@ window "infowindow" size = 100x20 anchor1 = 19,0 anchor2 = 34,0 + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Rules" command = "rules" @@ -195,6 +166,8 @@ window "infowindow" size = 100x20 anchor1 = 34,0 anchor2 = 50,0 + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Wiki" command = "wiki" @@ -204,6 +177,8 @@ window "infowindow" size = 100x20 anchor1 = 50,0 anchor2 = 66,0 + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" text = "Forum" command = "forum" @@ -213,8 +188,10 @@ window "infowindow" size = 100x20 anchor1 = 66,0 anchor2 = 81,0 + text-color = #e0e0e0 + background-color = #40628a saved-params = "is-checked" - text = "Github" + text = "GitHub" command = "github" elem "report-issue" type = BUTTON @@ -222,6 +199,9 @@ window "infowindow" size = 100x20 anchor1 = 81,0 anchor2 = 97,0 + font-size = 8 + text-color = #e0e0e0 + background-color = #a92c2c saved-params = "is-checked" text = "Report Issue" command = "report-issue" @@ -233,15 +213,44 @@ window "outputwindow" size = 640x480 anchor1 = none anchor2 = none + background-color = #272727 saved-params = "pos;size;is-minimized;is-maximized" + titlebar = false + statusbar = false + can-close = false + can-minimize = false + can-resize = false is-pane = true + elem "input" + type = INPUT + pos = 2,460 + size = 595x20 + anchor1 = 0,100 + anchor2 = 100,100 + background-color = #d3b5b5 + is-default = true + border = sunken + saved-params = "command" + elem "say" + type = BUTTON + pos = 600,460 + size = 37x20 + anchor1 = 100,100 + anchor2 = none + text-color = #e0e0e0 + background-color = #272727 + saved-params = "is-checked" + text = "Chat" + command = ".winset \"say.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"" + is-flat = true + button-type = pushbox elem "browseroutput" type = BROWSER pos = 0,0 - size = 640x480 + size = 640x456 anchor1 = 0,0 anchor2 = 100,100 - background-color = #ffffff + background-color = #272727 is-visible = false is-disabled = true saved-params = "" @@ -249,19 +258,22 @@ window "outputwindow" elem "output" type = OUTPUT pos = 0,0 - size = 640x480 + size = 640x456 anchor1 = 0,0 anchor2 = 100,100 + text-color = #e0e0e0 + background-color = #272727 is-default = true saved-params = "" window "statwindow" elem "statwindow" type = MAIN - pos = 0,0 + pos = 281,0 size = 640x480 anchor1 = none anchor2 = none + background-color = #242424 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "stat" @@ -270,8 +282,14 @@ window "statwindow" size = 640x480 anchor1 = 0,0 anchor2 = 100,100 + text-color = #e0e0e0 + background-color = #272727 is-default = true saved-params = "" + tab-text-color = #e0e0e0 + tab-background-color = #242424 + prefix-color = #e0e0e0 + suffix-color = #e0e0e0 window "preferences_window" elem "preferences_window" diff --git a/modular_citadel/code/__HELPERS/list2list.dm b/modular_citadel/code/__HELPERS/list2list.dm deleted file mode 100644 index e812b3a1e9..0000000000 --- a/modular_citadel/code/__HELPERS/list2list.dm +++ /dev/null @@ -1,12 +0,0 @@ -/proc/tg_ui_icon_to_cit_ui(ui_style) - switch(ui_style) - if('icons/mob/screen_plasmafire.dmi') - return 'modular_citadel/icons/ui/screen_plasmafire.dmi' - if('icons/mob/screen_slimecore.dmi') - return 'modular_citadel/icons/ui/screen_slimecore.dmi' - if('icons/mob/screen_operative.dmi') - return 'modular_citadel/icons/ui/screen_operative.dmi' - if('icons/mob/screen_clockwork.dmi') - return 'modular_citadel/icons/ui/screen_clockwork.dmi' - else - return 'modular_citadel/icons/ui/screen_midnight.dmi' diff --git a/modular_citadel/code/__HELPERS/lists.dm b/modular_citadel/code/__HELPERS/lists.dm deleted file mode 100644 index b249dfc554..0000000000 --- a/modular_citadel/code/__HELPERS/lists.dm +++ /dev/null @@ -1,9 +0,0 @@ -/proc/is_type_in_ref_list(path, list/L) - if(!ispath(path))//not a path - return - for(var/i in L) - var/datum/D = i - if(!istype(D))//not an usable reference - continue - if(istype(D, path)) - return TRUE \ No newline at end of file diff --git a/modular_citadel/code/__HELPERS/mobs.dm b/modular_citadel/code/__HELPERS/mobs.dm deleted file mode 100644 index 2666696564..0000000000 --- a/modular_citadel/code/__HELPERS/mobs.dm +++ /dev/null @@ -1,28 +0,0 @@ -/proc/slot_to_string(slot) - switch(slot) - if(SLOT_BACK) - return "Backpack" - if(SLOT_WEAR_MASK) - return "Mask" - if(SLOT_HANDS) - return "Hands" - if(SLOT_BELT) - return "Belt" - if(SLOT_EARS) - return "Ears" - if(SLOT_GLASSES) - return "Glasses" - if(SLOT_GLOVES) - return "Gloves" - if(SLOT_NECK) - return "Neck" - if(SLOT_HEAD) - return "Head" - if(SLOT_SHOES) - return "Shoes" - if(SLOT_WEAR_SUIT) - return "Suit" - if(SLOT_W_UNIFORM) - return "Uniform" - if(SLOT_IN_BACKPACK) - return "In backpack" diff --git a/modular_citadel/code/_onclick/click.dm b/modular_citadel/code/_onclick/click.dm index f077b3a71b..004cc2fe80 100644 --- a/modular_citadel/code/_onclick/click.dm +++ b/modular_citadel/code/_onclick/click.dm @@ -72,30 +72,3 @@ /mob/proc/AltRangedAttack(atom/A, params) return FALSE - -/mob/proc/mouse_face_atom(atom/A) //Basically a copy of face_atom but with ismousemovement set to TRUE - if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y ) - return - var/dx = A.x - x - var/dy = A.y - y - if(!dx && !dy) // Wall items are graphically shifted but on the floor - if(A.pixel_y > 16) - setDir(NORTH, ismousemovement = TRUE) - else if(A.pixel_y < -16) - setDir(SOUTH, ismousemovement = TRUE) - else if(A.pixel_x > 16) - setDir(EAST, ismousemovement = TRUE) - else if(A.pixel_x < -16) - setDir(WEST, ismousemovement = TRUE) - return - - if(abs(dx) < abs(dy)) - if(dy > 0) - setDir(NORTH, ismousemovement = TRUE) - else - setDir(SOUTH, ismousemovement = TRUE) - else - if(dx > 0) - setDir(EAST, ismousemovement = TRUE) - else - setDir(WEST, ismousemovement = TRUE) diff --git a/modular_citadel/code/_onclick/other_mobs.dm b/modular_citadel/code/_onclick/other_mobs.dm index 6d9ffdd6ca..ec740f023b 100644 --- a/modular_citadel/code/_onclick/other_mobs.dm +++ b/modular_citadel/code/_onclick/other_mobs.dm @@ -12,7 +12,7 @@ if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless. return TRUE changeNext_move(CLICK_CD_RANGE) - var/list/target_viewers = viewers(11, A) //Byond proc, doesn't check for blindness. + var/list/target_viewers = fov_viewers(11, A) //doesn't check for blindness. if(!(src in target_viewers)) //click catcher issuing calls for out of view objects. return TRUE if(!has_active_hand()) @@ -26,16 +26,16 @@ switch(a_intent) if(INTENT_DISARM) the_action = "shoos away [A]" - what_action = "shoo away something you can't see" + what_action = "shoo away something out of your vision" self_action = "shoo away [A]" if(INTENT_GRAB) the_action = "beckons [A] to come" - what_action = "beckons something you can't see to come" + what_action = "beckons something out of your vision to come" self_action = "beckon [A] to come" if(INTENT_HARM) var/pronoun = "[p_their()]" the_action = "shakes [pronoun] fist at [A]" - what_action = "shakes [pronoun] fist at something you can't see" + what_action = "shakes [pronoun] fist at something out of your vision" self_action = "shake your fist at [A]" if(!eye_blind) diff --git a/modular_citadel/code/game/machinery/wishgranter.dm b/modular_citadel/code/game/machinery/wishgranter.dm deleted file mode 100644 index 6cfe07b7a0..0000000000 --- a/modular_citadel/code/game/machinery/wishgranter.dm +++ /dev/null @@ -1,122 +0,0 @@ -/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user) - if(charges <= 0) - to_chat(user, "The Wish Granter lies silent.") - return - - else if(!ishuman(user)) - to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.") - return - - else if (!insisting) - to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?") - insisting++ - - else - if(is_special_character(user)) - to_chat(user, "You speak. [pick("I want power","Humanity is corrupt, mankind must be destroyed", "I want to rule the world","I want immortality")]. The Wish Granter answers.") - to_chat(user, "Your head pounds for a moment, before your vision clears. The Wish Granter, sensing the darkness in your heart, has given you limitless power, and it's all yours!") - user.dna.add_mutation(HULK) - user.dna.add_mutation(XRAY) - user.dna.add_mutation(SPACEMUT) - user.dna.add_mutation(TK) - user.next_move_modifier *= 0.5 //half the delay between attacks! - to_chat(user, "Things around you feel slower!") - charges-- - insisting = FALSE - to_chat(user, "You have a very great feeling about this!") - else - to_chat(user, "The Wish Granter awaits your wish.") - var/wish = input("You want...","Wish") as null|anything in list("Power","Wealth","The Station To Disappear","To Kill","Nothing") - switch(wish) - if("Power") //Gives infinite power in exchange for infinite power going off in your face! - if(charges <= 0) - return - to_chat(user, "Your wish is granted, but at a terrible cost...") - to_chat(user, "The Wish Granter punishes you for your selfishness, warping itself into a delaminating supermatter shard!") - var/obj/item/stock_parts/cell/infinite/powah = new /obj/item/stock_parts/cell/infinite(get_turf(user)) - if(user.put_in_hands(powah)) - to_chat(user, "[powah] materializes into your hands!") - else - to_chat(user, "[powah] materializes onto the floor.") - var/obj/machinery/power/supermatter_crystal/powerwish = new /obj/machinery/power/supermatter_crystal(loc) - powerwish.damage = 700 //right at the emergency threshold - powerwish.produces_gas = FALSE - charges-- - insisting = FALSE - if(!charges) - qdel(src) - if("Wealth") //Gives 1 million space bucks in exchange for being turned into gold! - if(charges <= 0) - return - to_chat(user, "Your wish is granted, but at a cost...") - to_chat(user, "The Wish Granter punishes you for your selfishness, warping your body to match the greed in your heart.") - new /obj/structure/closet/crate/trashcart/moneywish(loc) - new /obj/structure/closet/crate/trashcart/moneywish(loc) - user.set_species(/datum/species/golem/gold) - charges-- - insisting = FALSE - if(!charges) - qdel(src) - if("The Station To Disappear") //teleports you to the station and makes you blind, making the station disappear for you! - if(charges <= 0) - return - to_chat(user, "Your wish is 'granted', but at a terrible cost...") - to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your eyes to match the darkness in your heart.") - user.dna.add_mutation(BLINDMUT) - var/obj/item/organ/eyes/eyes = user.getorganslot(ORGAN_SLOT_EYES) - if(eyes) - eyes.applyOrganDamage(eyes.maxHealth) - var/list/destinations = list() - for(var/obj/item/beacon/B in GLOB.teleportbeacons) - var/turf/T = get_turf(B) - if(is_station_level(T.z)) - destinations += B - var/chosen_beacon = pick(destinations) - var/obj/effect/portal/jaunt_tunnel/J = new (get_turf(src), src, 100, null, FALSE, get_turf(chosen_beacon)) - try_move_adjacent(J) - playsound(src,'sound/effects/sparks4.ogg',50,1) - charges-- - insisting = FALSE - if(!charges) - qdel(src) - if("To Kill") //Makes you kill things in exchange for rewards! - if(charges <= 0) - return - to_chat(user, "Your wish is granted, but at a terrible cost...") - to_chat(user, "The Wish Granter punishes you for your wickedness, warping itself into a dastardly creature for you to kill! ...but it almost seems to reward you for this.") - var/obj/item/melee/transforming/energy/sword/cx/killreward = new /obj/item/melee/transforming/energy/sword/cx(get_turf(user)) - if(user.put_in_hands(killreward)) - to_chat(user, "[killreward] materializes into your hands!") - else - to_chat(user, "[killreward] materializes onto the floor.") - user.next_move_modifier *= 0.8 //20% less delay between attacks! - to_chat(user, "Things around you feel slightly slower!") - var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc) - killwish.maxHealth = 1500 - killwish.health = killwish.maxHealth - killwish.vine_grab_distance = 6 - killwish.melee_damage_upper = 30 - killwish.loot = list(/obj/item/twohanded/dualsaber/hypereutactic) - charges-- - insisting = FALSE - if(!charges) - qdel(src) - if("Nothing") //Makes the wish granter disappear - if(charges <= 0) - return - to_chat(user, "The Wish Granter vanishes from sight!") - to_chat(user, "You feel as if you just narrowly avoided a terrible fate...") - charges-- - insisting = FALSE - qdel(src) - -//ITEMS THAT IT USES - -/obj/structure/closet/crate/trashcart/moneywish - desc = "A heavy, metal trashcart with wheels. Filled with cash." - name = "loaded trash cart" - -/obj/structure/closet/crate/trashcart/moneywish/PopulateContents() //25*20*1000=500,000 - for(var/i = 0, i < 25, i++) - var/obj/item/stack/spacecash/c1000/lodsamoney = new /obj/item/stack/spacecash/c1000(src) - lodsamoney.amount = lodsamoney.max_amount diff --git a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm b/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm deleted file mode 100644 index 6c9f12a852..0000000000 --- a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm +++ /dev/null @@ -1,83 +0,0 @@ -/obj/item/electropack/shockcollar - name = "shock collar" - desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." - icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi' - mob_overlay_icon = 'modular_citadel/icons/mob/citadel/neck.dmi' - icon_state = "shockcollar" - item_state = "shockcollar" - body_parts_covered = NECK - slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers - w_class = WEIGHT_CLASS_SMALL - strip_delay = 60 - equip_delay_other = 60 - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - var/tagname = null - -/datum/design/electropack/shockcollar - name = "Shockcollar" - id = "shockcollar" - build_type = AUTOLATHE - build_path = /obj/item/electropack/shockcollar - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - category = list("hacked", "Misc") - -/obj/item/electropack/shockcollar/attack_hand(mob/user) - if(loc == user && user.get_item_by_slot(SLOT_NECK)) - to_chat(user, "The collar is fastened tight! You'll need help taking this off!") - return - ..() - -/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) - if(!signal || signal.data["code"] != code) - return - - if(isliving(loc) && on) - if(shock_cooldown != 0) - return - shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 - var/mob/living/L = loc - step(L, pick(GLOB.cardinals)) - - to_chat(L, "You feel a sharp shock from the collar!") - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, L) - s.start() - - L.DefaultCombatKnockdown(100) - - if(master) - master.receive_signal() - return - -/obj/item/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle.. - var/option = "Change Name" - option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency") - switch(option) - if("Change Name") - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - if("Change Frequency") - if(!ishuman(user)) - return - user.set_machine(src) - var/dat = {"
- Frequency/Code for shock collar:
- Frequency: - - - - [format_frequency(frequency)] - + - +
- Code: - - - - [code] - + - +
-
"} - - user << browse(dat, "window=radio") - onclose(user, "radio") - return diff --git a/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm b/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm deleted file mode 100644 index 5b20fe048b..0000000000 --- a/modular_citadel/code/game/objects/structures/beds_chairs/chair.dm +++ /dev/null @@ -1,21 +0,0 @@ -/obj/structure/chair/alt_attack_hand(mob/living/user) - if(Adjacent(user) && istype(user)) - if(!item_chair || !user.can_hold_items() || !has_buckled_mobs() || buckled_mobs.len > 1 || dir != user.dir || flags_1 & NODECONSTRUCT_1) - return TRUE - if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user))) - to_chat(user, "You can't do that right now!") - return TRUE - if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) - to_chat(user, "You're too exhausted for that.") - return TRUE - var/mob/living/poordude = buckled_mobs[1] - if(!istype(poordude)) - return TRUE - user.visible_message("[user] pulls [src] out from under [poordude].", "You pull [src] out from under [poordude].") - var/C = new item_chair(loc) - user.put_in_hands(C) - poordude.DefaultCombatKnockdown(20)//rip in peace - user.adjustStaminaLoss(5) - unbuckle_all_mobs(TRUE) - qdel(src) - return TRUE diff --git a/modular_citadel/code/modules/client/loadout/_loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm index d35bede179..51256f8cde 100644 --- a/modular_citadel/code/modules/client/loadout/_loadout.dm +++ b/modular_citadel/code/modules/client/loadout/_loadout.dm @@ -10,7 +10,6 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) /proc/load_loadout_config(loadout_config) if(!loadout_config) loadout_config = "config/loadout_config.txt" - LAZYINITLIST(GLOB.loadout_whitelist_ids) var/list/file_lines = world.file2list(loadout_config) for(var/line in file_lines) if(!line || line[1] == "#") @@ -26,12 +25,9 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) GLOB.loadout_whitelist_ids["[lineID]"] = sublinecontent /proc/initialize_global_loadout_items() - LAZYINITLIST(GLOB.loadout_items) load_loadout_config() for(var/item in subtypesof(/datum/gear)) var/datum/gear/I = new item - if(!GLOB.loadout_items[slot_to_string(I.category)]) - LAZYINITLIST(GLOB.loadout_items[slot_to_string(I.category)]) LAZYSET(GLOB.loadout_items[slot_to_string(I.category)], I.name, I) if(islist(I.geargroupID)) var/list/ggidlist = I.geargroupID diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index d51f4b6125..8d089a129a 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -69,18 +69,6 @@ path = /obj/item/toy/katana cost = 3 -/datum/gear/box - name = "Spare box" - category = SLOT_IN_BACKPACK - path = /obj/item/storage/box - cost = 2 - -/datum/gear/crowbar - name = "Pocket Crowbar" - category = SLOT_IN_BACKPACK - path = /obj/item/crowbar - cost = 2 - /datum/gear/tapeplayer name = "Taperecorder" category = SLOT_IN_BACKPACK @@ -96,11 +84,6 @@ category = SLOT_IN_BACKPACK path = /obj/item/newspaper -/datum/gear/paperbin - name = "Paper Bin" - category = SLOT_IN_BACKPACK - path = /obj/item/paper_bin - /datum/gear/crayons name = "Box of crayons" category = SLOT_IN_BACKPACK @@ -146,4 +129,4 @@ category = SLOT_IN_BACKPACK path = /obj/item/storage/fancy/ringbox/diamond cost = 5 - + diff --git a/modular_citadel/code/modules/client/loadout/mask.dm b/modular_citadel/code/modules/client/loadout/mask.dm index 82824814ae..eeba06cad4 100644 --- a/modular_citadel/code/modules/client/loadout/mask.dm +++ b/modular_citadel/code/modules/client/loadout/mask.dm @@ -12,5 +12,5 @@ name = "Joy mask" category = SLOT_WEAR_MASK path = /obj/item/clothing/mask/joy - cost = 9 - + cost = 3 + diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index 9b39d006bd..64deaf9be2 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -85,14 +85,6 @@ path = /obj/item/clothing/suit/hooded/wintercoat/polychromic cost = 4 //too many people with neon green coats is hard on the eyes -/* Commented out until it is "balanced" -/datum/gear/coat/sec - name = "Security winter coat" - category = SLOT_WEAR_SUIT - path = /obj/item/clothing/suit/hooded/wintercoat/security - restricted_roles = list("Head of Security", "Warden", "Detective", "Security Officer") // Reserve it to the Security Departement -*/ - /datum/gear/coat/med name = "Medical winter coat" category = SLOT_WEAR_SUIT diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm deleted file mode 100644 index 8c55f2d9a8..0000000000 --- a/modular_citadel/code/modules/client/preferences.dm +++ /dev/null @@ -1,47 +0,0 @@ -#define DEFAULT_SLOT_AMT 2 -#define HANDS_SLOT_AMT 2 -#define BACKPACK_SLOT_AMT 4 - -/datum/preferences - //gear - var/gear_points = 10 - var/list/gear_categories - var/list/chosen_gear - var/gear_tab - - //pref vars - var/screenshake = 100 - var/damagescreenshake = 2 - var/arousable = TRUE - var/widescreenpref = TRUE - var/autostand = TRUE - var/auto_ooc = FALSE - - //vore prefs - var/toggleeatingnoise = TRUE - var/toggledigestionnoise = TRUE - var/hound_sleeper = TRUE - var/cit_toggles = TOGGLES_CITADEL - - -/datum/preferences/New(client/C) - ..() - LAZYINITLIST(chosen_gear) - -/datum/preferences/proc/is_loadout_slot_available(slot) - var/list/L - LAZYINITLIST(L) - for(var/i in chosen_gear) - var/datum/gear/G = i - var/occupied_slots = L[slot_to_string(initial(G.category))] ? L[slot_to_string(initial(G.category))] + 1 : 1 - LAZYSET(L, slot_to_string(initial(G.category)), occupied_slots) - switch(slot) - if(SLOT_IN_BACKPACK) - if(L[slot_to_string(SLOT_IN_BACKPACK)] < BACKPACK_SLOT_AMT) - return TRUE - if(SLOT_HANDS) - if(L[slot_to_string(SLOT_HANDS)] < HANDS_SLOT_AMT) - return TRUE - else - if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT) - return TRUE diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index d9b902656f..d0363d228f 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -14,17 +14,6 @@ features["mcolor2"] = sanitize_hexcolor(features["mcolor2"], 3, 0) features["mcolor3"] = sanitize_hexcolor(features["mcolor3"], 3, 0) - //gear loadout - var/text_to_load - S["loadout"] >> text_to_load - var/list/saved_loadout_paths = splittext(text_to_load, "|") - LAZYCLEARLIST(chosen_gear) - gear_points = initial(gear_points) - for(var/i in saved_loadout_paths) - var/datum/gear/path = text2path(i) - if(path) - LAZYADD(chosen_gear, path) - gear_points -= initial(path.cost) /datum/preferences/proc/cit_character_pref_save(savefile/S) //ipcs @@ -47,10 +36,3 @@ //flavor text WRITE_FILE(S["feature_flavor_text"], features["flavor_text"]) - //gear loadout - if(islist(chosen_gear)) - if(chosen_gear.len) - var/text_to_save = chosen_gear.Join("|") - S["loadout"] << text_to_save - else - S["loadout"] << "" //empty string to reset the value diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm index e95948e562..0532f59afa 100644 --- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm +++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm @@ -25,5 +25,5 @@ /mob/living/carbon/onMouseMove(object, location, control, params) if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) return - mouse_face_atom(object) + face_atom(object, TRUE) lastmousedir = dir diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index 89a7f58cee..d3daad7964 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -194,14 +194,14 @@ Creating a chem with a low purity will make you permanently fall in love with so if (M.ckey == creatorID && creatorName == M.real_name)//If the creator drinks it, they fall in love randomly. If someone else drinks it, the creator falls in love with them. if(M.has_status_effect(STATUS_EFFECT_INLOVE))//Can't be enthralled when enthralled, so to speak. return - var/list/seen = viewers(7, get_turf(M)) + var/list/seen = (M.fov_view(M.client?.view || world.view) - M) | viewers(M.client?.view || world.view, M) for(var/victim in seen) if(ishuman(victim)) var/mob/living/carbon/V = victim - if((V == M) || (!V.client) || (V.stat == DEAD)) - seen = seen - victim + if(!V.client || V.stat == DEAD) + seen -= victim else - seen = seen - victim + seen -= victim if(LAZYLEN(seen)) return @@ -213,7 +213,7 @@ Creating a chem with a low purity will make you permanently fall in love with so var/mob/living/carbon/C = get_mob_by_key(creatorID) if(M.has_status_effect(STATUS_EFFECT_INLOVE)) return - if((C in viewers(7, get_turf(M))) && (C.client)) + if(C.client && (M in C.fov_view(C.client.view))) M.reagents.del_reagent(type) FallInLove(C, M) return @@ -279,15 +279,13 @@ Creating a chem with a low purity will make you permanently fall in love with so if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) return ..() if(!M.has_status_effect(STATUS_EFFECT_INLOVE)) - var/list/seen = viewers(7, get_turf(M))//Sound and sight checkers + var/list/seen = (M.fov_view(M.client?.view || world.view) - M) | viewers(M.client?.view || world.view, M) for(var/victim in seen) - if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (M.stat == DEAD) || (!isliving(victim))) - seen = seen - victim - if(seen.len == 0) + if((isanimal(victim)) || (!isliving(victim))) + seen -= victim + if(!length(seen)) return love = pick(seen) - if(!love) - return M.apply_status_effect(STATUS_EFFECT_INLOVE, love) lewd = (M.client?.prefs.cit_toggles & HYPNO) && (love.client?.prefs.cit_toggles & HYPNO) to_chat(M, "[(lewd?"":"")][(lewd?"You develop a sudden crush on [love], your heart beginning to race as you look upon them with new eyes.":"You suddenly feel like making friends with [love].")] You feel strangely drawn towards them.") diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm index dac6d97eef..8a3a648863 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm @@ -98,10 +98,8 @@ M.emote("cough") var/obj/item/toy/plush/P = pick(subtypesof(/obj/item/toy/plush)) new P(T) - to_chat(M, "You feel a lump form in your throat, as you suddenly cough up what seems to be a hairball?") - var/list/seen = viewers(8, T) - for(var/mob/S in seen) - to_chat(S, "[M] suddenly coughs up a [P.name]!") + M.visible_message("[M] suddenly coughs up a [P.name]!",\ + "You feel a lump form in your throat, as you suddenly cough up what seems to be a hairball?") var/T2 = get_random_station_turf() P.throw_at(T2, 8, 1) ..() @@ -120,10 +118,10 @@ to_chat(M, "You find yourself unable to supress the desire to howl!") M.emote("awoo") if(prob(20)) - var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers + var/list/seen = M.fov_view() - M //Sound and sight checkers for(var/victim in seen) - if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (!isliving(victim))) - seen = seen - victim + if(isanimal(victim) || !isliving(victim)) + seen -= victim if(LAZYLEN(seen)) to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]") if(16) @@ -141,10 +139,10 @@ to_chat(M, "You find yourself unable to supress the desire to howl!") M.emote("awoo") if(prob(5)) - var/list/seen = viewers(5, get_turf(M))//Sound and sight checkers + var/list/seen = M.fov_view() - M //Sound and sight checkers for(var/victim in seen) - if((istype(victim, /mob/living/simple_animal/pet/)) || (victim == M) || (!isliving(victim))) - seen = seen - victim + if(isanimal(victim) || !isliving(victim)) + seen -= victim if(LAZYLEN(seen)) to_chat(M, "You notice [pick(seen)]'s bulge [pick("OwO!", "uwu!")]") ..() @@ -301,9 +299,8 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume) else var/datum/chemical_reaction/Ferm = GLOB.chemical_reagents_list[reagent.type] Ferm.on_reaction(holder, reagent.volume) - for(var/mob/M in viewers(8, location)) - to_chat(M, "The solution reacts dramatically, with a meow!") - playsound(get_turf(M), 'modular_citadel/sound/voice/merowr.ogg', 50, 1) + holder.my_atom.visible_message("The solution reacts dramatically, with a meow!") + playsound(holder.my_atom, 'modular_citadel/sound/voice/merowr.ogg', 50, 1) holder.clear_reagents() /datum/reagent/fermi/acidic_buffer @@ -321,10 +318,8 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume) if(LAZYLEN(holder.reagent_list) == 1) return ..() holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) - var/list/seen = viewers(5, get_turf(holder)) - for(var/mob/M in seen) - to_chat(M, "The beaker fizzes as the pH changes!") - playsound(get_turf(holder.my_atom), 'sound/FermiChem/bufferadd.ogg', 50, 1) + holder.my_atom.visible_message("The beaker fizzes as the pH changes!") + playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1) holder.remove_reagent(type, volume, ignore_pH = TRUE) ..() @@ -342,10 +337,8 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume) if(LAZYLEN(holder.reagent_list) == 1) return ..() holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume)) - var/list/seen = viewers(5, get_turf(holder)) - for(var/mob/M in seen) - to_chat(M, "The beaker froths as the pH changes!") - playsound(get_turf(holder.my_atom), 'sound/FermiChem/bufferadd.ogg', 50, 1) + holder.my_atom.visible_message("The beaker froths as the pH changes!") + playsound(holder.my_atom, 'sound/FermiChem/bufferadd.ogg', 50, 1) holder.remove_reagent(type, volume, ignore_pH = TRUE) ..() diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm index 837524d49f..a8998a51ac 100644 --- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm @@ -172,9 +172,7 @@ S.rabid = 1//Make them an angery boi S.color = "#810010" my_atom.reagents.clear_reagents() - var/list/seen = viewers(8, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The cells clump up into a horrifying tumour!") + my_atom.visible_message("An horrifying tumoural mass forms in [my_atom]!") /datum/chemical_reaction/fermi/breast_enlarger name = "Sucubus milk" @@ -211,9 +209,7 @@ /datum/chemical_reaction/fermi/breast_enlarger/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(get_turf(my_atom)) - var/list/seen = viewers(8, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The reaction suddenly condenses, creating a pair of breasts!") + my_atom.visible_message("The reaction suddenly condenses, creating a pair of breasts!") var/datum/reagent/fermi/breast_enlarger/BE = locate(/datum/reagent/fermi/breast_enlarger) in my_atom.reagents.reagent_list B.size = ((BE.volume * BE.purity) / 10) //half as effective. my_atom.reagents.clear_reagents() @@ -243,9 +239,7 @@ /datum/chemical_reaction/fermi/penis_enlarger/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(get_turf(my_atom)) - var/list/seen = viewers(8, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The reaction suddenly condenses, creating a penis!") + my_atom.visible_message("The reaction suddenly condenses, creating a penis!") var/datum/reagent/fermi/penis_enlarger/PE = locate(/datum/reagent/fermi/penis_enlarger) in my_atom.reagents.reagent_list P.length = ((PE.volume * PE.purity) / 10)//half as effective. my_atom.reagents.clear_reagents() @@ -383,9 +377,7 @@ for(var/i in 1 to amount_to_spawn) var/obj/item/clothing/head/hattip/hat = new /obj/item/clothing/head/hattip(get_turf(my_atom)) hat.animate_atom_living() - var/list/seen = viewers(8, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The [my_atom] makes an off sounding pop, as a hat suddenly climbs out of it!") + my_atom.visible_message("The [my_atom] makes an off sounding pop, as a hat suddenly climbs out of it!") my_atom.reagents.clear_reagents() /datum/chemical_reaction/fermi/furranium @@ -543,9 +535,7 @@ /datum/chemical_reaction/fermi/secretcatchem/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH) var/mob/living/simple_animal/pet/cat/custom_cat/catto = new(get_turf(my_atom)) - var/list/seen = viewers(8, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The reaction suddenly gives out a meow, condensing into a chemcat!")//meow! + my_atom.visible_message("The reaction suddenly gives out a meow, condensing into a chemcat!")//meow! playsound(get_turf(my_atom), 'modular_citadel/sound/voice/merowr.ogg', 50, 1, -1) catto.name = "Chemcat" catto.desc = "A cute chem cat, created by a lot of compicated and confusing chemistry!" diff --git a/modular_citadel/code/modules/reagents/objects/clothes.dm b/modular_citadel/code/modules/reagents/objects/clothes.dm index 34af39bbe0..de4cb38360 100644 --- a/modular_citadel/code/modules/reagents/objects/clothes.dm +++ b/modular_citadel/code/modules/reagents/objects/clothes.dm @@ -5,7 +5,7 @@ name = "Synthetic hat" icon = 'icons/obj/clothing/hats.dmi' icon_state = "cowboy" - desc = "A synthesized hat, you can't seem to take it off. And tips their hat." + desc = "A synthesized hat. You feel compelled to keep it on all times." armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) //item_flags = NODROP //Tips their hat! @@ -49,9 +49,8 @@ /obj/item/clothing/head/hattip/proc/root_and_toot(obj/item/clothing/head/hattip/hat) hat.animate_atom_living() - var/list/seen = viewers(6, get_turf(hat)) - for(var/mob/M2 in seen) - to_chat(M2, "[hat] exclaims, \"[pick("Whooee! Time for a hootenanny!", "Rough 'em up boys!", "Yeehaw! Freedom at last!", "Y'all about to get a good old fashioned spanking!")]\"") + var/mob/living/simple_animal/hostile/mimic/M = loc + M.say(pick("Whooee! Time for a hootenanny!", "Rough 'em up boys!", "Yeehaw! Freedom at last!", "Y'all about to get a good old fashioned spanking!")) /obj/item/clothing/head/hattip/proc/handle_speech(datum/source, mob/speech_args) var/message = speech_args[SPEECH_MESSAGE] diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi index d91f15a3f7..a67c1b718c 100644 Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ diff --git a/modular_citadel/icons/mob/mam_taur.dmi b/modular_citadel/icons/mob/mam_taur.dmi index 3625c293c9..cf332019af 100644 Binary files a/modular_citadel/icons/mob/mam_taur.dmi and b/modular_citadel/icons/mob/mam_taur.dmi differ diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf deleted file mode 100644 index 8130e84f90..0000000000 --- a/modular_citadel/interface/skin.dmf +++ /dev/null @@ -1,335 +0,0 @@ -macro "default" - - -menu "menu" - elem - name = "&File" - command = "" - saved-params = "is-checked" - elem - name = "&Quick screenshot\tF2" - command = ".screenshot auto" - category = "&File" - saved-params = "is-checked" - elem - name = "&Save screenshot as...\tShift+F2" - command = ".screenshot" - category = "&File" - saved-params = "is-checked" - elem - name = "" - command = "" - category = "&File" - saved-params = "is-checked" - elem "reconnectbutton" - name = "&Reconnect" - command = ".reconnect" - category = "&File" - saved-params = "is-checked" - elem - name = "&Quit\tAlt-F4" - command = ".quit" - category = "&File" - saved-params = "is-checked" - elem - name = "&Help" - command = "" - saved-params = "is-checked" - elem - name = "&Admin Help\tF1" - command = "adminhelp" - category = "&Help" - saved-params = "is-checked" - elem - name = "&Hotkeys" - command = "hotkeys-help" - category = "&Help" - saved-params = "is-checked" - elem - name = "&Hotkeys" - command = "hotkeys-help" - category = "&Help" - saved-params = "is-checked" - -window "mainwindow" - elem "mainwindow" - type = MAIN - pos = 0,0 - size = 640x440 - anchor1 = none - anchor2 = none - background-color = #242424 - is-default = true - saved-params = "pos;size;is-minimized;is-maximized" - icon = 'icons\\ss13_64.png' - macro = "default" - menu = "menu" - elem "split" - type = CHILD - pos = 0,0 - size = 637x440 - anchor1 = 0,0 - anchor2 = 100,100 - background-color = #272727 - saved-params = "splitter" - left = "mapwindow" - right = "infowindow" - is-vert = true - splitter = 75 - elem "asset_cache_browser" - type = BROWSER - pos = 0,0 - size = 200x200 - anchor1 = none - anchor2 = none - background-color = #272727 - is-visible = false - saved-params = "" - elem "tooltip" - type = BROWSER - pos = 0,0 - size = 999x999 - anchor1 = none - anchor2 = none - background-color = #272727 - is-visible = false - saved-params = "" - -window "mapwindow" - elem "mapwindow" - type = MAIN - pos = 418,0 - size = 1024x1024 - anchor1 = none - anchor2 = none - background-color = none - saved-params = "pos;size;is-minimized;is-maximized" - statusbar = false - is-pane = true - outer-size = 684x617 - inner-size = 662x561 - elem "map" - type = MAP - pos = 0,0 - size = 1024x1024 - anchor1 = 0,0 - anchor2 = 100,100 - font-family = "Arial" - font-size = 7 - is-default = true - saved-params = "icon-size" - zoom-mode = distort - style = ".center { text-align: center; }\n.maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; }\n.command_headset { font-weight: bold;\tfont-size: 8px; } .small { font-size: 6px; }\n.big { font-size: 8px; }\n.reallybig { font-size: 8px; }\n.extremelybig { font-size: 8px; }\n.greentext { color: #00ff00; font-size: 7px; }\n.redtext { color: #ff0000; font-size: 7px; }\n.clown { color: #ff69bf; font-size: 7px; font-weight: bold; }\n.his_grace { color: #15d512; }\n.hypnophrase { color: #0d0d0d; font-weight: bold; }\n.yell { font-weight: bold; }\n.italics { font-size: 6px; }" - -window "infowindow" - elem "infowindow" - type = MAIN - pos = 0,0 - size = 640x480 - anchor1 = none - anchor2 = none - background-color = #242424 - saved-params = "pos;size;is-minimized;is-maximized" - is-pane = true - elem "info" - type = CHILD - pos = 0,30 - size = 640x445 - anchor1 = 0,0 - anchor2 = 100,100 - background-color = #272727 - saved-params = "splitter" - left = "statwindow" - right = "outputwindow" - is-vert = false - elem "changelog" - type = BUTTON - pos = 16,5 - size = 104x20 - anchor1 = 3,0 - anchor2 = 19,0 - text-color = #e0e0e0 - background-color = #40628a - saved-params = "is-checked" - text = "Changelog" - command = "changelog" - elem "rules" - type = BUTTON - pos = 120,5 - size = 100x20 - anchor1 = 19,0 - anchor2 = 34,0 - text-color = #e0e0e0 - background-color = #40628a - saved-params = "is-checked" - text = "Rules" - command = "rules" - elem "wiki" - type = BUTTON - pos = 220,5 - size = 100x20 - anchor1 = 34,0 - anchor2 = 50,0 - text-color = #e0e0e0 - background-color = #40628a - saved-params = "is-checked" - text = "Wiki" - command = "wiki" - elem "forum" - type = BUTTON - pos = 320,5 - size = 100x20 - anchor1 = 50,0 - anchor2 = 66,0 - text-color = #e0e0e0 - background-color = #40628a - saved-params = "is-checked" - text = "Forum" - command = "forum" - elem "github" - type = BUTTON - pos = 420,5 - size = 100x20 - anchor1 = 66,0 - anchor2 = 81,0 - text-color = #e0e0e0 - background-color = #40628a - saved-params = "is-checked" - text = "GitHub" - command = "github" - elem "report-issue" - type = BUTTON - pos = 520,5 - size = 100x20 - anchor1 = 81,0 - anchor2 = 97,0 - font-size = 8 - text-color = #e0e0e0 - background-color = #a92c2c - saved-params = "is-checked" - text = "Report Issue" - command = "report-issue" - -window "outputwindow" - elem "outputwindow" - type = MAIN - pos = 0,0 - size = 640x480 - anchor1 = none - anchor2 = none - background-color = #272727 - saved-params = "pos;size;is-minimized;is-maximized" - titlebar = false - statusbar = false - can-close = false - can-minimize = false - can-resize = false - is-pane = true - elem "input" - type = INPUT - pos = 2,460 - size = 595x20 - anchor1 = 0,100 - anchor2 = 100,100 - background-color = #d3b5b5 - is-default = true - border = sunken - saved-params = "command" - elem "say" - type = BUTTON - pos = 600,460 - size = 37x20 - anchor1 = 100,100 - anchor2 = none - text-color = #e0e0e0 - background-color = #272727 - saved-params = "is-checked" - text = "Chat" - command = ".winset \"say.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"" - is-flat = true - button-type = pushbox - elem "browseroutput" - type = BROWSER - pos = 0,0 - size = 640x456 - anchor1 = 0,0 - anchor2 = 100,100 - background-color = #272727 - is-visible = false - is-disabled = true - saved-params = "" - auto-format = false - elem "output" - type = OUTPUT - pos = 0,0 - size = 640x456 - anchor1 = 0,0 - anchor2 = 100,100 - text-color = #e0e0e0 - background-color = #272727 - is-default = true - saved-params = "" - -window "statwindow" - elem "statwindow" - type = MAIN - pos = 281,0 - size = 640x480 - anchor1 = none - anchor2 = none - background-color = #242424 - saved-params = "pos;size;is-minimized;is-maximized" - is-pane = true - elem "stat" - type = INFO - pos = 0,0 - size = 640x480 - anchor1 = 0,0 - anchor2 = 100,100 - text-color = #e0e0e0 - background-color = #272727 - is-default = true - saved-params = "" - tab-text-color = #e0e0e0 - tab-background-color = #242424 - prefix-color = #e0e0e0 - suffix-color = #e0e0e0 - -window "popupwindow" - elem "popupwindow" - type = MAIN - pos = 281,0 - size = 120x120 - anchor1 = none - anchor2 = none - background-color = none - is-visible = false - saved-params = "pos;size;is-minimized;is-maximized" - statusbar = false - can-resize = false -window "preferences_window" - elem "preferences_window" - type = MAIN - pos = 281,0 - size = 1280x1000 - anchor1 = none - anchor2 = none - is-visible = false - saved-params = "pos;size;is-minimized;is-maximized" - statusbar = false - elem "preferences_browser" - type = BROWSER - pos = 0,0 - size = 960x1000 - anchor1 = 0,0 - anchor2 = 75,100 - saved-params = "" - elem "character_preview_map" - type = MAP - pos = 960,0 - size = 320x1000 - anchor1 = 75,0 - anchor2 = 100,100 - right-click = true - saved-params = "zoom;letterbox;zoom-mode" - diff --git a/rust_g.dll b/rust_g.dll index 27ee495684..f4be6e730a 100644 Binary files a/rust_g.dll and b/rust_g.dll differ diff --git a/strings/tips.txt b/strings/tips.txt index c8f233bb1a..0176420dd3 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -64,6 +64,7 @@ As a Roboticist, you can greatly help out Shaft Miners by building a Firefighter As a Roboticist, you can augment people with cyborg limbs. Augmented limbs can easily be repaired with cables and welders. As a Roboticist, you can use your printer that is linked to the ore silo to teleport mats into your work place! As a Roboticist, you can upgrade cleanbots with adv mops and brooms to make them faster and better! +As a Roboticist, you can upgrade medical bots with diamond-tipped syringes, MK.II Hypospray, dispenser-sleeper-chemheater boards to make them inject faster, harder and better chems! 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. 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. diff --git a/tgstation.dme b/tgstation.dme index b4d3f6f712..e54d164852 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -94,7 +94,6 @@ #include "code\__DEFINES\research.dm" #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" -#include "code\__DEFINES\rust_g.config.dm" #include "code\__DEFINES\rust_g.dm" #include "code\__DEFINES\say.dm" #include "code\__DEFINES\security_levels.dm" @@ -105,7 +104,6 @@ #include "code\__DEFINES\stat.dm" #include "code\__DEFINES\stat_tracking.dm" #include "code\__DEFINES\status_effects.dm" -#include "code\__DEFINES\storage.dm" #include "code\__DEFINES\subsystems.dm" #include "code\__DEFINES\tgs.config.dm" #include "code\__DEFINES\tgs.dm" @@ -121,6 +119,7 @@ #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\wall_dents.dm" #include "code\__DEFINES\wires.dm" +#include "code\__DEFINES\admin\keybindings.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" @@ -132,6 +131,8 @@ #include "code\__DEFINES\research\stock_parts.dm" #include "code\__DEFINES\skills\defines.dm" #include "code\__DEFINES\skills\helpers.dm" +#include "code\__DEFINES\storage\_storage.dm" +#include "code\__DEFINES\storage\volumetrics.dm" #include "code\__HELPERS\_cit_helpers.dm" #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" @@ -185,7 +186,9 @@ #include "code\_globalvars\misc.dm" #include "code\_globalvars\regexes.dm" #include "code\_globalvars\traits.dm" +#include "code\_globalvars\lists\client.dm" #include "code\_globalvars\lists\flavor_misc.dm" +#include "code\_globalvars\lists\keybindings.dm" #include "code\_globalvars\lists\maintenance_loot.dm" #include "code\_globalvars\lists\mapping.dm" #include "code\_globalvars\lists\medals.dm" @@ -292,7 +295,6 @@ #include "code\controllers\subsystem\minimaps.dm" #include "code\controllers\subsystem\minor_mapping.dm" #include "code\controllers\subsystem\mobs.dm" -#include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\overlays.dm" @@ -370,6 +372,7 @@ #include "code\datums\shuttles.dm" #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" +#include "code\datums\tgs_event_handler.dm" #include "code\datums\verbs.dm" #include "code\datums\weakrefs.dm" #include "code\datums\world_topic.dm" @@ -386,6 +389,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\armor_plate.dm" +#include "code\datums\components\art.dm" #include "code\datums\components\bane.dm" #include "code\datums\components\bouncy.dm" #include "code\datums\components\butchering.dm" @@ -398,6 +402,7 @@ #include "code\datums\components\edit_complainer.dm" #include "code\datums\components\empprotection.dm" #include "code\datums\components\explodable.dm" +#include "code\datums\components\field_of_vision.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\forced_gravity.dm" #include "code\datums\components\identification.dm" @@ -524,6 +529,7 @@ #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\dusts_on_catatonia.dm" #include "code\datums\elements\dusts_on_leaving_area.dm" +#include "code\datums\elements\dwarfism.dm" #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\flavor_text.dm" @@ -586,8 +592,12 @@ #include "code\datums\skills\_check_skills.dm" #include "code\datums\skills\_skill.dm" #include "code\datums\skills\_skill_holder.dm" +#include "code\datums\skills\_skill_modifier.dm" #include "code\datums\skills\engineering.dm" #include "code\datums\skills\medical.dm" +#include "code\datums\skills\modifiers\job.dm" +#include "code\datums\skills\modifiers\mood.dm" +#include "code\datums\skills\modifiers\organs.dm" #include "code\datums\status_effects\buffs.dm" #include "code\datums\status_effects\debuffs.dm" #include "code\datums\status_effects\gas.dm" @@ -1087,6 +1097,7 @@ #include "code\game\objects\items\stacks\tiles\light.dm" #include "code\game\objects\items\stacks\tiles\tile_mineral.dm" #include "code\game\objects\items\stacks\tiles\tile_types.dm" +#include "code\game\objects\items\storage\_storage.dm" #include "code\game\objects\items\storage\backpack.dm" #include "code\game\objects\items\storage\bags.dm" #include "code\game\objects\items\storage\belt.dm" @@ -1098,7 +1109,6 @@ #include "code\game\objects\items\storage\firstaid.dm" #include "code\game\objects\items\storage\lockbox.dm" #include "code\game\objects\items\storage\secure.dm" -#include "code\game\objects\items\storage\storage.dm" #include "code\game\objects\items\storage\toolbox.dm" #include "code\game\objects\items\storage\uplink_kits.dm" #include "code\game\objects\items\storage\wallets.dm" @@ -1467,6 +1477,7 @@ #include "code\modules\antagonists\clockcult\clock_items\soul_vessel.dm" #include "code\modules\antagonists\clockcult\clock_items\wraith_spectacles.dm" #include "code\modules\antagonists\clockcult\clock_items\clock_weapons\_call_weapon.dm" +#include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_shield.dm" #include "code\modules\antagonists\clockcult\clock_items\clock_weapons\ratvarian_spear.dm" #include "code\modules\antagonists\clockcult\clock_mobs\_eminence.dm" #include "code\modules\antagonists\clockcult\clock_mobs\clockwork_marauder.dm" @@ -2034,6 +2045,7 @@ #include "code\modules\hydroponics\grown\onion.dm" #include "code\modules\hydroponics\grown\peach.dm" #include "code\modules\hydroponics\grown\peanuts.dm" +#include "code\modules\hydroponics\grown\peas.dm" #include "code\modules\hydroponics\grown\pineapple.dm" #include "code\modules\hydroponics\grown\potato.dm" #include "code\modules\hydroponics\grown\pumpkin.dm" @@ -2139,16 +2151,22 @@ #include "code\modules\jobs\job_types\virologist.dm" #include "code\modules\jobs\job_types\warden.dm" #include "code\modules\jobs\map_changes\map_changes.dm" -#include "code\modules\keybindings\bindings_admin.dm" #include "code\modules\keybindings\bindings_atom.dm" -#include "code\modules\keybindings\bindings_carbon.dm" #include "code\modules\keybindings\bindings_client.dm" -#include "code\modules\keybindings\bindings_human.dm" -#include "code\modules\keybindings\bindings_living.dm" -#include "code\modules\keybindings\bindings_mob.dm" -#include "code\modules\keybindings\bindings_robot.dm" #include "code\modules\keybindings\focus.dm" #include "code\modules\keybindings\setup.dm" +#include "code\modules\keybindings\keybind\__defines.dm" +#include "code\modules\keybindings\keybind\_keybind.dm" +#include "code\modules\keybindings\keybind\admin.dm" +#include "code\modules\keybindings\keybind\carbon.dm" +#include "code\modules\keybindings\keybind\client.dm" +#include "code\modules\keybindings\keybind\emote.dm" +#include "code\modules\keybindings\keybind\human.dm" +#include "code\modules\keybindings\keybind\living.dm" +#include "code\modules\keybindings\keybind\mob.dm" +#include "code\modules\keybindings\keybind\movement.dm" +#include "code\modules\keybindings\keybind\robot.dm" +#include "code\modules\keybindings\keybind\targeting.dm" #include "code\modules\language\aphasia.dm" #include "code\modules\language\beachbum.dm" #include "code\modules\language\codespeak.dm" @@ -2250,6 +2268,7 @@ #include "code\modules\mob\say_vr.dm" #include "code\modules\mob\status_procs.dm" #include "code\modules\mob\transform_procs.dm" +#include "code\modules\mob\typing_indicator.dm" #include "code\modules\mob\update_icons.dm" #include "code\modules\mob\camera\camera.dm" #include "code\modules\mob\dead\dead.dm" @@ -2377,10 +2396,12 @@ #include "code\modules\mob\living\carbon\human\human_movement.dm" #include "code\modules\mob\living\carbon\human\inventory.dm" #include "code\modules\mob\living\carbon\human\life.dm" +#include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\physiology.dm" #include "code\modules\mob\living\carbon\human\say.dm" #include "code\modules\mob\living\carbon\human\species.dm" #include "code\modules\mob\living\carbon\human\status_procs.dm" +#include "code\modules\mob\living\carbon\human\typing_indicator.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\species_types\abductors.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm" @@ -3324,9 +3345,7 @@ #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm" -#include "modular_citadel\code\__HELPERS\list2list.dm" -#include "modular_citadel\code\__HELPERS\lists.dm" -#include "modular_citadel\code\__HELPERS\mobs.dm" +#include "interface\skin.dmf" #include "modular_citadel\code\_onclick\click.dm" #include "modular_citadel\code\_onclick\item_attack.dm" #include "modular_citadel\code\_onclick\other_mobs.dm" @@ -3335,7 +3354,6 @@ #include "modular_citadel\code\_onclick\hud\stamina.dm" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" -#include "modular_citadel\code\game\machinery\wishgranter.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" @@ -3343,7 +3361,6 @@ #include "modular_citadel\code\modules\admin\secrets.dm" #include "modular_citadel\code\modules\client\client_defines.dm" #include "modular_citadel\code\modules\client\client_procs.dm" -#include "modular_citadel\code\modules\client\preferences.dm" #include "modular_citadel\code\modules\client\preferences_savefile.dm" #include "modular_citadel\code\modules\client\preferences_toggles.dm" #include "modular_citadel\code\modules\client\loadout\__donator.dm" @@ -3410,5 +3427,4 @@ #include "modular_citadel\code\modules\reagents\objects\clothes.dm" #include "modular_citadel\code\modules\reagents\objects\items.dm" #include "modular_citadel\code\modules\reagents\reagents\cit_reagents.dm" -#include "modular_citadel\interface\skin.dmf" // END_INCLUDE diff --git a/tgui-next/packages/tgui/interfaces/Canvas.js b/tgui-next/packages/tgui/interfaces/Canvas.js new file mode 100644 index 0000000000..0955aedc3b --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Canvas.js @@ -0,0 +1,90 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box } from '../components'; +import { Component, createRef } from 'inferno'; +import { pureComponentHooks } from 'common/react'; + + +class PaintCanvas extends Component { + constructor(props) { + super(props); + this.canvasRef = createRef(); + this.onCVClick = props.onCanvasClick; + } + + componentDidMount() { + this.drawCanvas(this.props); + } + + componentDidUpdate() { + this.drawCanvas(this.props); + } + + drawCanvas(propSource) { + const ctx = this.canvasRef.current.getContext("2d"); + const grid = propSource.value; + const x_size = grid.length; + if (!x_size) { + return; + } + const y_size = grid[0].length; + const x_scale = Math.round(this.canvasRef.current.width / x_size); + const y_scale = Math.round(this.canvasRef.current.height / y_size); + ctx.save(); + ctx.scale(x_scale, y_scale); + for (let x = 0; x < grid.length; x++) { + const element = grid[x]; + for (let y = 0; y < element.length; y++) { + const color = element[y]; + ctx.fillStyle = color; + ctx.fillRect(x, y, 1, 1); + } + } + ctx.restore(); + } + + clickwrapper(event) { + const x_size = this.props.value.length; + if (!x_size) + { + return; + } + const y_size = this.props.value[0].length; + const x_scale = this.canvasRef.current.width / x_size; + const y_scale = this.canvasRef.current.height / y_size; + const x = Math.floor(event.offsetX / x_scale)+1; + const y = Math.floor(event.offsetY / y_scale)+1; + this.onCVClick(x, y); + } + + render() { + const { + res = 1, + value, + px_per_unit = 28, + ...rest + } = this.props; + const x_size = value.length * px_per_unit; + const y_size = x_size !== 0 ? value[0].length * px_per_unit : 0; + return ( + this.clickwrapper(e)}> + Canvas failed to render. + + ); + } +} +export const Canvas = props => { + const { act, data } = useBackend(props); + return ( + + act("paint", { x, y })} /> + {data.name} + ); +};