diff --git a/.github/alternate_byond_versions.txt b/.github/alternate_byond_versions.txt index 1407b98d98a7..830244379f6f 100644 --- a/.github/alternate_byond_versions.txt +++ b/.github/alternate_byond_versions.txt @@ -2,7 +2,12 @@ # This is useful for making sure we maintain compatibility with both older and newer versions, # while still having our main tests run on a guaranteed pinned version. -# Format is version: map +# Format is "version: map" or "version: map;max_required_client_version" # Example: # 500.1337: runtimestation -515.1636: runtimestation +# 516.1638: runtimestation;516 +# Lowest supported version +# NOVA EDIT - Original: 515.1627: runtimestation +515.1637: runtimestation +# Beta version +516.1648: runtimestation;516 diff --git a/.github/guides/STANDARDS.md b/.github/guides/STANDARDS.md index c27c8ae7417e..00fc1efc3849 100644 --- a/.github/guides/STANDARDS.md +++ b/.github/guides/STANDARDS.md @@ -68,8 +68,6 @@ var/path_type = "/obj/item/baseball_bat" * You are expected to help maintain the code that you add, meaning that if there is a problem then you are likely to be approached in order to fix any issues, runtimes, or bugs. -* Do not divide when you can easily convert it to multiplication. (ie `4/2` should be done as `4*0.5`) - * Separating single lines into more readable blocks is not banned, however you should use it only where it makes new information more accessible, or aids maintainability. We do not have a column limit, and mass conversions will not be received well. * If you used regex to replace code during development of your code, post the regex in your PR for the benefit of future developers and downstream users. diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index fab8f6799219..1d93bf93fc47 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -190,7 +190,7 @@ jobs: - name: Find Alternate Tests id: alternate_test_finder run: | - ALTERNATE_TESTS_JSON=$(jq -nRc '[inputs | capture("^(?[0-9]+)\\.(?[0-9]+): (?.+)$")]' .github/alternate_byond_versions.txt) + ALTERNATE_TESTS_JSON=$(jq -nRc '[inputs | capture("^(?[0-9]+)\\.(?[0-9]+): (?[^;]+);?(?[0-9]+)?$")]' .github/alternate_byond_versions.txt) echo "alternate_tests=$ALTERNATE_TESTS_JSON" >> $GITHUB_OUTPUT - name: Collect byond client version configuration id: max_required_byond_client @@ -226,7 +226,7 @@ jobs: map: ${{ matrix.setup.map }} major: ${{ matrix.setup.major }} minor: ${{ matrix.setup.minor }} - max_required_byond_client: ${{needs.collect_data.outputs.max_required_byond_client}} + max_required_byond_client: ${{ matrix.setup.max_client_version || needs.collect_data.outputs.max_required_byond_client }} compare_screenshots: if: needs.collect_data.outputs.alternate_tests == '[]' || needs.run_alternate_tests.result == 'success' @@ -294,10 +294,11 @@ jobs: completion_gate: # Serves as a non-moving target for branch rulesets if: always() && !cancelled() name: Completion Gate - needs: [ test_windows, compare_screenshots, compile_all_maps, run_linters ] + needs: [ test_windows, compare_screenshots, compile_all_maps, run_all_tests, run_alternate_tests, run_linters ] runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} + allowed-skips: compare_screenshots diff --git a/.github/workflows/run_integration_tests.yml b/.github/workflows/run_integration_tests.yml index 3485b90d4748..1a200a2947a9 100644 --- a/.github/workflows/run_integration_tests.yml +++ b/.github/workflows/run_integration_tests.yml @@ -20,7 +20,7 @@ on: jobs: run_integration_tests: runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 20 # NOVA EDIT CHANGE - Original: timeout-minutes: 15 services: mysql: image: mysql:latest diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_phonebooth.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_phonebooth.dmm index 905403954b67..d252e77417ac 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_surface_phonebooth.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_surface_phonebooth.dmm @@ -1,99 +1,119 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/obj/machinery/holopad, -/turf/open/floor/iron/dark/smooth_edge{ +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/powered/icemoon_phone_booth) "c" = ( -/obj/machinery/door/window/left/directional/north, -/obj/machinery/door/window/left/directional/south, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 4 - }, -/area/ruin/powered/icemoon_phone_booth) +/turf/open/floor/plating/snowed/smoothed/icemoon, +/area/icemoon/underground/explored) "e" = ( +/obj/structure/lattice, /turf/open/misc/asteroid/snow/icemoon, -/area/ruin/powered/icemoon_phone_booth) +/area/icemoon/underground/explored) "k" = ( -/obj/machinery/vending/coffee, +/obj/machinery/vending/cigarette{ + all_products_free = 0 + }, /obj/structure/window/reinforced/spawner/directional/east, -/turf/open/floor/plating/icemoon, -/area/ruin/powered/icemoon_phone_booth) -"q" = ( -/obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/tile/yellow/half/contrasted{ - dir = 4 + dir = 8 }, -/obj/machinery/atmospherics/components/tank/air/layer4{ +/obj/effect/turf_decal/weather/snow/corner{ dir = 8 }, -/obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/turf_decal/weather/snow, /turf/open/floor/plating/icemoon, /area/ruin/powered/icemoon_phone_booth) -"v" = ( +"q" = ( /obj/structure/lattice, /obj/structure/billboard/Phone_booth, /turf/open/misc/asteroid/snow/icemoon, -/area/ruin/powered/icemoon_phone_booth) -"z" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ +/area/icemoon/underground/explored) +"v" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 }, +/obj/item/gps/spaceruin{ + gpstag = "Public Holophone" + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/effect/turf_decal/weather/snow, +/turf/open/floor/plating/icemoon, +/area/ruin/powered/icemoon_phone_booth) +"z" = ( +/obj/machinery/door/window/left/directional/north, +/obj/machinery/door/window/left/directional/south, +/obj/effect/turf_decal/weather/snow/corner, /turf/open/floor/iron/dark/smooth_edge{ - dir = 4 + dir = 1 }, /area/ruin/powered/icemoon_phone_booth) "J" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 }, -/obj/item/gps/spaceruin{ - gpstag = "Public Holophone" - }, -/obj/machinery/light/small{ - dir = 1 +/obj/machinery/atmospherics/components/tank/air/layer4{ + dir = 8 }, /obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow, /turf/open/floor/plating/icemoon, /area/ruin/powered/icemoon_phone_booth) "M" = ( /turf/closed/wall/ice, /area/ruin/powered/icemoon_phone_booth) "R" = ( -/obj/effect/spawner/structure/window/hollow/reinforced, -/turf/open/floor/plating/icemoon, +/obj/machinery/holopad, +/obj/machinery/airalarm/directional/north, +/obj/effect/mapping_helpers/airalarm/all_access, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/powered/icemoon_phone_booth) "V" = ( -/obj/structure/lattice, -/turf/open/misc/asteroid/snow/icemoon, -/area/ruin/powered/icemoon_phone_booth) -"W" = ( -/obj/machinery/vending/cigarette{ - all_products_free = 0 - }, +/obj/machinery/vending/coffee, /obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow, /turf/open/floor/plating/icemoon, /area/ruin/powered/icemoon_phone_booth) +"W" = ( +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/underground/explored) (1,1,1) = {" -v +q M +V k -W M +c "} (2,1,1) = {" -e +W +M R a z c "} (3,1,1) = {" -V +e M +v J -q M +c "} diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm index d5c344e9cd31..3553672b1080 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm @@ -993,9 +993,6 @@ /area/ruin/comms_agent) "UI" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/records/security/laptop/syndie{ - dir = 1 - }, /obj/item/paper/monitorkey{ pixel_x = -15; pixel_y = 7 diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_frozen_comms.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_frozen_comms.dmm index eb537cd26f6c..54b33b5e8111 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_frozen_comms.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_frozen_comms.dmm @@ -311,7 +311,7 @@ }, /obj/structure/rack, /obj/item/wrench, -/obj/item/crowbar/large/heavy, +/obj/item/crowbar/large/twenty_force, /obj/machinery/light/small/built/directional/south, /turf/open/floor/plating/icemoon, /area/ruin/powered/shuttle) diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm index 228c55292fbb..e41c2db68632 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm @@ -3503,7 +3503,7 @@ /area/ruin/syndibiodome) "Pw" = ( /obj/structure/table/reinforced/plastitaniumglass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/siding/wideplating/dark{ dir = 5 }, diff --git a/_maps/RandomRuins/LavaRuins/nova/lavaland_surface_interdyne_base1.dmm b/_maps/RandomRuins/LavaRuins/nova/lavaland_surface_interdyne_base1.dmm index cc273a2792d9..28230fd5e08b 100644 --- a/_maps/RandomRuins/LavaRuins/nova/lavaland_surface_interdyne_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/nova/lavaland_surface_interdyne_base1.dmm @@ -2005,7 +2005,7 @@ /area/ruin/interdyne_planetary_base/eng) "qw" = ( /obj/structure/table/reinforced/rglass, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /obj/machinery/camera/autoname/directional/east{ network = list("intd13") }, diff --git a/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_1.dmm b/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_1.dmm index 5d7b0c4bee51..4f032c8ac053 100644 --- a/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_1.dmm +++ b/_maps/RandomRuins/SpaceRuins/DJstation/kitchen_1.dmm @@ -30,7 +30,6 @@ /area/ruin/space/djstation) "t" = ( /obj/structure/closet/secure_closet/freezer/fridge/all_access, -/obj/machinery/light/directional/south, /obj/effect/turf_decal/tile/bar/opposingcorners, /obj/machinery/light/small/directional/south, /turf/open/floor/iron, diff --git a/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm b/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm index c396ddb4121e..ccbe450085dc 100644 --- a/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm +++ b/_maps/RandomRuins/SpaceRuins/anomaly_research.dmm @@ -351,7 +351,7 @@ "kp" = ( /obj/effect/spawner/random/environmentally_safe_anomaly/immobile, /turf/template_noop, -/area/space) +/area/space/nearstation) "kt" = ( /obj/effect/turf_decal/tile/purple/half/contrasted{ dir = 1 diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index a52a428a8258..5e219273e136 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -584,7 +584,7 @@ name = "dried blood trail" }, /mob/living/basic/creature{ - desc = "Awh its so sm-OH GOD WHAT THE FUCK."; + desc = "Awh, it's so sm-OH GOD, WHAT THE FUCK."; health = 25; maxHealth = 25; name = "hatchling"; diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index a8a4a968d976..1ecb40291e33 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -285,7 +285,7 @@ /turf/open/misc/asteroid/airless, /area/ruin/space) "ET" = ( -/mob/living/basic/lizard, +/mob/living/basic/lizard/space, /turf/open/misc/asteroid/airless, /area/ruin/space) "Fo" = ( diff --git a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm index 52a288e64e6d..42fa98704a30 100644 --- a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm +++ b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm @@ -98,7 +98,7 @@ /turf/open/floor/iron/white, /area/ruin/space/has_grav/dangerous_research/medical) "aZ" = ( -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/structure/table, /turf/open/floor/plating/rust, /area/ruin/space/has_grav/dangerous_research/medical) diff --git a/_maps/RandomRuins/SpaceRuins/garbagetruck4.dmm b/_maps/RandomRuins/SpaceRuins/garbagetruck4.dmm index aa15bb27e8b9..35b18eff47ff 100644 --- a/_maps/RandomRuins/SpaceRuins/garbagetruck4.dmm +++ b/_maps/RandomRuins/SpaceRuins/garbagetruck4.dmm @@ -122,7 +122,6 @@ /area/ruin/space/has_grav/garbagetruck/toystore) "lm" = ( /obj/structure/spider/stickyweb, -/obj/structure/spider/stickyweb/very_sticky, /turf/open/floor/plating, /area/ruin/space/has_grav/garbagetruck/toystore) "mf" = ( @@ -182,7 +181,6 @@ /turf/open/floor/plating, /area/ruin/space/has_grav/garbagetruck/toystore) "qX" = ( -/obj/structure/spider/stickyweb/very_sticky, /obj/item/food/badrecipe/moldy, /obj/structure/spider/stickyweb, /obj/item/food/spidereggs{ diff --git a/_maps/RandomRuins/SpaceRuins/interdyne.dmm b/_maps/RandomRuins/SpaceRuins/interdyne.dmm index 9c802b0be434..46e22d19fb67 100644 --- a/_maps/RandomRuins/SpaceRuins/interdyne.dmm +++ b/_maps/RandomRuins/SpaceRuins/interdyne.dmm @@ -1015,7 +1015,7 @@ /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/interdyne) "PD" = ( -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/structure/table/reinforced/rglass, /turf/open/floor/mineral/plastitanium, /area/ruin/space/has_grav/interdyne) diff --git a/_maps/RandomRuins/SpaceRuins/meatderelict.dmm b/_maps/RandomRuins/SpaceRuins/meatderelict.dmm index 3e4bece11e8e..96959954e267 100644 --- a/_maps/RandomRuins/SpaceRuins/meatderelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/meatderelict.dmm @@ -484,7 +484,7 @@ /obj/effect/turf_decal/siding/blue{ dir = 6 }, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/indestructible/white, /area/ruin/space/has_grav/powered/biooutpost) "kh" = ( @@ -728,8 +728,8 @@ /obj/effect/turf_decal/siding/purple{ dir = 1 }, -/obj/item/ammo_casing/a357/spent, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/indestructible/white, /area/ruin/space/has_grav/powered/biooutpost) "oQ" = ( @@ -887,7 +887,7 @@ /obj/effect/turf_decal/siding/purple{ dir = 1 }, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/indestructible/white, /area/ruin/space/has_grav/powered/biooutpost) "rl" = ( @@ -1561,9 +1561,9 @@ /turf/open/indestructible/plating, /area/ruin/space/has_grav/powered/biooutpost) "DC" = ( -/obj/item/ammo_casing/a357/spent, -/obj/item/ammo_casing/a357/spent, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, +/obj/item/ammo_casing/c357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/indestructible/white, /area/ruin/space/has_grav/powered/biooutpost) "DJ" = ( diff --git a/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm b/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm index c98a43e89c2a..7a76e71debf6 100644 --- a/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm +++ b/_maps/RandomRuins/SpaceRuins/mimesvsclowns.dmm @@ -6,7 +6,7 @@ /area/ruin) "dI" = ( /obj/item/grown/bananapeel, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 9; pixel_x = -13; pixel_y = 10 @@ -78,19 +78,19 @@ }, /obj/effect/decal/cleanable/blood/gibs, /obj/machinery/light/small/broken/directional/south, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/floor/iron/checker/airless, /area/ruin) "uc" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 4 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = -5; dir = 5; pixel_y = 6 }, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /obj/item/gps/spaceruin, /turf/open/floor/plating/airless, /area/ruin) @@ -204,7 +204,7 @@ /obj/effect/mob_spawn/corpse/human/clown, /obj/effect/decal/cleanable/blood/footprints, /obj/effect/decal/cleanable/dirt, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/floor/plating/airless, /area/ruin) "Ij" = ( @@ -253,7 +253,7 @@ "Pq" = ( /obj/machinery/light/broken/directional/north, /obj/structure/reagent_dispensers/watertank, -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /turf/open/floor/iron/checker/airless, /area/ruin) "Qb" = ( diff --git a/_maps/RandomRuins/SpaceRuins/nova/blackmarket.dmm b/_maps/RandomRuins/SpaceRuins/nova/blackmarket.dmm index 12f01c218fe6..df9f82f50959 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/blackmarket.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/blackmarket.dmm @@ -236,7 +236,7 @@ "mg" = ( /obj/structure/marker_beacon/teal, /obj/structure/lattice/catwalk, -/turf/open/space/basic, +/turf/open/misc/asteroid/airless, /area/ruin/space/has_grav/nova/blackmarket) "mH" = ( /obj/effect/decal/cleanable/dirt, @@ -426,7 +426,7 @@ "ve" = ( /obj/structure/marker_beacon/burgundy, /obj/structure/lattice/catwalk, -/turf/open/space/basic, +/turf/open/misc/asteroid/airless, /area/ruin/space/has_grav/nova/blackmarket) "vg" = ( /obj/effect/turf_decal/bot_white, @@ -873,7 +873,7 @@ /area/ruin/space/has_grav/nova/blackmarket) "Qu" = ( /obj/structure/lattice/catwalk, -/turf/open/space/basic, +/turf/open/misc/asteroid/airless, /area/ruin/space/has_grav/nova/blackmarket) "QB" = ( /obj/effect/decal/cleanable/dirt, diff --git a/_maps/RandomRuins/SpaceRuins/nova/cargodiselost.dmm b/_maps/RandomRuins/SpaceRuins/nova/cargodiselost.dmm index e23c28e58d91..2e07fc66302e 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/cargodiselost.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/cargodiselost.dmm @@ -2805,7 +2805,7 @@ /obj/item/storage/organbox{ pixel_y = 6 }, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 8 }, diff --git a/_maps/RandomRuins/SpaceRuins/nova/crash.dmm b/_maps/RandomRuins/SpaceRuins/nova/crash.dmm index 50aa0d0c86a8..7eef44b99596 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/crash.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/crash.dmm @@ -47,7 +47,7 @@ /obj/machinery/power/shuttle_engine/propulsion{ dir = 8 }, -/turf/template_noop, +/turf/open/floor/plating/airless, /area/ruin/unpowered/no_grav) "H" = ( /obj/effect/decal/cleanable/blood, diff --git a/_maps/RandomRuins/SpaceRuins/nova/des_two.dmm b/_maps/RandomRuins/SpaceRuins/nova/des_two.dmm index 22dcb5cb1664..017b03980220 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/des_two.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/des_two.dmm @@ -7750,8 +7750,7 @@ /turf/open/floor/plating/airless, /area/ruin/space/has_grav/nova/des_two) "IE" = ( -/obj/structure/lattice, -/turf/open/space/basic, +/turf/open/floor/plating/airless, /area/ruin/space/has_grav/nova/des_two/engineering) "IG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, diff --git a/_maps/RandomRuins/SpaceRuins/nova/ghostship.dmm b/_maps/RandomRuins/SpaceRuins/nova/ghostship.dmm index 5922c8c5c4f5..34fa2a0cad91 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/ghostship.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/ghostship.dmm @@ -10,48 +10,48 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ct" = ( /obj/effect/decal/cleanable/wrapping{ pixel_y = 19 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "eL" = ( /obj/machinery/portable_atmospherics/canister/freon{ name = "Coolant canister" }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fj" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/small/red/directional/south, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fo" = ( /obj/effect/decal/fakelattice/passthru, /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fF" = ( /obj/structure/frame/computer{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fM" = ( /obj/structure/sign/warning, /obj/structure/cable, /turf/closed/wall/r_wall{ color = "#7a9ee0" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "go" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -59,14 +59,14 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gw" = ( /obj/effect/decal/cleanable/robot_debris/limb{ pixel_y = -7 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gx" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/tank_holder/oxygen{ @@ -76,14 +76,14 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hf" = ( /obj/machinery/door/airlock/multi_tile/metal{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hn" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ @@ -97,7 +97,7 @@ pixel_y = 11 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hp" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -106,7 +106,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "iF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible/layer1, /turf/template_noop, @@ -115,7 +115,7 @@ /obj/structure/lattice, /obj/structure/grille, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jx" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -128,14 +128,14 @@ /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/dim/directional/south, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jA" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/chair/comfy/shuttle, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jJ" = ( /obj/structure/frame/computer{ dir = 4 @@ -146,13 +146,13 @@ pixel_y = -10 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jL" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible/layer1, /turf/closed/wall/r_wall{ color = "#7a9ee0" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jM" = ( /obj/structure/table, /obj/item/storage/toolbox/electrical{ @@ -166,7 +166,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/red/directional/south, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "kg" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/chair/comfy/shuttle, @@ -174,13 +174,13 @@ /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/dim/directional/west, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "kh" = ( /obj/effect/decal/cleanable/robot_debris/limb, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "kQ" = ( /obj/effect/decal/cleanable/generic{ pixel_x = 14 @@ -193,7 +193,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lw" = ( /obj/item/ai_module/toy_ai{ desc = "A totally real AI, the first of its kind to achieve self-awareness. Totally real."; @@ -211,7 +211,7 @@ pixel_y = 24 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lA" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, @@ -220,7 +220,7 @@ pixel_y = 3 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lG" = ( /obj/item/trash/boritos, /obj/effect/decal/cleanable/dirt, @@ -231,7 +231,7 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mx" = ( /obj/structure/table, /obj/item/stock_parts/power_store/cell/hyper{ @@ -245,7 +245,7 @@ /obj/effect/decal/cleanable/dirt, /obj/item/disk/design_disk/bepis, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mW" = ( /obj/effect/decal/cleanable/greenglow, /obj/effect/decal/cleanable/dirt, @@ -253,52 +253,52 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nz" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /turf/closed/wall/r_wall{ color = "#7a9ee0" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "oc" = ( /obj/machinery/door/airlock/multi_tile/metal{ dir = 4 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pw" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4{ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pD" = ( /obj/machinery/power/smes, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "qW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/visible/layer1, /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "rb" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /obj/structure/decorative/shelf/soda_milk, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "rp" = ( /obj/structure/cable, /obj/effect/decal/cleanable/robot_debris/limb, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "sk" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/red/directional/north, @@ -313,19 +313,19 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "sp" = ( /obj/structure/cable, /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "sz" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/small/red/directional/north, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ts" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -337,25 +337,25 @@ /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/dim/directional/west, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tz" = ( /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tV" = ( /obj/effect/decal/cleanable/generic, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vi" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair/comfy/shuttle{ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vt" = ( /obj/machinery/power/shuttle_engine/heater{ dir = 4 @@ -370,13 +370,13 @@ /obj/item/taperecorder/empty, /obj/machinery/light/dim/directional/west, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "wH" = ( /obj/effect/decal/cleanable/robot_debris/limb, /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "wN" = ( /obj/effect/decal/cleanable/robot_debris/limb{ pixel_x = -16; @@ -385,28 +385,28 @@ /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xq" = ( /obj/structure/frame/computer{ dir = 1 }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xs" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/layer4{ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xF" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xP" = ( /obj/structure/lattice, /turf/template_noop, @@ -419,11 +419,11 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yi" = ( /obj/structure/fans/tiny, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yG" = ( /obj/machinery/door_buttons/access_button{ pixel_x = 9; @@ -432,7 +432,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yU" = ( /obj/effect/decal/cleanable/generic, /obj/effect/decal/cleanable/dirt, @@ -440,13 +440,13 @@ pixel_y = -10 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zE" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/chair/comfy/shuttle, @@ -457,7 +457,7 @@ /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/dim/directional/north, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zM" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -468,14 +468,14 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Cc" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc/auto_name/directional/north, /obj/effect/mapping_helpers/apc/unlocked, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Cp" = ( /obj/machinery/atmospherics/pipe/layer_manifold/orange/visible{ dir = 4 @@ -483,7 +483,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ct" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -500,7 +500,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "DN" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/layer2, /obj/structure/lattice, @@ -510,7 +510,7 @@ /obj/effect/decal/cleanable/plastic, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ga" = ( /obj/machinery/portable_atmospherics/canister/plasma{ desc = "Plasma gas. Highly fuel efficient. Highly volatile. Highly toxic."; @@ -521,16 +521,16 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Gq" = ( /turf/closed/wall/mineral/titanium/spaceship{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "He" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ij" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/asteroid/corner{ @@ -540,7 +540,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Iy" = ( /obj/effect/decal/cleanable/robot_debris/limb, /obj/effect/decal/cleanable/dirt, @@ -548,7 +548,7 @@ dir = 8 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "IJ" = ( /obj/machinery/door_buttons/access_button{ pixel_x = 9; @@ -557,7 +557,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JX" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -567,44 +567,44 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Kj" = ( /obj/item/trash/energybar, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Kt" = ( /obj/effect/decal/fakelattice/passthru, /turf/closed/wall/mineral/titanium/spaceship{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "KR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/layer4{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "KZ" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Li" = ( /obj/structure/rack, /obj/item/stack/sheet/glass/fifty, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Lk" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{ dir = 1 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "LT" = ( /obj/machinery/airalarm/directional/south{ pixel_x = -5 @@ -613,32 +613,32 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "LV" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/generic, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Mo" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Mp" = ( /obj/effect/decal/cleanable/plastic, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/small/red/directional/south, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "MQ" = ( /obj/effect/decal/cleanable/oil, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "MY" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ @@ -648,18 +648,18 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Oj" = ( /obj/structure/window/reinforced/shuttle/spaceship{ color = "#8ab1ec" }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Pr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/structure/crate_loot, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Qc" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -675,16 +675,16 @@ pixel_y = -25 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QC" = ( /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QF" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/tank/air, /obj/machinery/atmospherics/components/unary/portables_connector/visible/layer4, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/frame/computer{ @@ -695,13 +695,13 @@ pixel_y = -3 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "RQ" = ( /obj/machinery/power/shuttle_engine/propulsion{ dir = 4 }, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "SR" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -711,7 +711,7 @@ /obj/effect/decal/fakelattice/passthru, /obj/effect/spawner/random/maintenance/three, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ta" = ( /obj/effect/decal/cleanable/generic{ pixel_x = 4; @@ -719,7 +719,7 @@ }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "TM" = ( /obj/machinery/door_buttons/airlock_controller{ pixel_x = 9 @@ -727,7 +727,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "TW" = ( /turf/template_noop, /area/template_noop) @@ -738,7 +738,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Uw" = ( /obj/machinery/power/terminal, /obj/structure/cable, @@ -749,7 +749,7 @@ pixel_y = -24 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "UL" = ( /obj/machinery/power/shuttle_engine/heater{ dir = 4 @@ -757,7 +757,7 @@ /turf/closed/wall/r_wall{ color = "#7a9ee0" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Vv" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/portable_atmospherics/canister/plasma{ @@ -768,17 +768,17 @@ dir = 4 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "WH" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Xr" = ( /turf/closed/wall/r_wall{ color = "#7a9ee0" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Xz" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/decorative/fluff/ai_node{ @@ -786,12 +786,12 @@ pixel_y = 23 }, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Yd" = ( /obj/item/trash/cheesie, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "YN" = ( /obj/structure/closet, /obj/effect/turf_decal/stripes/line{ @@ -801,12 +801,12 @@ /obj/effect/decal/fakelattice/passthru, /obj/machinery/light/dim/directional/west, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "YT" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Zf" = ( /obj/machinery/power/shuttle_engine/heater{ dir = 4 @@ -815,7 +815,7 @@ /turf/closed/wall/mineral/titanium/spaceship/nodiagonal{ color = "#8ab1ec" }, -/area/ruin/unpowered) +/area/ruin/space/unpowered) (1,1,1) = {" TW diff --git a/_maps/RandomRuins/SpaceRuins/nova/piratefort.dmm b/_maps/RandomRuins/SpaceRuins/nova/piratefort.dmm index 49e1989d0279..0bfbbae6a1e6 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/piratefort.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/piratefort.dmm @@ -329,7 +329,7 @@ "lC" = ( /obj/structure/lattice/catwalk, /obj/structure/marker_beacon/burgundy, -/turf/open/space/basic, +/turf/open/floor/engine/airless, /area/ruin/space) "lV" = ( /obj/machinery/power/smes/magical{ @@ -1346,7 +1346,7 @@ /area/ruin/space/has_grav/powered) "UM" = ( /obj/structure/lattice/catwalk, -/turf/open/space/basic, +/turf/open/floor/engine/airless, /area/ruin/space) "Vm" = ( /obj/machinery/door/airlock/captain, diff --git a/_maps/RandomRuins/SpaceRuins/nova/port_tarkon.dmm b/_maps/RandomRuins/SpaceRuins/nova/port_tarkon.dmm index 0ecdac067745..5b11c5dc3ff7 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/port_tarkon.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/port_tarkon.dmm @@ -3544,7 +3544,7 @@ "xE" = ( /obj/effect/turf_decal/tile/purple/half, /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/port_tarkon/developement) "xG" = ( @@ -5153,7 +5153,7 @@ dir = 4 }, /obj/structure/table/rolling, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/machinery/button/polarizer{ id = "tarkon_med1"; pixel_x = 31 diff --git a/_maps/RandomRuins/SpaceRuins/nova/scrapheap.dmm b/_maps/RandomRuins/SpaceRuins/nova/scrapheap.dmm index cfa0839b8e93..6af4ec2c4735 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/scrapheap.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/scrapheap.dmm @@ -1123,7 +1123,7 @@ /area/ruin/space/has_grav/powered/nova/scrapheap) "Ej" = ( /obj/structure/rack/shelf, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/white, /area/ruin/space/has_grav/powered/nova/scrapheap) "El" = ( @@ -1704,7 +1704,6 @@ /turf/closed/indestructible/fakedoor/maintenance, /area/ruin/space/has_grav/powered/nova/scrapheap) "QW" = ( -/obj/effect/mapping_helpers/airlock/locked, /turf/closed/indestructible/fakedoor/glass_airlock, /area/ruin/space/has_grav/powered/nova/scrapheap) "RA" = ( diff --git a/_maps/RandomRuins/SpaceRuins/nova/shuttlescrap.dmm b/_maps/RandomRuins/SpaceRuins/nova/shuttlescrap.dmm index 831767c1af0c..49422d7e2352 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/shuttlescrap.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/shuttlescrap.dmm @@ -89,7 +89,7 @@ /obj/machinery/power/shuttle_engine/propulsion{ dir = 8 }, -/turf/template_noop, +/turf/open/floor/plating/airless, /area/ruin/unpowered/no_grav) "P" = ( /obj/effect/mob_spawn/corpse/human/syndicatecommando, diff --git a/_maps/RandomRuins/SpaceRuins/nova/spacehotel.dmm b/_maps/RandomRuins/SpaceRuins/nova/spacehotel.dmm index 5fcfa52070cf..cb025c90255a 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/spacehotel.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/spacehotel.dmm @@ -7135,7 +7135,7 @@ /area/ruin/space/has_grav/hotel) "Ps" = ( /obj/structure/table, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/showroomfloor, /area/ruin/space/has_grav/hotel) "Pw" = ( diff --git a/_maps/RandomRuins/SpaceRuins/nova/waypointstation.dmm b/_maps/RandomRuins/SpaceRuins/nova/waypointstation.dmm index eae8b1f5a763..b4a4e268a108 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/waypointstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/waypointstation.dmm @@ -7,7 +7,7 @@ "ay" = ( /obj/item/stack/sheet/iron, /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "aR" = ( /obj/machinery/light/broken/directional/north, /turf/open/floor/iron/airless, @@ -28,7 +28,9 @@ /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "bF" = ( -/mob/living/basic/alien/queen/large, +/mob/living/basic/alien/queen/large{ + minimum_survivable_temperature = 0 + }, /obj/structure/alien/weeds, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) @@ -52,9 +54,11 @@ /area/ruin/space/has_grav/waypoint) "co" = ( /obj/structure/lattice, -/mob/living/basic/alien, +/mob/living/basic/alien{ + minimum_survivable_temperature = 0 + }, /turf/template_noop, -/area/ruin) +/area/ruin/space/unpowered) "cV" = ( /obj/effect/decal/cleanable/blood/drip, /turf/open/floor/iron/airless, @@ -67,14 +71,16 @@ /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) "dz" = ( -/mob/living/basic/alien, +/mob/living/basic/alien{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "dQ" = ( /obj/item/shard, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "eD" = ( /obj/item/stack/cable_coil/cut{ pixel_x = 2; @@ -137,10 +143,12 @@ /obj/item/stack/tile/iron/base, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "hE" = ( /obj/effect/decal/cleanable/blood/tracks, -/mob/living/basic/alien, +/mob/living/basic/alien{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "iu" = ( @@ -162,7 +170,7 @@ "ju" = ( /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "ka" = ( /turf/open/floor/plating/airless, /area/ruin/space/has_grav/waypoint) @@ -175,12 +183,16 @@ /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) "kR" = ( -/mob/living/basic/alien/sentinel, +/mob/living/basic/alien/sentinel{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "lf" = ( /obj/effect/decal/cleanable/blood/drip, -/mob/living/basic/alien, +/mob/living/basic/alien{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "lr" = ( @@ -222,7 +234,7 @@ /obj/item/stack/sheet/iron, /obj/structure/lattice, /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "mJ" = ( /obj/effect/mob_spawn/corpse/human/cargo_tech, /obj/effect/decal/cleanable/blood/splatter, @@ -241,12 +253,16 @@ /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "nC" = ( -/mob/living/basic/alien/drone, +/mob/living/basic/alien/drone{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "nO" = ( -/mob/living/basic/alien, /obj/structure/alien/weeds, +/mob/living/basic/alien{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "oa" = ( @@ -298,13 +314,17 @@ /obj/structure/alien/weeds, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) +"qR" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/ruin/space) "qT" = ( /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) "ra" = ( /obj/item/stack/tile/iron/base, /turf/template_noop, -/area/ruin) +/area/ruin/space) "rc" = ( /obj/effect/decal/cleanable/blood/tracks{ dir = 9 @@ -351,7 +371,9 @@ pixel_x = -3; pixel_y = 10 }, -/mob/living/basic/alien/sentinel, +/mob/living/basic/alien/sentinel{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) "sw" = ( @@ -432,6 +454,9 @@ "wB" = ( /turf/closed/wall, /area/ruin/space/has_grav/waypoint) +"wY" = ( +/turf/template_noop, +/area/ruin/space/unpowered) "xi" = ( /obj/effect/decal/cleanable/blood/gibs/up, /turf/open/floor/carpet/royalblue/airless, @@ -447,6 +472,10 @@ }, /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) +"xU" = ( +/obj/item/stack/tile/iron/base, +/turf/open/floor/plating/airless, +/area/ruin/space/unpowered) "yn" = ( /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/structure/alien/weeds, @@ -476,9 +505,11 @@ /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "zy" = ( -/mob/living/basic/alien/drone, /obj/effect/decal/cleanable/xenoblood, /obj/structure/sign/poster/contraband/lusty_xenomorph/directional/east, +/mob/living/basic/alien/drone{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) "zE" = ( @@ -498,9 +529,14 @@ }, /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) +"zJ" = ( +/turf/template_noop, +/area/ruin/space) "Af" = ( -/mob/living/basic/alien/sentinel, /obj/structure/alien/weeds/node, +/mob/living/basic/alien/sentinel{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "Al" = ( @@ -517,7 +553,9 @@ /area/ruin/space/has_grav/waypoint) "AG" = ( /obj/effect/decal/cleanable/blood/drip, -/mob/living/basic/alien/drone, +/mob/living/basic/alien/drone{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) "AP" = ( @@ -537,7 +575,9 @@ }, /obj/effect/decal/cleanable/blood/splatter, /obj/machinery/light/small/broken/directional/north, -/mob/living/basic/alien/sentinel, +/mob/living/basic/alien/sentinel{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) "BD" = ( @@ -619,6 +659,10 @@ /obj/effect/decal/cleanable/blood/gibs/torso, /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) +"FC" = ( +/obj/item/stack/sheet/iron, +/turf/template_noop, +/area/ruin/space/unpowered) "FS" = ( /turf/closed/mineral/bananium, /area/ruin/space) @@ -626,6 +670,10 @@ /obj/effect/spawner/random/vending/colavend, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) +"Gj" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating/airless, +/area/ruin/space/unpowered) "Gv" = ( /obj/machinery/power/solar/fake, /turf/open/floor/iron/solarpanel/airless, @@ -650,6 +698,11 @@ /obj/item/flashlight/flare, /turf/open/floor/iron/airless, /area/ruin/space/has_grav/waypoint) +"Hs" = ( +/obj/item/shard, +/obj/structure/lattice, +/turf/template_noop, +/area/ruin/space/unpowered) "Hx" = ( /obj/item/shard{ pixel_x = -6; @@ -727,7 +780,7 @@ /area/ruin/space/has_grav/waypoint) "Ke" = ( /turf/template_noop, -/area/ruin) +/area/ruin/space/has_grav/waypoint) "Kh" = ( /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/airless, @@ -959,9 +1012,15 @@ /obj/item/stack/cable_coil{ pixel_y = -3 }, -/mob/living/basic/alien/drone, +/mob/living/basic/alien/drone{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/waypoint) +"Vy" = ( +/obj/structure/lattice, +/turf/template_noop, +/area/ruin/space/unpowered) "VK" = ( /obj/effect/decal/cleanable/blood/splatter, /obj/item/stack/cable_coil/cut{ @@ -971,7 +1030,9 @@ /turf/open/floor/carpet/royalblue/airless, /area/ruin/space/has_grav/waypoint) "Wg" = ( -/mob/living/basic/alien/drone, +/mob/living/basic/alien/drone{ + minimum_survivable_temperature = 0 + }, /turf/open/floor/plating/airless, /area/ruin/space/has_grav/waypoint) "Wu" = ( @@ -1030,7 +1091,7 @@ "YL" = ( /obj/item/shard, /turf/template_noop, -/area/ruin) +/area/ruin/space) "YT" = ( /turf/closed/wall/r_wall/syndicate, /area/ruin/space/has_grav/waypoint) @@ -1372,9 +1433,9 @@ hl hl ka co -ju -ju -Ke +Vy +Vy +zJ rH eP eP @@ -1433,10 +1494,10 @@ ka rh pB ka -bG -dQ -Ke -Ke +Gj +Hs +wY +wY eP eP eP @@ -1495,10 +1556,10 @@ ka ka Pj bG -ju -Ke -Ke -Ke +Vy +wY +wY +wY eP eP eP @@ -1557,10 +1618,10 @@ qh bD bG ka -ZA -bG -ju -ay +xU +Gj +Vy +FC eP OB eP @@ -1620,9 +1681,9 @@ qh yn zu bG -ju -Ke -Ke +Vy +wY +wY eP eP eP @@ -1683,7 +1744,7 @@ hl qh Pj ZA -ju +Vy Ke ju Ke @@ -2870,7 +2931,7 @@ eP bG IC bG -ju +qR OC eP rH @@ -2930,10 +2991,10 @@ eP eP eP ZA -ju -Ke +qR +zJ YL -ju +qR eP eP eP @@ -2991,11 +3052,11 @@ eP eP eP eP -ju +qR bG -Ke +zJ ra -ju +qR eP eP eP diff --git a/_maps/RandomRuins/SpaceRuins/nova/whiteshipruin_box.dmm b/_maps/RandomRuins/SpaceRuins/nova/whiteshipruin_box.dmm index 1b876c3b8afa..6570abdc5cde 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/whiteshipruin_box.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/whiteshipruin_box.dmm @@ -14,13 +14,6 @@ /obj/effect/decal/cleanable/glass/plastitanium, /turf/open/floor/mineral/titanium/white/airless, /area/ruin/space/has_grav/whiteship/box) -"az" = ( -/obj/machinery/power/shuttle_engine/large{ - dir = 8; - pixel_x = 8 - }, -/turf/open/space/basic, -/area/ruin/space/has_grav/whiteship/box) "aB" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/broken/directional/north, @@ -1133,9 +1126,6 @@ "Jy" = ( /turf/closed/mineral/random, /area/ruin/space/has_grav/whiteship/box) -"JF" = ( -/turf/open/space/basic, -/area/ruin/space/has_grav/whiteship/box) "JI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/dark, /obj/machinery/light/broken/directional/east, @@ -1654,13 +1644,13 @@ nH nH nH nH -JF -az -JF -JF -JF -JF -az +nH +FN +nH +nH +nH +nH +FN nH nH nH diff --git a/_maps/RandomRuins/SpaceRuins/nova/wreckedfriendship.dmm b/_maps/RandomRuins/SpaceRuins/nova/wreckedfriendship.dmm index 0f4d155b7ad0..5a21d12bdf64 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/wreckedfriendship.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/wreckedfriendship.dmm @@ -4,13 +4,13 @@ dir = 8 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "aq" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 10 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "aC" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -22,43 +22,43 @@ icon_state = "medium" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "aI" = ( /obj/item/shard{ icon_state = "medium" }, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "bf" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 9 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "bj" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "bt" = ( /obj/structure/lattice, /obj/item/shard{ icon_state = "medium" }, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "bV" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "cb" = ( /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "cD" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -69,7 +69,7 @@ /obj/effect/mob_spawn/corpse/human/charredskeleton, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "dd" = ( /obj/effect/turf_decal/tile/green{ dir = 1 @@ -84,38 +84,38 @@ /obj/effect/decal/cleanable/blood, /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "do" = ( /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "du" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 5 }, /obj/effect/mob_spawn/corpse/human/skeleton, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "dB" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 8 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "dL" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 }, /obj/structure/grille/broken, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "dX" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/item/shard{ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ea" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -128,38 +128,38 @@ }, /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "eg" = ( /obj/structure/grille, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "eo" = ( /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "eq" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ev" = ( /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/engine/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fh" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/item/shard{ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fG" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fN" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 1 @@ -167,11 +167,11 @@ /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "fZ" = ( /obj/structure/grille/broken, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gl" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -185,7 +185,7 @@ /obj/effect/turf_decal/tile/blue, /obj/structure/grille/broken, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gw" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -195,7 +195,7 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gB" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 @@ -205,14 +205,14 @@ }, /obj/item/shard, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "gI" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hb" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 @@ -225,11 +225,11 @@ }, /obj/effect/turf_decal/tile/purple, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hi" = ( /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "hy" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -237,32 +237,32 @@ /obj/effect/turf_decal/trimline/green/filled/corner, /obj/structure/grille/broken, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ic" = ( /obj/machinery/power/shuttle_engine/heater{ dir = 8 }, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "id" = ( /obj/item/ammo_casing/c9mm, /obj/item/stack/rods, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "iC" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, /obj/effect/turf_decal/trimline/green/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "iU" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 6 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jj" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 9 @@ -270,33 +270,33 @@ /obj/effect/turf_decal/trimline/purple/filled/corner, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jx" = ( /obj/effect/turf_decal/bot_red, /obj/item/shard{ icon_state = "medium" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "jG" = ( /obj/item/shard{ icon_state = "small" }, /obj/item/stack/rods, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "kk" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 9 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "km" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 5 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "kF" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -309,20 +309,20 @@ }, /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lf" = ( /obj/effect/mob_spawn/corpse/human/engineer{ brute_damage = 200 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lp" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lw" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -330,21 +330,21 @@ /obj/structure/grille/broken, /obj/item/shard, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "lE" = ( /obj/structure/lattice, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mp" = ( /obj/effect/decal/cleanable/blood, /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mx" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/engine/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mN" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -354,42 +354,42 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "mP" = ( /obj/effect/turf_decal/trimline/white/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "na" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nv" = ( /obj/item/shard{ icon_state = "medium" }, /obj/item/stack/rods, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nF" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 6 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nH" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 10 }, /obj/item/shard, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nN" = ( /obj/item/stack/rods, /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "nP" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/turf_decal/trimline/purple/filled/corner{ @@ -397,24 +397,24 @@ }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ok" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 10 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "om" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "oo" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ph" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -427,37 +427,37 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pl" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 6 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pu" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 4 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pA" = ( /obj/effect/turf_decal/trimline/brown/filled/line, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "pZ" = ( /obj/effect/turf_decal/trimline/green/filled/line, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "qv" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 }, /obj/effect/turf_decal/trimline/brown/filled/corner, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "qM" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -470,7 +470,7 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "qR" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 9 @@ -478,14 +478,14 @@ /obj/item/ammo_casing/c9mm, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ry" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 }, /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "sn" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 6 @@ -495,7 +495,7 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "sK" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -504,7 +504,7 @@ /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tc" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -518,24 +518,24 @@ /obj/effect/turf_decal/tile/neutral, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "te" = ( /obj/item/ammo_casing/c9mm, /obj/item/shard{ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tn" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 }, /obj/effect/mob_spawn/corpse/human/engineer, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tv" = ( /turf/open/floor/engine/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tw" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 1 @@ -543,58 +543,58 @@ /obj/effect/turf_decal/trimline/brown/filled/line, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tD" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tE" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tK" = ( /obj/effect/decal/cleanable/blood, /obj/effect/mob_spawn/corpse/human/clown, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tW" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 8 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "tX" = ( /obj/structure/lattice, /obj/item/stack/rods, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ub" = ( /turf/open/floor/carpet/black/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ud" = ( /obj/item/stack/rods, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ui" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, /obj/effect/mob_spawn/corpse/human/skeleton, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "um" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 10 }, /obj/item/stack/rods, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "us" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 @@ -604,22 +604,22 @@ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "uB" = ( /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "uO" = ( /obj/effect/mob_spawn/corpse/human/skeleton, /turf/open/floor/engine/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ve" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 6 }, /obj/effect/mob_spawn/corpse/human/skeleton, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vm" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 1 @@ -629,30 +629,30 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vx" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vA" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vH" = ( /obj/structure/lattice, /obj/item/stack/sheet/mineral/titanium, /turf/template_noop, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "vK" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "wo" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -662,23 +662,23 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "wr" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xs" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 10 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xJ" = ( /obj/effect/turf_decal/trimline/red/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "xL" = ( /turf/closed/wall/mineral/titanium, /area/ruin/unpowered) @@ -697,28 +697,28 @@ icon_state = "medium" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yo" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 5 }, /obj/item/stack/rods, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yB" = ( /obj/effect/turf_decal/trimline/brown/filled/line, /obj/item/ammo_casing/c9mm, /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yO" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "yU" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/brown{ @@ -733,36 +733,36 @@ /obj/item/ammo_casing/c9mm, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zd" = ( /obj/structure/grille/broken, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zn" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 10 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zJ" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 5 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "zY" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "AK" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "AM" = ( /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 1 @@ -772,21 +772,21 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "AN" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "AR" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 9 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Bj" = ( /obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ @@ -799,12 +799,12 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "BO" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Cl" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 4 @@ -814,13 +814,13 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Cp" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 10 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Cu" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -834,21 +834,21 @@ }, /obj/structure/girder, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "CT" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "DN" = ( /obj/item/stack/rods, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Er" = ( /obj/effect/gibspawner/human, /obj/effect/mob_spawn/corpse/human/doctor, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ED" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 9 @@ -856,28 +856,28 @@ /obj/item/ammo_casing/c9mm, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "EP" = ( /obj/structure/girder, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "FD" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "FU" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 5 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Gc" = ( /obj/item/shard, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Gi" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -887,25 +887,25 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Gn" = ( /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Gr" = ( /obj/effect/gibspawner/human, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "GH" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/structure/grille/broken, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "GJ" = ( /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "GO" = ( /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ @@ -919,7 +919,7 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "GV" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 10 @@ -927,7 +927,7 @@ /obj/item/stack/sheet/mineral/titanium, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Hh" = ( /obj/effect/turf_decal/tile/green{ dir = 1 @@ -940,28 +940,28 @@ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Hi" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ho" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 9 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Hv" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "HL" = ( /obj/item/shard, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "HX" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -970,47 +970,47 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ic" = ( /obj/effect/turf_decal/trimline/brown/filled/line, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Io" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 6 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "IC" = ( /obj/effect/turf_decal/bot_red, /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "IO" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "IT" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 6 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "IU" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Jc" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Jl" = ( /obj/effect/turf_decal/trimline/white/filled/corner{ dir = 1 @@ -1025,7 +1025,7 @@ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Jp" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 4 @@ -1035,21 +1035,21 @@ }, /obj/effect/turf_decal/trimline/brown/filled/corner, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Jx" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Jz" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 4 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JH" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -1057,7 +1057,7 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JK" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 6 @@ -1065,14 +1065,14 @@ /obj/item/stack/rods, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JR" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 9 }, /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JT" = ( /obj/effect/turf_decal/tile/green{ dir = 1 @@ -1087,13 +1087,13 @@ /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "JY" = ( /obj/effect/decal/cleanable/blood, /obj/effect/mob_spawn/corpse/human/skeleton, /obj/item/shard, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Kn" = ( /obj/effect/turf_decal/trimline/brown/filled/corner, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -1101,14 +1101,14 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Kr" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 6 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Kx" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -1117,13 +1117,13 @@ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "KH" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "KN" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 6 @@ -1131,28 +1131,28 @@ /obj/item/shard, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "KU" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 8 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Lm" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 10 }, /obj/item/stack/rods, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Lx" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 9 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "LK" = ( /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ @@ -1165,7 +1165,7 @@ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Mh" = ( /obj/effect/turf_decal/trimline/brown/filled/line, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -1173,7 +1173,7 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Mu" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -1186,11 +1186,11 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "MK" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ne" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -1199,7 +1199,7 @@ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "NU" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 10 @@ -1207,7 +1207,7 @@ /obj/item/ammo_casing/c9mm, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "NX" = ( /obj/effect/turf_decal/tile/red{ dir = 1 @@ -1220,20 +1220,20 @@ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "NY" = ( /obj/effect/turf_decal/trimline/green/filled/line, /obj/item/shard{ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "OE" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "OK" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 8 @@ -1242,24 +1242,24 @@ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "OY" = ( /obj/effect/turf_decal/trimline/green/filled/line, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Pg" = ( /obj/structure/girder, /obj/item/stack/sheet/mineral/titanium, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Pn" = ( /obj/effect/turf_decal/trimline/green/filled/corner, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Pq" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/turf_decal/trimline/purple/filled/line{ @@ -1267,37 +1267,37 @@ }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Px" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "PH" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 }, /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Qd" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 1 }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Qs" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QH" = ( /obj/structure/grille, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QN" = ( /obj/effect/turf_decal/tile/green{ dir = 8 @@ -1310,48 +1310,48 @@ }, /obj/effect/turf_decal/tile/green, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "QU" = ( /obj/structure/grille/broken, /obj/item/ammo_casing/c9mm, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Rj" = ( /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/engine/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Rq" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 10 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Rw" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "RL" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "RN" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "RV" = ( /obj/effect/turf_decal/trimline/white/filled/corner{ dir = 4 }, /obj/effect/turf_decal/trimline/brown/filled/line, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "RZ" = ( /obj/effect/turf_decal/tile/purple{ dir = 4 @@ -1365,7 +1365,7 @@ /obj/effect/turf_decal/tile/purple, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Su" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 5 @@ -1374,7 +1374,7 @@ /obj/effect/mob_spawn/corpse/human/syndicatesoldier, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "SF" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner{ dir = 8 @@ -1387,25 +1387,25 @@ }, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "SS" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 5 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Tk" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Tu" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 9 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "TF" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/effect/turf_decal/trimline/yellow/filled/corner{ @@ -1415,24 +1415,24 @@ icon_state = "small" }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "TH" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "TW" = ( /obj/effect/decal/cleanable/blood, /obj/effect/mob_spawn/corpse/human/doctor, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Ua" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 10 }, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Uo" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -1442,7 +1442,7 @@ }, /obj/effect/decal/cleanable/blood, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "UD" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 10 @@ -1450,12 +1450,12 @@ /obj/effect/gibspawner/human, /obj/effect/mob_spawn/corpse/human/doctor, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Vz" = ( /obj/effect/turf_decal/trimline/green/filled/line, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Wy" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/effect/turf_decal/trimline/red/filled/corner{ @@ -1469,26 +1469,29 @@ }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) +"WF" = ( +/turf/closed/wall/mineral/titanium, +/area/ruin/space/unpowered) "WK" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "WY" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 4 }, /obj/item/ammo_casing/c9mm, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Xp" = ( /obj/effect/turf_decal/trimline/brown/filled/corner, /obj/item/ammo_casing/c9mm, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Xw" = ( /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -1501,13 +1504,13 @@ dir = 8 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Xy" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 5 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "XL" = ( /turf/template_noop, /area/template_noop) @@ -1519,7 +1522,7 @@ dir = 4 }, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "YD" = ( /obj/effect/turf_decal/tile/brown{ dir = 8 @@ -1535,7 +1538,7 @@ /obj/structure/frame/machine, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "YV" = ( /obj/effect/turf_decal/tile/green{ dir = 4 @@ -1550,11 +1553,11 @@ /obj/structure/mecha_wreckage/ripley, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "Zt" = ( /obj/effect/turf_decal/bot_red, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ZT" = ( /obj/effect/turf_decal/trimline/white/filled/line{ dir = 1 @@ -1562,14 +1565,14 @@ /obj/item/ammo_casing/c9mm, /obj/structure/frame/machine, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) "ZW" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 5 }, /obj/item/shard, /turf/open/floor/iron/dark/airless, -/area/ruin/unpowered) +/area/ruin/space/unpowered) (1,1,1) = {" XL @@ -1585,7 +1588,7 @@ XL XL XL XL -xL +WF ao ao do @@ -1603,18 +1606,18 @@ ic nv EP ic -xL -xL +WF +WF XL XL XL -xL -xL +WF +WF ic ic Pg ic -xL +WF XL XL XL @@ -1628,11 +1631,11 @@ GJ kk tE Ua -xL -xL +WF +WF QH QH -xL +WF Ho tn OE @@ -1646,13 +1649,13 @@ XL (4,1,1) = {" XL XL -xL +WF Zt JY WK eo dX -xL +WF JR OE um @@ -1670,13 +1673,13 @@ XL (5,1,1) = {" XL XL -xL +WF IC jx vH IO iU -xL +WF na id CT @@ -1694,7 +1697,7 @@ XL (6,1,1) = {" XL XL -xL +WF kk tE bj @@ -1718,7 +1721,7 @@ XL (7,1,1) = {" XL XL -xL +WF SS lE Zt @@ -1743,12 +1746,12 @@ XL XL XL xL -xL +WF dL IO tX cb -xL +WF lE lE RN @@ -1770,9 +1773,9 @@ XL EP WK xJ -xL -xL -xL +WF +WF +WF lE lE do @@ -1828,8 +1831,8 @@ pZ YV JT lE -xL -xL +WF +WF XL XL XL @@ -1890,18 +1893,18 @@ XL jG ub ub -xL +WF fG QH Hi Gr TH -xL +WF hy WY WY IT -xL +WF XL XL XL @@ -1911,10 +1914,10 @@ XL XL XL uB -xL -xL -xL -xL +WF +WF +WF +WF nP lE vA @@ -1925,8 +1928,8 @@ iC do Hh lE -xL -xL +WF +WF XL XL XL @@ -1940,8 +1943,8 @@ Rq tv lE bV -xL -xL +WF +WF Mu do QH @@ -1962,7 +1965,7 @@ EP FU pl uO -xL +WF bV QH Lx @@ -1985,8 +1988,8 @@ XL QH do Bj -xL -xL +WF +WF JH QH Jx @@ -2010,7 +2013,7 @@ QH AR tW ok -xL +WF PH qM Hi @@ -2049,7 +2052,7 @@ lE do XL lE -xL +WF "} (21,1,1) = {" XL @@ -2064,7 +2067,7 @@ QH ui vx ve -xL +WF iC Rw Qd @@ -2073,7 +2076,7 @@ Vz do XL lE -xL +WF "} (22,1,1) = {" XL @@ -2082,12 +2085,12 @@ EP yo Jc lE -xL +WF bV QH do lE -xL +WF QH lE GO @@ -2096,8 +2099,8 @@ Pn Kr EP XL -xL -xL +WF +WF "} (23,1,1) = {" XL @@ -2106,7 +2109,7 @@ do uB FU pl -xL +WF OK qv HX @@ -2120,18 +2123,18 @@ sn DN EP XL -xL +WF XL "} (24,1,1) = {" XL XL XL -xL -xL -xL -xL -xL +WF +WF +WF +WF +WF Ic tv tv @@ -2151,7 +2154,7 @@ XL XL XL XL -xL +WF ED dB zn @@ -2175,7 +2178,7 @@ XL XL XL XL -xL +WF ZT hi mP @@ -2213,7 +2216,7 @@ YD lE Xp KN -xL +WF XL XL XL @@ -2236,7 +2239,7 @@ EP EP gI yB -xL +WF QH XL XL @@ -2257,7 +2260,7 @@ AN AN wr Cp -xL +WF Su JK Pg @@ -2284,7 +2287,7 @@ nF EP Rw Gc -xL +WF XL XL XL @@ -2292,7 +2295,7 @@ XL XL "} (31,1,1) = {" -xL +WF lE XL XL @@ -2316,8 +2319,8 @@ XL XL "} (32,1,1) = {" -xL -xL +WF +WF XL lE XL @@ -2341,9 +2344,9 @@ XL "} (33,1,1) = {" XL -xL -xL -xL +WF +WF +WF XL XL XL diff --git a/_maps/RandomRuins/SpaceRuins/nova/wreckedhomestead.dmm b/_maps/RandomRuins/SpaceRuins/nova/wreckedhomestead.dmm index 680ee3a654e7..434eff20bba2 100644 --- a/_maps/RandomRuins/SpaceRuins/nova/wreckedhomestead.dmm +++ b/_maps/RandomRuins/SpaceRuins/nova/wreckedhomestead.dmm @@ -76,7 +76,7 @@ /area/ruin/unpowered) "mP" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/reagent_containers/cup/beaker/cryoxadone, /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden{ dir = 5 diff --git a/_maps/RandomRuins/SpaceRuins/old_infiltrator.dmm b/_maps/RandomRuins/SpaceRuins/old_infiltrator.dmm index 4b42f668c337..85c2910d1fab 100644 --- a/_maps/RandomRuins/SpaceRuins/old_infiltrator.dmm +++ b/_maps/RandomRuins/SpaceRuins/old_infiltrator.dmm @@ -210,8 +210,8 @@ "nF" = ( /obj/item/radio/intercom/directional/south, /obj/effect/decal/cleanable/blood/old, -/obj/item/ammo_casing/a357/match, -/obj/item/ammo_casing/a357/match{ +/obj/item/ammo_casing/c357/match, +/obj/item/ammo_casing/c357/match{ pixel_y = -4; pixel_x = -7 }, @@ -306,7 +306,7 @@ /area/ruin/space/unpowered) "uS" = ( /obj/machinery/newscaster/directional/south, -/obj/item/ammo_casing/a357/match, +/obj/item/ammo_casing/c357/match, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/unpowered) "vi" = ( @@ -425,7 +425,7 @@ /turf/open/floor/mineral/plastitanium/red/airless, /area/ruin/space/unpowered) "Cv" = ( -/obj/item/ammo_casing/a357/match, +/obj/item/ammo_casing/c357/match, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/unpowered) "CC" = ( diff --git a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm index 6acec2ccc439..7b0f8a6e8fbc 100644 --- a/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm +++ b/_maps/RandomRuins/SpaceRuins/prison_shuttle.dmm @@ -147,8 +147,8 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space/prison_shuttle) "O" = ( -/mob/living/basic/cockroach, /obj/effect/turf_decal/tile/brown/fourcorners, +/obj/effect/decal/cleanable/xenoblood/xsplatter, /turf/open/floor/iron/dark/airless, /area/ruin/space/prison_shuttle) "P" = ( diff --git a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm index 5377a113df53..592b42538509 100644 --- a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm @@ -4146,14 +4146,14 @@ "Eb" = ( /obj/structure/cable, /obj/effect/mapping_helpers/burnt_floor, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = -6; pixel_y = 3 }, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = -5 }, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 6; dir = 9; pixel_y = -3 @@ -5018,8 +5018,8 @@ /turf/open/floor/plating/airless, /area/space/nearstation) "IG" = ( -/obj/item/ammo_casing/a357, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357, +/obj/item/ammo_casing/c357{ pixel_x = 5; pixel_y = 6 }, @@ -5893,8 +5893,8 @@ /turf/open/floor/plating, /area/ruin/space/ks13/science/ordnance) "Nk" = ( -/obj/effect/spawner/random/maintenance, /obj/structure/lattice, +/obj/effect/spawner/random/maintenance/no_decals, /turf/template_noop, /area/space/nearstation) "Nl" = ( @@ -6330,11 +6330,11 @@ /turf/open/floor/iron/airless, /area/ruin/space/ks13/hallway/aft) "Pv" = ( -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 4; pixel_y = -7 }, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = -5 }, /obj/structure/cable, @@ -6847,12 +6847,12 @@ "Sk" = ( /obj/structure/cable, /obj/effect/mapping_helpers/burnt_floor, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 6; pixel_y = -4 }, -/obj/item/ammo_casing/a357, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357, +/obj/item/ammo_casing/c357{ pixel_x = -10; pixel_y = 7; dir = 9 @@ -7599,12 +7599,12 @@ /area/ruin/space/ks13/service/hydro) "VH" = ( /obj/effect/mapping_helpers/burnt_floor, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 8; dir = 8; pixel_y = 6 }, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 6; pixel_y = -4 }, diff --git a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm index 71074aa4451f..3534df8db024 100644 --- a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm +++ b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm @@ -63,7 +63,7 @@ /obj/structure/chair/old{ dir = 1 }, -/obj/item/crowbar/large/heavy, +/obj/item/crowbar/large/twenty_force, /turf/open/floor/oldshuttle, /area/ruin/space/has_grav/powered) "o" = ( diff --git a/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm b/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm index b31a11cba31c..a358d59956e8 100644 --- a/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm +++ b/_maps/RandomRuins/SpaceRuins/the_faceoff.dmm @@ -1,15 +1,15 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aj" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 12 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 6 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 @@ -45,40 +45,40 @@ /turf/template_noop, /area/template_noop) "bM" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = -1; pixel_y = 5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 6 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = -5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 2 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = -5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 12 @@ -168,7 +168,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "eI" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = -1; pixel_y = 5 @@ -213,17 +213,17 @@ /turf/open/misc/asteroid/basalt/airless, /area/ruin/space) "gq" = ( -/obj/item/ammo_casing/a357/spent, +/obj/item/ammo_casing/c357/spent, /obj/structure/barricade/wooden, /turf/open/floor/iron/dark/airless, /area/ruin/space) "gx" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 6 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 2 }, @@ -280,41 +280,41 @@ /turf/open/floor/iron/dark/textured/airless, /area/ruin/space) "je" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 12 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -2; pixel_y = -5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 2 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 1 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 6; dir = 1 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = -6 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_y = 13; pixel_x = -5 @@ -322,7 +322,7 @@ /turf/open/floor/mineral/plastitanium/red/airless, /area/ruin/space) "jX" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9; pixel_y = 9 @@ -354,7 +354,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "mC" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 @@ -392,7 +392,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "pl" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = -5 @@ -434,11 +434,11 @@ /area/ruin/space) "qX" = ( /obj/effect/mapping_helpers/broken_floor, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9; pixel_y = 9 @@ -455,7 +455,7 @@ /area/ruin/space) "rU" = ( /obj/effect/mapping_helpers/broken_floor, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9 }, @@ -482,7 +482,7 @@ /area/ruin/space) "su" = ( /obj/effect/mapping_helpers/broken_floor, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 12 @@ -541,7 +541,7 @@ /turf/open/misc/asteroid/basalt/airless, /area/ruin/space) "vA" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = -1; pixel_y = 5 @@ -549,7 +549,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "vZ" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -2; pixel_y = -5 @@ -588,7 +588,7 @@ /turf/open/floor/mineral/plastitanium/airless, /area/ruin/space) "xi" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 @@ -726,7 +726,7 @@ /area/ruin/space) "Dm" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 12 }, @@ -786,7 +786,7 @@ /turf/open/misc/asteroid/basalt/airless, /area/ruin/space) "FQ" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 2 }, @@ -804,7 +804,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "GA" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 @@ -822,7 +822,7 @@ /area/ruin/space) "HE" = ( /obj/structure/table/reinforced/plastitaniumglass, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, @@ -881,7 +881,7 @@ /turf/open/floor/mineral/plastitanium/airless, /area/ruin/space) "JP" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, @@ -897,11 +897,11 @@ /turf/open/floor/mineral/plastitanium/red/airless, /area/ruin/space) "Kd" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9; pixel_y = 9 @@ -909,7 +909,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "Kp" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 @@ -940,14 +940,14 @@ /turf/open/floor/iron/dark/textured/airless, /area/ruin/space) "LM" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, /turf/open/floor/iron/dark/airless, /area/ruin/space) "LX" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 12 @@ -973,7 +973,7 @@ /turf/open/floor/mineral/plastitanium/red/airless, /area/ruin/space) "Nc" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 @@ -1047,7 +1047,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "TH" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9 }, @@ -1065,7 +1065,7 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "Uy" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 6 @@ -1102,36 +1102,36 @@ /turf/open/floor/mineral/plastitanium/airless, /area/ruin/space) "Vn" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 4; pixel_x = 14; pixel_y = 14 }, -/obj/item/ammo_casing/a357/spent, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent, +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 6 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = 9; pixel_y = 9 @@ -1152,7 +1152,7 @@ /turf/open/floor/mineral/plastitanium/airless, /area/ruin/space) "VB" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 2 }, @@ -1209,40 +1209,40 @@ /turf/open/floor/iron/dark/airless, /area/ruin/space) "Zg" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 10; pixel_y = 5 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = 7 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -4; pixel_y = -7 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 2; pixel_y = 12 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 1; pixel_x = -1; pixel_y = 8 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -2; pixel_y = -4 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = -7; pixel_y = 8 }, -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ pixel_x = 5; pixel_y = -4 }, @@ -1259,7 +1259,7 @@ /turf/open/floor/mineral/plastitanium/airless, /area/ruin/space) "ZP" = ( -/obj/item/ammo_casing/a357/spent{ +/obj/item/ammo_casing/c357/spent{ dir = 8; pixel_x = 2; pixel_y = 1 diff --git a/_maps/RandomRuins/SpaceRuins/the_outlet.dmm b/_maps/RandomRuins/SpaceRuins/the_outlet.dmm index 719088322f21..922715ca8d7f 100644 --- a/_maps/RandomRuins/SpaceRuins/the_outlet.dmm +++ b/_maps/RandomRuins/SpaceRuins/the_outlet.dmm @@ -701,7 +701,7 @@ /area/ruin/space/has_grav/the_outlet/employeesection) "rF" = ( /obj/structure/table/reinforced/rglass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/reagent_containers/syringe/lethal/execution, /turf/open/floor/iron/freezer, /area/ruin/space/has_grav/the_outlet/researchrooms) diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index a8f52784b343..c830fdc968fa 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -4131,7 +4131,7 @@ /area/awaymission/moonoutpost19/arrivals/shed) "Bf" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = -2; pixel_y = -7 }, @@ -6467,7 +6467,7 @@ "QZ" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = 11; pixel_y = 8 }, @@ -7514,7 +7514,7 @@ /obj/item/stack/ore/glass{ pixel_x = 8 }, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357{ pixel_x = -10; pixel_y = -7 }, diff --git a/_maps/RandomZLevels/mothership_astrum.dmm b/_maps/RandomZLevels/mothership_astrum.dmm index dd275f086bf8..03a2a9d0111a 100644 --- a/_maps/RandomZLevels/mothership_astrum.dmm +++ b/_maps/RandomZLevels/mothership_astrum.dmm @@ -41,7 +41,7 @@ /area/awaymission/mothership_astrum/halls) "aw" = ( /obj/effect/decal/cleanable/blood/splatter, -/obj/item/ammo_casing/a357, +/obj/item/ammo_casing/c357, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "aD" = ( @@ -1818,7 +1818,7 @@ /turf/open/floor/wood, /area/awaymission/mothership_astrum/deck5) "Dk" = ( -/obj/item/ammo_casing/a357, +/obj/item/ammo_casing/c357, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "Dq" = ( @@ -1998,7 +1998,7 @@ /area/awaymission/mothership_astrum/halls) "Fy" = ( /obj/effect/decal/cleanable/blood/gibs/body, -/obj/item/ammo_casing/a357, +/obj/item/ammo_casing/c357, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "FD" = ( @@ -2266,7 +2266,7 @@ /area/awaymission/mothership_astrum/deck4) "Ie" = ( /obj/effect/decal/cleanable/blood/gibs/up, -/obj/item/ammo_casing/a357, +/obj/item/ammo_casing/c357, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "Iq" = ( diff --git a/_maps/deathmatch/arena_station.dmm b/_maps/deathmatch/arena_station.dmm index 50089df45e8a..8009387c5025 100644 --- a/_maps/deathmatch/arena_station.dmm +++ b/_maps/deathmatch/arena_station.dmm @@ -79,7 +79,7 @@ /obj/structure/closet/crate/cardboard, /obj/effect/turf_decal/tile/brown/fourcorners, /obj/item/mail/junkmail, -/obj/item/ammo_casing/a357, +/obj/item/ammo_casing/c357, /obj/item/reagent_containers/syringe/plasma, /turf/open/indestructible, /area/deathmatch) diff --git a/_maps/deathmatch/species_warfare.dmm b/_maps/deathmatch/species_warfare.dmm index e80485c2b5e5..66e7e9b2275a 100644 --- a/_maps/deathmatch/species_warfare.dmm +++ b/_maps/deathmatch/species_warfare.dmm @@ -23,7 +23,7 @@ dir = 1 }, /obj/structure/table/glass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/indestructible/white, /area/deathmatch) "bX" = ( @@ -228,7 +228,7 @@ "iM" = ( /obj/effect/turf_decal/tile/blue/half/contrasted, /obj/structure/table/glass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/indestructible/white, /area/deathmatch) "iV" = ( diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index f18d092fd15a..f8c5523c2cc1 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -130,7 +130,7 @@ /obj/effect/turf_decal/siding/white, /obj/machinery/light/small/directional/south, /obj/structure/table/reinforced, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /turf/open/floor/iron/small, /area/station/medical/morgue) "adL" = ( @@ -9394,10 +9394,9 @@ /obj/machinery/airalarm/directional/north, /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, -/obj/effect/turf_decal/siding/wood{ - dir = 5 +/obj/effect/turf_decal/siding/wood/end{ + dir = 4 }, -/obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "dxZ" = ( @@ -10072,6 +10071,7 @@ }, /obj/structure/disposalpipe/segment, /obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/stone, /area/station/service/bar) "dMm" = ( @@ -10716,7 +10716,7 @@ /obj/machinery/camera/autoname/directional/north, /obj/structure/sign/poster/official/random/directional/north, /obj/machinery/status_display/ai/directional/west, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) "dZk" = ( @@ -10872,7 +10872,10 @@ /obj/effect/turf_decal/tile/yellow{ dir = 1 }, -/obj/machinery/door/window/right/directional/east, +/obj/machinery/door/window/right/directional/east{ + name = "Engineering Deliveries"; + req_access = list("engineering") + }, /turf/open/floor/iron/smooth, /area/station/engineering/main) "ecn" = ( @@ -20927,6 +20930,7 @@ }, /obj/machinery/vending/boozeomat, /obj/effect/turf_decal/siding/wood, +/obj/structure/sign/warning/no_smoking/circle/directional/north, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "hsC" = ( @@ -30564,11 +30568,6 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, -/obj/machinery/barsign{ - chosen_sign = "thecavern"; - icon_state = "thecavern"; - pixel_y = 32 - }, /obj/machinery/reagentgrinder{ pixel_x = -5; pixel_y = 10 @@ -33244,11 +33243,14 @@ pixel_x = -7; pixel_y = 15 }, -/obj/effect/turf_decal/siding/wood{ - dir = 9 +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, +/obj/machinery/barsign{ + chosen_sign = "thecavern"; + icon_state = "thecavern"; + pixel_y = 32 }, -/obj/effect/turf_decal/siding/wood, -/obj/structure/sign/warning/no_smoking/circle/directional/north, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "lnI" = ( @@ -33933,7 +33935,7 @@ /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/airalarm/directional/north, /obj/structure/rack, -/obj/item/crowbar/large/heavy, +/obj/item/crowbar/large, /obj/item/wirecutters, /obj/item/wrench, /turf/open/floor/iron, @@ -34878,7 +34880,7 @@ /area/station/tcommsat/server) "lPO" = ( /obj/structure/table, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = -5 }, /obj/item/wirecutters{ @@ -43772,7 +43774,7 @@ /area/station/science/ordnance/burnchamber) "oZL" = ( /obj/structure/table, -/obj/item/crowbar/large/heavy, +/obj/item/crowbar/large, /obj/item/stack/cable_coil, /obj/machinery/light/small/directional/south, /turf/open/floor/iron, @@ -47524,7 +47526,7 @@ /obj/machinery/door/airlock/maintenance{ name = "Atmospherics Maintenance" }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) "qmz" = ( @@ -50830,12 +50832,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/service/lawoffice) -"rrX" = ( -/obj/effect/turf_decal/siding/wood/corner{ - dir = 4 - }, -/turf/open/floor/stone, -/area/station/service/bar) "rrZ" = ( /obj/structure/closet/crate/trashcart, /obj/effect/spawner/random/trash/garbage, @@ -56442,11 +56438,14 @@ /turf/open/floor/eighties/red, /area/station/hallway/primary/central/fore) "tjT" = ( -/obj/structure/extinguisher_cabinet/directional/north, +/obj/machinery/chem_master/condimaster, +/obj/effect/turf_decal/siding/wood/end{ + dir = 8 + }, /obj/effect/turf_decal/siding/wood{ - dir = 5 + dir = 4 }, -/turf/open/floor/stone, +/turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "tjY" = ( /obj/machinery/atmospherics/components/binary/pump/on{ @@ -57400,6 +57399,9 @@ /obj/item/gun/energy/ionrifle{ pixel_y = 3 }, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 5 + }, /obj/item/clothing/suit/hooded/ablative, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) @@ -58689,7 +58691,7 @@ }, /obj/machinery/chem_dispenser/drinks/beer, /obj/effect/turf_decal/siding/wood, -/obj/machinery/digital_clock/directional/north, +/obj/structure/fish_mount/bar/directional/north, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "tVt" = ( @@ -100080,7 +100082,7 @@ iXW dRb sON tjT -rrX +xkV lAV fYJ eGU diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 9b3be36c63c5..d79d3b54896d 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -3246,6 +3246,32 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron/dark, /area/station/ai_monitored/command/storage/eva) +"aNM" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/duct, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron, +/area/station/maintenance/department/chapel) +"aNN" = ( +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/item/clothing/suit/hooded/ablative, +/obj/item/gun/energy/temperature/security, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/security/armory) "aNP" = ( /obj/structure/sign/warning/hot_temp/directional/west, /turf/open/floor/plating, @@ -7873,23 +7899,6 @@ /obj/structure/sign/poster/official/anniversary_vintage_reprint/directional/south, /turf/open/floor/iron/white, /area/station/science/research) -"bSp" = ( -/obj/effect/landmark/start/hangover, -/obj/structure/table/wood, -/obj/effect/spawner/random/entertainment/cigarette, -/obj/item/lighter, -/obj/machinery/status_display/ai/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/north{ - c_tag = "Service - Bar Fore"; - name = "service camera" - }, -/obj/effect/turf_decal/tile/red/opposingcorners{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow/opposingcorners, -/turf/open/floor/iron, -/area/station/commons/lounge) "bSq" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -17863,6 +17872,16 @@ /obj/structure/cable, /turf/open/floor/iron/solarpanel/airless, /area/station/solars/port/aft) +"etv" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/effect/turf_decal/box/red, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/open/floor/engine/xenobio, +/area/station/science/xenobiology) "etw" = ( /obj/structure/lattice, /obj/structure/sign/nanotrasen{ @@ -40188,10 +40207,6 @@ }, /turf/open/floor/iron/white, /area/station/science/robotics/lab) -"jVP" = ( -/obj/machinery/status_display/ai/directional/south, -/turf/open/floor/iron/dark, -/area/station/hallway/secondary/service) "jVS" = ( /obj/structure/tank_dispenser, /obj/effect/decal/cleanable/dirt, @@ -46823,6 +46838,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/medical/storage) +"lFL" = ( +/obj/structure/table/glass, +/obj/effect/spawner/surgery_tray/full, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/item/clothing/gloves/latex, +/obj/item/clothing/suit/apron/surgical, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/surgery/theatre) "lFP" = ( /obj/structure/chair, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -49355,6 +49379,23 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/iron/dark, /area/station/ai_monitored/command/storage/eva) +"mph" = ( +/obj/effect/landmark/start/hangover, +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/cigarette, +/obj/item/lighter, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera/directional/north{ + c_tag = "Service - Bar Fore"; + name = "service camera" + }, +/obj/effect/turf_decal/tile/red/opposingcorners{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/structure/fish_mount/bar/directional/north, +/turf/open/floor/iron, +/area/station/commons/lounge) "mpk" = ( /obj/effect/turf_decal/trimline/blue/filled/warning{ dir = 1 @@ -53094,16 +53135,6 @@ }, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat_interior) -"nmT" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/clothing/suit/hooded/ablative, -/obj/item/gun/energy/temperature/security, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) "nmU" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -62192,17 +62223,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) -"pET" = ( -/obj/effect/landmark/start/hangover, -/obj/structure/chair/sofa/right/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red/opposingcorners{ - dir = 1 - }, -/obj/effect/turf_decal/tile/yellow/opposingcorners, -/turf/open/floor/iron, -/area/station/commons/lounge) "pEU" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/bot, @@ -62601,6 +62621,17 @@ /obj/effect/decal/remains/xeno, /turf/open/floor/engine/xenobio, /area/station/science/xenobiology) +"pJI" = ( +/obj/effect/turf_decal/trimline/neutral/mid_joiner{ + dir = 4 + }, +/obj/structure/table/reinforced, +/obj/effect/spawner/surgery_tray/full/morgue, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/medical/morgue) "pJM" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -75211,15 +75242,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/abandoned_gambling_den/gaming) -"sOp" = ( -/obj/structure/table/glass, -/obj/item/surgery_tray/full, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/item/clothing/gloves/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/surgery/theatre) "sOs" = ( /obj/structure/chair/pew/left, /turf/open/floor/iron/chapel{ @@ -79108,17 +79130,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"tNU" = ( -/obj/effect/turf_decal/trimline/neutral/mid_joiner{ - dir = 4 - }, -/obj/structure/table/reinforced, -/obj/item/surgery_tray/full/morgue, -/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/medical/morgue) "tNV" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -82527,6 +82538,18 @@ /obj/effect/spawner/random/engineering/toolbox, /turf/open/floor/plating, /area/station/maintenance/department/electrical) +"uEz" = ( +/obj/effect/landmark/start/hangover, +/obj/structure/chair/sofa/right/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red/opposingcorners{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/machinery/status_display/ai/directional/north, +/turf/open/floor/iron, +/area/station/commons/lounge) "uED" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, @@ -84091,16 +84114,6 @@ /obj/effect/mapping_helpers/airalarm/tlv_no_checks, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"uXU" = ( -/obj/structure/disposalpipe/trunk{ - dir = 4 - }, -/obj/machinery/disposal/delivery_chute{ - dir = 8 - }, -/obj/effect/turf_decal/box/red, -/turf/open/floor/engine/xenobio, -/area/station/science/xenobiology) "uYg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/green, @@ -85081,6 +85094,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/fore) +"vkV" = ( +/obj/structure/table/glass, +/obj/effect/spawner/surgery_tray/full, +/obj/item/clothing/gloves/latex, +/obj/item/clothing/suit/apron/surgical, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/surgery/theatre) "vkX" = ( /obj/effect/turf_decal/bot, /obj/machinery/vending/cigarette, @@ -94594,14 +94615,6 @@ /obj/structure/plasticflaps, /turf/open/floor/plating, /area/station/cargo/storage) -"xES" = ( -/obj/structure/table/glass, -/obj/item/surgery_tray/full, -/obj/item/clothing/gloves/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/surgery/theatre) "xEV" = ( /obj/item/target, /obj/effect/decal/cleanable/dirt, @@ -116387,7 +116400,7 @@ rIb rIb xdn gCt -uXU +etv uhb uhb nCi @@ -133016,7 +133029,7 @@ vRB gch xMe kVP -bSp +mph jcv aWP qrP @@ -133271,9 +133284,9 @@ pPI kVP xiu uMT -jVP +giz kVP -pET +uEz vwr aWP rpZ @@ -137483,10 +137496,10 @@ pdl fOJ kuU tOS -xES +vkV jqJ jqJ -sOp +lFL qYL jNY llm @@ -138003,7 +138016,7 @@ uue jdf qYL qpU -tNU +pJI aNV hvf vid @@ -151047,7 +151060,7 @@ aEs iaT pUY tVw -nmT +aNN dwU wtB qBw diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 8c89f6f52314..3f81aa274788 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -798,12 +798,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/virology) -"anO" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "anP" = ( /obj/structure/table, /obj/machinery/light_switch/directional/north, @@ -3322,12 +3316,6 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/white, /area/station/medical/virology) -"aWb" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "aWc" = ( /obj/structure/railing{ dir = 8 @@ -3499,6 +3487,12 @@ }, /turf/open/floor/iron, /area/station/commons/storage/mining) +"aYt" = ( +/obj/item/target, +/obj/structure/window/reinforced/spawner/directional/north, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "aYu" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/structure/disposalpipe/segment{ @@ -3998,12 +3992,6 @@ /obj/structure/sign/painting/large, /turf/open/floor/wood, /area/station/security/prison/rec) -"beZ" = ( -/turf/closed/indestructible/riveted{ - desc = "A wall impregnated with Fixium, able to withstand massive explosions with ease"; - name = "hyper-reinforced wall" - }, -/area/station/science/ordnance/bomb) "bff" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, @@ -4823,12 +4811,6 @@ }, /turf/open/floor/plating, /area/station/service/hydroponics) -"bqr" = ( -/obj/item/target, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "bqt" = ( /obj/machinery/airalarm/directional/west, /turf/open/floor/circuit, @@ -5500,10 +5482,6 @@ }, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) -"byB" = ( -/obj/effect/spawner/random/engineering/tracking_beacon, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "byH" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /turf/open/floor/iron/dark, @@ -9890,12 +9868,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/pharmacy) -"cJB" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "cJC" = ( /obj/structure/closet, /obj/effect/spawner/random/maintenance/four, @@ -13862,6 +13834,12 @@ dir = 1 }, /area/station/command/gateway) +"dRU" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "dRX" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -15813,9 +15791,6 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/vault, /area/station/security/prison/rec) -"evT" = ( -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "ewi" = ( /obj/machinery/navbeacon{ codes_txt = "delivery;dir=8"; @@ -18946,23 +18921,6 @@ /obj/item/flashlight/lantern/on, /turf/open/misc/hay/icemoon, /area/icemoon/underground/explored) -"fsz" = ( -/obj/structure/table/glass, -/obj/machinery/vending/wallmed/directional/north, -/obj/item/book/manual/wiki/surgery{ - pixel_x = -4; - pixel_y = 3 - }, -/obj/item/surgery_tray/full, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/obj/machinery/camera/directional/north{ - c_tag = "Surgery A"; - network = list("ss13","medbay") - }, -/turf/open/floor/iron/white, -/area/station/medical/surgery/fore) "fsF" = ( /obj/effect/spawner/structure/window, /obj/effect/mapping_helpers/broken_floor, @@ -20518,6 +20476,13 @@ /obj/structure/sign/clock/directional/north, /turf/open/floor/iron, /area/station/commons/fitness) +"fRr" = ( +/obj/item/target/alien/anchored, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "fRv" = ( /obj/machinery/light/small/directional/north, /turf/open/floor/engine, @@ -25908,15 +25873,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"hvt" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/item/surgery_tray/full/morgue, -/obj/structure/table/reinforced, -/obj/machinery/requests_console/auto_name/directional/north, -/obj/effect/turf_decal/bot_white, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/dark, -/area/station/medical/morgue) "hvQ" = ( /obj/effect/spawner/random/trash/mess, /turf/open/floor/stone, @@ -26455,10 +26411,6 @@ /obj/machinery/shower/directional/north, /turf/open/floor/iron/smooth, /area/mine/eva/lower) -"hDA" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "hDG" = ( /obj/docking_port/stationary/random/icemoon{ dir = 4; @@ -26627,6 +26579,10 @@ }, /turf/open/openspace, /area/station/engineering/atmos/storage) +"hGu" = ( +/obj/effect/spawner/random/engineering/tracking_beacon, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "hGH" = ( /turf/closed/wall, /area/station/security/lockers) @@ -28517,6 +28473,13 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured, /area/station/security/execution/transfer) +"ihM" = ( +/obj/structure/chair, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "iih" = ( /obj/effect/spawner/xmastree, /obj/effect/turf_decal/tile/neutral{ @@ -28865,6 +28828,23 @@ dir = 1 }, /area/station/commons/storage/art) +"imT" = ( +/obj/structure/table/glass, +/obj/machinery/vending/wallmed/directional/north, +/obj/item/book/manual/wiki/surgery{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/effect/spawner/surgery_tray/full, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/machinery/camera/directional/north{ + c_tag = "Surgery A"; + network = list("ss13","medbay") + }, +/turf/open/floor/iron/white, +/area/station/medical/surgery/fore) "ini" = ( /obj/structure/falsewall, /turf/open/floor/plating, @@ -30131,15 +30111,6 @@ /obj/effect/spawner/random/armory/rubbershot, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/security/armory) -"iJI" = ( -/obj/structure/chair{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "iJK" = ( /obj/structure/lattice/catwalk, /obj/structure/railing, @@ -30176,14 +30147,6 @@ }, /turf/open/floor/carpet/lone, /area/station/service/chapel) -"iJX" = ( -/obj/item/target, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "iKd" = ( /obj/structure/window/reinforced/spawner/directional/south, /obj/effect/turf_decal/siding/white, @@ -33012,6 +32975,10 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/engineering/atmos) +"jBY" = ( +/obj/structure/weightmachine, +/turf/open/floor/iron, +/area/station/commons/fitness) "jCl" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/aft) @@ -34833,6 +34800,9 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/station/engineering/storage/tech) +"kcy" = ( +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "kcC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -38550,6 +38520,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"lfZ" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "lgg" = ( /obj/machinery/air_sensor/engine_chamber, /turf/open/floor/engine, @@ -38589,6 +38563,19 @@ }, /turf/open/floor/iron/textured, /area/station/security/brig) +"lgE" = ( +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/item/gun/energy/temperature/security, +/obj/item/clothing/suit/hooded/ablative, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured, +/area/station/ai_monitored/security/armory) "lgK" = ( /turf/closed/wall, /area/station/security/prison/visit) @@ -38610,15 +38597,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/storage) -"lhf" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "lhu" = ( /obj/machinery/camera/directional/north{ c_tag = "Xenobiology Lab Access"; @@ -41106,13 +41084,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/mechbay) -"lRd" = ( -/obj/structure/chair, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "lRf" = ( /obj/machinery/teleport/station, /turf/open/floor/plating, @@ -42092,6 +42063,10 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron/dark/textured_half, /area/station/security/office) +"mhP" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "mhQ" = ( /turf/closed/wall/r_wall, /area/station/command/teleporter) @@ -42513,12 +42488,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/prison/mess) -"mps" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "mpH" = ( /obj/effect/landmark/event_spawn, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -42629,18 +42598,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"mrD" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/surgery{ - pixel_x = -4; - pixel_y = 3 - }, -/obj/item/surgery_tray/full, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/surgery/aft) "mrI" = ( /obj/structure/railing{ dir = 1 @@ -42910,10 +42867,6 @@ "mvv" = ( /turf/open/floor/wood, /area/station/security/courtroom) -"mvE" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "mvG" = ( /obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible{ dir = 8 @@ -44032,18 +43985,6 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining_station, /turf/open/floor/iron/smooth, /area/mine/eva) -"mMU" = ( -/obj/machinery/camera/preset/ordnance{ - dir = 4 - }, -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "mNi" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -46406,6 +46347,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/maintenance/solars/port/aft) +"nxo" = ( +/obj/structure/chair{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "nxD" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -47591,6 +47541,13 @@ }, /turf/open/floor/wood, /area/station/service/library) +"nMU" = ( +/obj/structure/chair, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "nNe" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -48365,6 +48322,12 @@ /obj/structure/flora/rock/pile/icy/style_random, /turf/open/misc/asteroid/snow/coldroom, /area/icemoon/underground/explored) +"nYF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "nYZ" = ( /obj/item/storage/bag/trash, /turf/open/floor/plating, @@ -48457,6 +48420,9 @@ dir = 1 }, /area/station/security/prison) +"oaD" = ( +/turf/closed/wall, +/area/station/science/ordnance/bomb/planet) "oaG" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 9 @@ -50614,12 +50580,6 @@ }, /turf/open/misc/asteroid/snow/coldroom, /area/icemoon/underground/explored) -"oDd" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "oDg" = ( /obj/structure/chair/stool/directional/west, /obj/effect/decal/cleanable/dirt, @@ -51267,15 +51227,6 @@ }, /turf/open/floor/iron/white/side, /area/mine/living_quarters) -"oLt" = ( -/obj/structure/chair{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "oLz" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -53839,17 +53790,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/security/checkpoint/supply) -"pyl" = ( -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/item/kirbyplants/random, -/obj/structure/sign/flag/terragov/directional/north, -/turf/open/floor/iron, -/area/station/commons/fitness) "pyn" = ( /obj/item/storage/photo_album/chapel, /obj/structure/noticeboard/directional/west, @@ -55094,9 +55034,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"pRa" = ( -/turf/closed/wall, -/area/station/science/ordnance/bomb) "pRj" = ( /turf/closed/wall, /area/station/maintenance/port/aft) @@ -56811,6 +56748,12 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/hop) +"qqh" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "qqv" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance/two, @@ -56942,6 +56885,14 @@ "qtj" = ( /turf/closed/wall, /area/station/engineering/storage) +"qtl" = ( +/obj/item/target, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "qts" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/effect/turf_decal/stripes/red/line{ @@ -58087,13 +58038,6 @@ /obj/structure/closet/crate, /turf/open/floor/iron, /area/station/command/teleporter) -"qKB" = ( -/obj/structure/chair, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "qKQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -58187,6 +58131,13 @@ "qLY" = ( /turf/closed/wall/r_wall, /area/station/science/xenobiology) +"qMg" = ( +/obj/structure/sign/warning/secure_area{ + desc = "A warning sign which reads 'BOMB RANGE"; + name = "BOMB RANGE" + }, +/turf/closed/wall, +/area/station/science/ordnance/bomb/planet) "qMk" = ( /obj/structure/railing{ dir = 1 @@ -65052,12 +65003,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/mine/mechbay) -"sIb" = ( -/obj/effect/turf_decal/tile/bar/opposingcorners, -/obj/machinery/light/warm/directional/north, -/obj/machinery/digital_clock/directional/north, -/turf/open/floor/iron, -/area/station/service/bar) "sIl" = ( /obj/structure/flora/bush/flowers_yw/style_random, /obj/structure/flora/bush/fullgrass/style_random, @@ -65260,6 +65205,12 @@ dir = 1 }, /area/station/medical/chemistry) +"sLI" = ( +/obj/effect/turf_decal/tile/bar/opposingcorners, +/obj/machinery/light/warm/directional/north, +/obj/structure/fish_mount/bar/directional/north, +/turf/open/floor/iron, +/area/station/service/bar) "sLR" = ( /obj/machinery/conveyor{ dir = 1; @@ -69846,6 +69797,17 @@ }, /turf/open/floor/iron/showroomfloor, /area/station/security/processing) +"ufw" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/structure/sign/flag/terragov/directional/north, +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/iron, +/area/station/commons/fitness) "ufF" = ( /obj/structure/table, /obj/item/storage/box/prisoner{ @@ -69854,6 +69816,12 @@ /obj/item/storage/box/prisoner, /turf/open/floor/iron/smooth, /area/station/security/execution/transfer) +"ufM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "ufN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/iron/white, @@ -71022,13 +70990,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/dark/textured, /area/station/medical/treatment_center) -"uyV" = ( -/obj/item/target/alien/anchored, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plating/icemoon, -/area/station/science/ordnance/bomb) "uyW" = ( /obj/machinery/washing_machine, /obj/effect/turf_decal/siding/blue{ @@ -73196,6 +73157,12 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"viM" = ( +/turf/closed/indestructible/riveted{ + desc = "A wall impregnated with Fixium, able to withstand massive explosions with ease"; + name = "hyper-reinforced wall" + }, +/area/station/science/ordnance/bomb/planet) "viQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -75084,6 +75051,13 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/rd) +"vJZ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/commons/fitness) "vKk" = ( /obj/machinery/vending/security, /turf/open/floor/iron/smooth_edge, @@ -75447,6 +75421,18 @@ "vSi" = ( /turf/closed/wall, /area/mine/eva) +"vSo" = ( +/obj/machinery/camera/preset/ordnance{ + dir = 4 + }, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "vSE" = ( /obj/machinery/door/window/right/directional/east{ name = "Bar Access" @@ -75933,6 +75919,15 @@ "wam" = ( /turf/open/openspace, /area/station/cargo/storage) +"wav" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "waz" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/smooth_large, @@ -77002,6 +76997,18 @@ /obj/effect/turf_decal/tile/dark_blue/fourcorners, /turf/open/floor/iron, /area/station/command/bridge) +"wrt" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/surgery{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/effect/spawner/surgery_tray/full, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/medical/surgery/aft) "wrw" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 4 @@ -77461,16 +77468,6 @@ }, /turf/open/floor/plating, /area/station/cargo/storage) -"wyF" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/gun/energy/temperature/security, -/obj/item/clothing/suit/hooded/ablative, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/ai_monitored/security/armory) "wyL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ @@ -78492,6 +78489,12 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured, /area/station/security/processing) +"wOi" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "wOn" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -79913,13 +79916,6 @@ dir = 8 }, /area/station/science/ordnance/office) -"xgI" = ( -/obj/structure/sign/warning/secure_area{ - desc = "A warning sign which reads 'BOMB RANGE"; - name = "BOMB RANGE" - }, -/turf/closed/wall, -/area/station/science/ordnance/bomb) "xgK" = ( /obj/structure/table, /obj/item/transfer_valve{ @@ -79976,6 +79972,15 @@ "xhk" = ( /turf/open/floor/iron/dark, /area/station/commons/storage/primary) +"xhp" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/spawner/surgery_tray/full/morgue, +/obj/structure/table/reinforced, +/obj/machinery/requests_console/auto_name/directional/north, +/obj/effect/turf_decal/bot_white, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron/dark, +/area/station/medical/morgue) "xht" = ( /obj/machinery/door/window/right/directional/west{ name = "Shop Counter" @@ -80838,6 +80843,15 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"xvw" = ( +/obj/structure/chair{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plating/icemoon, +/area/station/science/ordnance/bomb/planet) "xvy" = ( /obj/structure/closet/firecloset, /obj/effect/turf_decal/stripes/line{ @@ -176295,7 +176309,7 @@ agF tgP rGh iJE -wyF +lgE yiL cVV dhi @@ -189455,7 +189469,7 @@ jre fuH fuH btU -hvt +xhp luR mlT lqZ @@ -249311,7 +249325,7 @@ cGB cGB gsI tLL -spy +vJZ kKL kKL kKL @@ -250334,8 +250348,8 @@ dyA skl gaC vfW -eOl vfW +jBY vfW lvk crv @@ -250589,7 +250603,7 @@ ygS oGr pDA skl -pyl +ufw uRo uRo uRo @@ -252403,7 +252417,7 @@ oqY kKL kKL kKL -sIb +sLI uXd iiE oIj @@ -255781,11 +255795,11 @@ oRu ccR uKj dDw -fsz +imT qgu tYA vds -mrD +wrt liz txH mFE @@ -272745,9 +272759,9 @@ bln bln bln bln -mvE -oDd -mvE +mhP +ufM +mhP bln bln wNO @@ -273001,11 +273015,11 @@ bln bln bln bln -xgI -mvE -anO -mvE -xgI +qMg +mhP +nYF +mhP +qMg bln bln wNO @@ -273257,13 +273271,13 @@ bln bln bln bln -mvE -mvE -cJB -oDd -aWb -mvE -mvE +mhP +mhP +dRU +ufM +qqh +mhP +mhP bln bln wNO @@ -273513,15 +273527,15 @@ wNO wNO bln bln -pRa -pRa -lRd -evT -evT -evT -iJI -pRa -pRa +oaD +oaD +nMU +kcy +kcy +kcy +nxo +oaD +oaD bln wNO wNO @@ -273770,15 +273784,15 @@ wNO wNO bln bln -mvE -iJX -mps -evT -byB -evT -hDA -bqr -mvE +mhP +qtl +wOi +kcy +hGu +kcy +lfZ +aYt +mhP bln wNO wNO @@ -274027,15 +274041,15 @@ wNO wNO bln bln -pRa -pRa -qKB -evT -evT -evT -oLt -pRa -pRa +oaD +oaD +ihM +kcy +kcy +kcy +xvw +oaD +oaD bln wNO wNO @@ -274285,13 +274299,13 @@ wNO wNO bln bln -mvE -mvE -mMU -uyV -lhf -mvE -mvE +mhP +mhP +vSo +fRr +wav +mhP +mhP bln bln wNO @@ -274543,11 +274557,11 @@ wNO wNO bln bln -xgI -mvE -beZ -mvE -xgI +qMg +mhP +viM +mhP +qMg bln bln wNO @@ -274801,9 +274815,9 @@ wNO wNO bln bln -mvE -pRa -mvE +mhP +oaD +mhP bln bln wNO diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index d70ea00eec6c..083c52fbc7f4 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -467,6 +467,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/office) +"ajn" = ( +/obj/structure/table/wood, +/obj/item/staff/broom, +/obj/item/wrench, +/obj/machinery/airalarm/directional/east, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/machinery/light_switch/directional/north, +/turf/open/floor/wood/large, +/area/station/service/theater) "ajq" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -1595,17 +1606,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"aEA" = ( -/obj/structure/table/wood, -/obj/item/staff/broom, -/obj/item/wrench, -/obj/machinery/airalarm/directional/east, -/obj/effect/turf_decal/siding/wood/corner{ - dir = 8 - }, -/obj/structure/sign/poster/random/directional/north, -/turf/open/floor/wood/large, -/area/station/service/theater) "aEH" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -2349,6 +2349,16 @@ /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/science/central) +"aRk" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/effect/spawner/surgery_tray/full, +/obj/item/clothing/gloves/latex, +/obj/item/clothing/suit/apron/surgical, +/turf/open/floor/iron/white, +/area/station/medical/surgery/aft) "aRo" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -9665,14 +9675,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"dyq" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/status_display/evac/directional/west, -/obj/machinery/digital_clock/directional/south, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "dyr" = ( /obj/machinery/status_display/door_timer{ id = "Cell 3"; @@ -10706,11 +10708,6 @@ /obj/effect/turf_decal/tile/brown/anticorner/contrasted, /turf/open/floor/iron, /area/station/cargo/miningoffice) -"dSJ" = ( -/obj/effect/turf_decal/siding/wood, -/obj/structure/sign/poster/random/directional/north, -/turf/open/floor/wood/large, -/area/station/service/theater) "dTi" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -11418,16 +11415,6 @@ }, /turf/open/floor/iron, /area/station/security/warden) -"eew" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/gun/energy/temperature/security, -/obj/item/clothing/suit/hooded/ablative, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) "eey" = ( /obj/machinery/firealarm/directional/west, /obj/structure/rack, @@ -12770,16 +12757,6 @@ /obj/item/flashlight/lamp, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) -"eBO" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/obj/item/surgery_tray/full, -/obj/item/clothing/gloves/latex, -/obj/item/clothing/suit/apron/surgical, -/turf/open/floor/iron/white, -/area/station/medical/surgery/aft) "eBU" = ( /obj/machinery/light/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -15051,13 +15028,6 @@ /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/iron/dark, /area/station/ai_monitored/aisat/exterior) -"fpg" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/status_display/evac/directional/west, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "fpj" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -15173,6 +15143,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/xenobiology/hallway) +"frt" = ( +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/item/gun/energy/temperature/security, +/obj/item/clothing/suit/hooded/ablative, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/security/armory) "frw" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/cobweb/cobweb2, @@ -19121,6 +19104,17 @@ }, /turf/open/floor/iron/white, /area/station/science/research) +"gUe" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/structure/window/spawner/directional/west, +/obj/effect/spawner/random/structure/musician/piano/random_piano, +/turf/open/floor/wood/large, +/area/station/service/theater) "gUf" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -28909,6 +28903,18 @@ /obj/machinery/atmospherics/pipe/smart/simple/supply/hidden, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage/gas) +"kkx" = ( +/obj/structure/table/reinforced, +/obj/machinery/airalarm/directional/north, +/obj/effect/turf_decal/tile/neutral/half{ + dir = 8 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/spawner/surgery_tray/full/morgue, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 8 + }, +/area/station/medical/morgue) "kkA" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 4 @@ -30837,6 +30843,16 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/locker) +"kTq" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/landmark/start/clown, +/obj/structure/chair/wood/wings{ + dir = 8 + }, +/obj/machinery/light/small/directional/north, +/obj/structure/fish_mount/bar/directional/north, +/turf/open/floor/wood/large, +/area/station/service/theater) "kTO" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -31337,18 +31353,6 @@ }, /turf/open/floor/iron/white, /area/station/science/research) -"lbX" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 10 - }, -/obj/structure/window/spawner/directional/west, -/obj/structure/sign/poster/random/directional/north, -/obj/effect/spawner/random/structure/musician/piano/random_piano, -/turf/open/floor/wood/large, -/area/station/service/theater) "lcG" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -31393,6 +31397,13 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics/garden) +"ldm" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/status_display/evac/directional/west, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "lds" = ( /obj/structure/table, /obj/item/storage/fancy/egg_box, @@ -37299,6 +37310,14 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"nnE" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/status_display/evac/directional/west, +/obj/machinery/digital_clock/directional/south, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "nnR" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -53801,16 +53820,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/wood, /area/station/command/heads_quarters/captain/private) -"sZa" = ( -/obj/machinery/light_switch/directional/north, -/obj/effect/turf_decal/siding/wood, -/obj/effect/landmark/start/clown, -/obj/structure/chair/wood/wings{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/wood/large, -/area/station/service/theater) "sZo" = ( /obj/machinery/light/directional/north, /obj/structure/reagent_dispensers/watertank/high, @@ -61148,18 +61157,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"vzt" = ( -/obj/structure/table/reinforced, -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/neutral/half{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/obj/item/surgery_tray/full/morgue, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 8 - }, -/area/station/medical/morgue) "vzx" = ( /obj/machinery/portable_atmospherics/canister/plasma, /obj/effect/turf_decal/siding/purple{ @@ -67091,10 +67088,6 @@ }, /turf/open/floor/iron, /area/station/ai_monitored/command/storage/eva) -"xBX" = ( -/obj/machinery/firealarm/directional/east, -/turf/closed/wall, -/area/station/security/checkpoint/customs) "xCf" = ( /obj/item/clothing/suit/jacket/straight_jacket, /obj/item/electropack, @@ -67594,6 +67587,10 @@ }, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"xLM" = ( +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/large, +/area/station/service/theater) "xLR" = ( /obj/structure/table, /obj/item/stack/sheet/iron/fifty, @@ -83042,7 +83039,7 @@ wdr fcq xfI fcq -xBX +xjh qhW xjh yme @@ -87448,13 +87445,13 @@ rke jUb nTn jUb -fpg +ldm snb kpV qOO gGK snb -dyq +nnE jUb iEm kym @@ -88752,7 +88749,7 @@ tck kHg nMf vDc -eBO +aRk nCc msC tBJ @@ -94408,7 +94405,7 @@ uYI iqz iaK hZV -vzt +kkx jBU kgx kgx @@ -96630,7 +96627,7 @@ aaa aeq pfs jcc -eew +frt fnO gHA kaC @@ -105921,7 +105918,7 @@ aEr sDs tUv obG -lbX +gUe yks okX tZX @@ -106178,7 +106175,7 @@ biV fRS tUv obG -sZa +kTq vRU gpf ouk @@ -106435,7 +106432,7 @@ vFB fRS tUv obG -dSJ +xLM wrZ aWq oph @@ -106949,7 +106946,7 @@ vFB fRS sGH obG -aEA +ajn mZc iUe dLT diff --git a/_maps/map_files/NSVBlueshift/Blueshift.dmm b/_maps/map_files/NSVBlueshift/Blueshift.dmm index 44755e21bda7..5201c56b2c33 100644 --- a/_maps/map_files/NSVBlueshift/Blueshift.dmm +++ b/_maps/map_files/NSVBlueshift/Blueshift.dmm @@ -40180,8 +40180,8 @@ /turf/closed/wall/r_wall, /area/station/engineering/break_room) "hLd" = ( -/obj/item/ammo_casing/a357, -/obj/item/ammo_casing/a357{ +/obj/item/ammo_casing/c357, +/obj/item/ammo_casing/c357{ pixel_x = 7; pixel_y = 7 }, @@ -48471,7 +48471,7 @@ /area/station/hallway/secondary/entry) "jqK" = ( /obj/structure/table, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /turf/open/floor/iron/white, /area/station/medical/morgue) "jqP" = ( @@ -61828,7 +61828,7 @@ desc = "An old pair of nitrile gloves, with no sterile properties."; name = "old nitrile gloves" }, -/obj/item/surgery_tray, +/obj/effect/spawner/surgery_tray, /turf/open/floor/iron, /area/station/maintenance/rus_surgery) "lSd" = ( @@ -78416,7 +78416,7 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/iron, /area/station/medical/surgery/theatre) "pbP" = ( @@ -82299,7 +82299,7 @@ /area/station/command/heads_quarters/hop) "pQu" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron, /area/station/medical/surgery) "pQy" = ( diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index 15bcb272d73f..a7a67eac11df 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -420,23 +420,6 @@ /obj/item/clothing/head/utility/hardhat/welding, /turf/open/misc/asteroid/airless, /area/space/nearstation) -"adt" = ( -/obj/machinery/defibrillator_mount/directional/south, -/obj/structure/table/glass, -/obj/item/surgery_tray/full, -/obj/effect/turf_decal/box/white/corners{ - dir = 4 - }, -/obj/effect/turf_decal/siding/thinplating_new/light{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/turf/open/floor/iron/white/textured_corner{ - dir = 1 - }, -/area/station/medical/surgery/theatre) "adH" = ( /obj/item/reagent_containers/cup/bottle/morphine{ pixel_x = -4; @@ -535,19 +518,6 @@ }, /turf/open/floor/wood/large, /area/station/maintenance/department/bridge) -"aeq" = ( -/obj/structure/table/reinforced/rglass, -/obj/effect/turf_decal/siding{ - dir = 10 - }, -/obj/machinery/button/door/directional/west{ - name = "CMO Surgery Privacy Shutters"; - id = "cmoprivacy2"; - req_access = list("cmo") - }, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/white/herringbone, -/area/station/command/heads_quarters/cmo) "aer" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -7612,6 +7582,15 @@ }, /turf/open/floor/iron/dark, /area/station/service/bar) +"bhq" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/trimline/red/corner, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/dark/side{ + dir = 9 + }, +/area/station/security/execution/education) "bhs" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 @@ -10566,15 +10545,6 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/primary/port) -"bDU" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/clothing/suit/hooded/ablative, -/obj/item/gun/energy/temperature/security, -/obj/effect/turf_decal/bot/right, -/obj/machinery/newscaster/directional/north, -/turf/open/floor/iron/dark/textured_large, -/area/station/ai_monitored/security/armory) "bDW" = ( /obj/item/bikehorn/rubberducky, /turf/open/misc/asteroid/snow/airless, @@ -12766,9 +12736,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/engineering/atmos) -"bUo" = ( -/turf/open/floor/iron/solarpanel/airless, -/area/station/solars/port/aft) "bUs" = ( /obj/structure/cable, /obj/effect/spawner/random/trash/cigbutt, @@ -27663,6 +27630,15 @@ /obj/structure/sign/poster/official/moth_meth/directional/east, /turf/open/floor/iron/dark, /area/station/medical/cryo) +"edG" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/surgery_tray/full/morgue, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark, +/area/station/medical/morgue) "edK" = ( /obj/effect/spawner/structure/window, /obj/machinery/door/poddoor/shutters/preopen{ @@ -45630,6 +45606,19 @@ }, /turf/open/floor/plating, /area/station/hallway/primary/port) +"gMw" = ( +/obj/structure/rack, +/obj/item/crowbar/large, +/obj/item/wirecutters, +/obj/item/wrench, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/security/mechbay) "gMy" = ( /obj/machinery/computer/records/medical{ dir = 1 @@ -56571,20 +56560,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/medical/storage) -"isM" = ( -/obj/machinery/defibrillator_mount/directional/south, -/obj/structure/table/glass, -/obj/item/surgery_tray/full, -/obj/effect/turf_decal/box/white/corners{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating_new/light{ - dir = 8 - }, -/turf/open/floor/iron/white/textured_corner{ - dir = 4 - }, -/area/station/medical/surgery/theatre) "isT" = ( /obj/effect/turf_decal/siding/dark{ dir = 1 @@ -58280,6 +58255,14 @@ /obj/structure/sign/poster/official/obey/directional/north, /turf/open/floor/iron/dark/herringbone, /area/station/security/warden) +"iFJ" = ( +/obj/item/toy/katana{ + icon_state = "supermatter_sword"; + icon_angle = -45 + }, +/obj/structure/ladder, +/turf/open/floor/plating, +/area/station/engineering/supermatter/room/upper) "iFK" = ( /obj/structure/broken_flooring/singular/directional/east, /obj/effect/decal/cleanable/dirt/dust, @@ -62229,15 +62212,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/white, /area/station/science/lower) -"jkv" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/trimline/red/corner, -/obj/effect/turf_decal/siding/thinplating_new/dark/corner, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/dark/side{ - dir = 9 - }, -/area/station/security/execution/education) "jkx" = ( /turf/open/floor/glass/reinforced, /area/station/engineering/main) @@ -62772,25 +62746,6 @@ /obj/structure/secure_safe/directional/north, /turf/open/floor/iron/dark/small, /area/station/maintenance/starboard/fore) -"jql" = ( -/obj/effect/turf_decal/siding/dark{ - dir = 5 - }, -/obj/effect/turf_decal/siding/dark/corner{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/green/filled/line{ - dir = 5 - }, -/obj/effect/turf_decal/trimline/green/filled/line{ - dir = 5 - }, -/obj/structure/table/glass, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/machinery/digital_clock/directional/east, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/dark/small, -/area/station/science/robotics/augments) "jqo" = ( /obj/effect/turf_decal/tile/dark_blue/anticorner/contrasted{ dir = 4 @@ -63645,15 +63600,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"jwC" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/hallway/primary/fore) "jwN" = ( /obj/effect/turf_decal/siding/thinplating_new/dark, /obj/effect/turf_decal/trimline/green/filled/line, @@ -64540,15 +64486,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/openspace, /area/station/engineering/supermatter/room/upper) -"jBX" = ( -/obj/structure/table/reinforced, -/obj/item/surgery_tray/full/morgue, -/obj/effect/turf_decal/siding/dark/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/dark, -/area/station/medical/morgue) "jCb" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -64693,6 +64630,19 @@ }, /turf/open/floor/iron/dark, /area/station/service/hydroponics) +"jDf" = ( +/obj/structure/table/reinforced/rglass, +/obj/effect/turf_decal/siding{ + dir = 10 + }, +/obj/machinery/button/door/directional/west{ + name = "CMO Surgery Privacy Shutters"; + id = "cmoprivacy2"; + req_access = list("cmo") + }, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/white/herringbone, +/area/station/command/heads_quarters/cmo) "jDg" = ( /obj/structure/kitchenspike, /turf/open/misc/asteroid/snow/coldroom, @@ -65657,6 +65607,25 @@ /obj/structure/sign/warning/electric_shock/directional/east, /turf/open/floor/iron, /area/station/maintenance/port/central) +"jLm" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 5 + }, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/green/filled/line{ + dir = 5 + }, +/obj/effect/turf_decal/trimline/green/filled/line{ + dir = 5 + }, +/obj/structure/table/glass, +/obj/structure/window/reinforced/spawner/directional/north, +/obj/machinery/digital_clock/directional/east, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/dark/small, +/area/station/science/robotics/augments) "jLx" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -76677,6 +76646,18 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plating, /area/station/maintenance/port/central) +"lpI" = ( +/obj/structure/rack, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/item/clothing/suit/hooded/ablative, +/obj/item/gun/energy/temperature/security, +/obj/effect/turf_decal/bot/right, +/obj/machinery/newscaster/directional/north, +/turf/open/floor/iron/dark/textured_large, +/area/station/ai_monitored/security/armory) "lpK" = ( /obj/effect/turf_decal/tile/brown/opposingcorners{ dir = 1 @@ -81352,17 +81333,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/lower) -"mcB" = ( -/obj/structure/hedge, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/marker_beacon/lime, -/turf/open/floor/iron/white, -/area/station/hallway/primary/fore) "mcX" = ( /obj/effect/turf_decal/trimline/blue, /obj/effect/turf_decal/trimline/blue/mid_joiner{ @@ -83271,6 +83241,20 @@ /obj/structure/flora/rock/pile/style_random, /turf/open/floor/iron/dark/herringbone, /area/station/ai_monitored/aisat/exterior) +"msl" = ( +/obj/machinery/defibrillator_mount/directional/south, +/obj/structure/table/glass, +/obj/effect/spawner/surgery_tray/full, +/obj/effect/turf_decal/box/white/corners{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/light{ + dir = 8 + }, +/turf/open/floor/iron/white/textured_corner{ + dir = 4 + }, +/area/station/medical/surgery/theatre) "msm" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/item/kirbyplants/random, @@ -85746,19 +85730,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/engine/hull/reinforced, /area/space/nearstation) -"mLK" = ( -/obj/structure/rack, -/obj/item/crowbar/large/heavy, -/obj/item/wirecutters, -/obj/item/wrench, -/obj/effect/turf_decal/siding/thinplating_new/dark{ - dir = 1 - }, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/security/mechbay) "mLL" = ( /obj/machinery/atmospherics/pipe/smart/simple/supply/visible{ dir = 1 @@ -89594,6 +89565,16 @@ icon_state = "asteroid11" }, /area/space/nearstation) +"nqF" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/station/hallway/primary/fore) "nqG" = ( /obj/structure/railing, /obj/structure/chair/sofa/bench/right{ @@ -92152,13 +92133,6 @@ /obj/structure/closet/secure_closet/security/science, /turf/open/floor/iron/dark/textured, /area/station/security/checkpoint/science) -"nKF" = ( -/obj/item/toy/katana{ - icon_state = "supermatter_sword" - }, -/obj/structure/ladder, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room/upper) "nKG" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners{ dir = 1 @@ -98761,6 +98735,20 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured_corner, /area/station/ai_monitored/turret_protected/aisat/foyer) +"oIK" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/surgery_tray/full, +/obj/machinery/status_display/ai/directional/east, +/obj/effect/turf_decal/trimline/dark_red/filled/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/dark/corner{ + dir = 1 + }, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 1 + }, +/area/station/security/medical) "oIM" = ( /obj/item/pizzabox, /turf/open/misc/asteroid/airless, @@ -105474,6 +105462,14 @@ }, /turf/open/floor/wood/tile, /area/station/service/cafeteria) +"pCC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/item/kirbyplants/organic/plant22, +/obj/structure/fish_mount/bar/directional/north, +/turf/open/floor/wood/parquet, +/area/station/commons/lounge) "pCF" = ( /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 4 @@ -106595,6 +106591,10 @@ }, /turf/open/floor/iron/dark/small, /area/station/service/theater) +"pMb" = ( +/obj/structure/cable, +/turf/open/floor/iron/solarpanel/airless, +/area/station/solars/port/aft) "pMe" = ( /obj/effect/turf_decal/siding/brown{ dir = 4 @@ -113583,14 +113583,6 @@ }, /turf/open/floor/engine/n2, /area/station/engineering/atmos) -"qOe" = ( -/obj/item/ammo_casing/a357/spent{ - pixel_y = 6; - pixel_x = 9 - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "qOf" = ( /obj/structure/flora/rock/pile/style_random, /obj/effect/decal/cleanable/dirt, @@ -120899,20 +120891,6 @@ /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) -"rUg" = ( -/obj/structure/table/reinforced, -/obj/item/surgery_tray/full, -/obj/machinery/status_display/ai/directional/east, -/obj/effect/turf_decal/trimline/dark_red/filled/corner{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/dark/corner{ - dir = 1 - }, -/turf/open/floor/iron/dark/smooth_corner{ - dir = 1 - }, -/area/station/security/medical) "rUp" = ( /obj/structure/hedge, /obj/machinery/light/small/dim/directional/north, @@ -122516,6 +122494,23 @@ dir = 1 }, /area/station/engineering/atmos/pumproom) +"sgJ" = ( +/obj/machinery/defibrillator_mount/directional/south, +/obj/structure/table/glass, +/obj/effect/spawner/surgery_tray/full, +/obj/effect/turf_decal/box/white/corners{ + dir = 4 + }, +/obj/effect/turf_decal/siding/thinplating_new/light{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/iron/white/textured_corner{ + dir = 1 + }, +/area/station/medical/surgery/theatre) "sgK" = ( /obj/structure/railing{ dir = 6 @@ -129427,14 +129422,6 @@ dir = 1 }, /area/station/maintenance/department/bridge) -"tlp" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 9 - }, -/obj/item/kirbyplants/organic/plant22, -/obj/machinery/barsign/directional/north, -/turf/open/floor/wood/parquet, -/area/station/commons/lounge) "tly" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -154090,6 +154077,18 @@ }, /turf/open/floor/iron/dark, /area/station/service/bar) +"wVM" = ( +/obj/structure/hedge, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/marker_beacon/lime, +/obj/machinery/firealarm/directional/south, +/turf/open/floor/iron/white, +/area/station/hallway/primary/fore) "wVQ" = ( /obj/effect/turf_decal/siding/dark{ dir = 1 @@ -154743,6 +154742,14 @@ dir = 8 }, /area/station/hallway/primary/fore) +"xbu" = ( +/obj/item/ammo_casing/c357/spent{ + pixel_y = 6; + pixel_x = 9 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "xbv" = ( /obj/machinery/light/floor{ color = "#ffcc99" @@ -190950,7 +190957,7 @@ gkr gJT eof lcq -aeq +jDf gIv leM nVH @@ -195081,7 +195088,7 @@ gfs tGW gwl tEk -jBX +edG bPN kmm gsi @@ -200516,7 +200523,7 @@ eAq wwa kVz gTR -mLK +gMw suG nuR qWH @@ -204127,7 +204134,7 @@ qld unf kBp fHP -rUg +oIK gCL mpm odE @@ -204622,7 +204629,7 @@ eFd dFs eFd eFd -bDU +lpI ocC epY bmk @@ -243468,9 +243475,9 @@ txW pCa txW txW -bUo +pMb ccy -bUo +pMb txW txW pCa @@ -243725,9 +243732,9 @@ eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW eBg ccy @@ -243982,9 +243989,9 @@ eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb pCa eBg ccy @@ -244239,9 +244246,9 @@ eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb pCa eBg ccy @@ -244496,9 +244503,9 @@ eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW eBg ccy @@ -245777,17 +245784,17 @@ txW txW rQU txW -bUo +pMb ccy -bUo +pMb txW txW uri txW txW -bUo +pMb ccy -bUo +pMb txW txW lGA @@ -246034,17 +246041,17 @@ txW txW txW txW -bUo +pMb ccy -bUo +pMb txW eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW txW txW @@ -246291,17 +246298,17 @@ txW txW txW pCa -bUo +pMb ccy -bUo +pMb pCa eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb pCa lGA txW @@ -246548,17 +246555,17 @@ txW txW txW txW -bUo +pMb ccy -bUo +pMb pCa eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb txW lGA txW @@ -246805,17 +246812,17 @@ pCa pCa lGA txW -bUo +pMb ccy -bUo +pMb txW eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW lGA txW @@ -247027,7 +247034,7 @@ kHc kHc gMt sRw -tlp +pCC wKS dDs iHr @@ -254711,7 +254718,7 @@ anu hCZ uEd pMJ -qOe +xbu xBf hCZ hCZ @@ -257283,7 +257290,7 @@ knv rjP ueF tyt -isM +msl hCZ bHr wGz @@ -257797,7 +257804,7 @@ ltw lEq lzJ osd -adt +sgJ hCZ scC dmO @@ -260423,7 +260430,7 @@ kTT etc qtr hrd -nKF +iFJ cAe cAe cAe @@ -261125,7 +261132,7 @@ lFg lkH nnA kqR -mcB +wVM qNb lzo sZB @@ -261361,7 +261368,7 @@ xrX vSf geL mPk -jwC +nqF mjo qzk qzk @@ -264732,7 +264739,7 @@ snn ddY ead hEC -jql +jLm bNT kFF xGM @@ -271972,7 +271979,7 @@ iBs pSA oSh fsP -jkv +bhq czf jsj hxD diff --git a/_maps/map_files/Ouroboros/Ouroboros.dmm b/_maps/map_files/Ouroboros/Ouroboros.dmm index ffedf8671787..81353bd4ac07 100644 --- a/_maps/map_files/Ouroboros/Ouroboros.dmm +++ b/_maps/map_files/Ouroboros/Ouroboros.dmm @@ -13374,7 +13374,7 @@ /obj/structure/table/glass, /obj/machinery/firealarm/directional/west, /obj/machinery/light/cold/no_nightlight/directional/west, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/reagent_containers/spray/cleaner{ pixel_x = 6; pixel_y = 7 @@ -50201,7 +50201,7 @@ /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 4 }, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /turf/open/floor/iron/dark, /area/station/medical/morgue) "ouR" = ( @@ -61377,7 +61377,7 @@ dir = 4 }, /obj/structure/table/glass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/surgery/fore) "rRs" = ( @@ -63863,7 +63863,7 @@ /obj/structure/table/glass, /obj/machinery/firealarm/directional/east, /obj/machinery/light/cold/no_nightlight/directional/east, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/reagent_containers/syringe{ pixel_x = -7 }, @@ -70702,7 +70702,7 @@ dir = 4 }, /obj/machinery/airalarm/directional/west, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/dark/smooth_half{ dir = 1 }, diff --git a/_maps/map_files/SerenityStation/SerenityStation.dmm b/_maps/map_files/SerenityStation/SerenityStation.dmm index 9ecbf1c7a1c5..2ce5604e73a2 100644 --- a/_maps/map_files/SerenityStation/SerenityStation.dmm +++ b/_maps/map_files/SerenityStation/SerenityStation.dmm @@ -10740,7 +10740,7 @@ "dbR" = ( /obj/structure/table, /obj/structure/window/reinforced/spawner/directional/north, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -16230,7 +16230,7 @@ /obj/structure/table/glass, /obj/machinery/light/directional/south, /obj/effect/turf_decal/trimline/blue/filled/line, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/machinery/camera/directional/south{ c_tag = "Medbay - Surgery Room A"; name = "medbay camera"; @@ -35505,7 +35505,7 @@ dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/white, /area/station/medical/surgery/aft) "kep" = ( @@ -75082,7 +75082,7 @@ /area/station/hallway/primary/central/fore) "vOd" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/reagent_containers/spray/cleaner, /turf/open/floor/iron/dark/diagonal, /area/station/medical/morgue) diff --git a/_maps/map_files/Snowglobe/snowglobe.dmm b/_maps/map_files/Snowglobe/snowglobe.dmm index 963da09a5457..4eec1db03b40 100644 --- a/_maps/map_files/Snowglobe/snowglobe.dmm +++ b/_maps/map_files/Snowglobe/snowglobe.dmm @@ -7379,7 +7379,7 @@ /area/station/medical/virology) "bXb" = ( /obj/machinery/defibrillator_mount/directional/south, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/tile/blue/half, /obj/structure/table/reinforced, /turf/open/floor/iron/white/smooth_edge, @@ -35453,7 +35453,7 @@ dir = 8 }, /obj/effect/turf_decal/tile/blue, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/siding/blue{ dir = 8 }, @@ -36150,7 +36150,7 @@ "jIS" = ( /obj/machinery/airalarm/directional/east, /obj/structure/table/reinforced, -/obj/item/surgery_tray, +/obj/effect/spawner/surgery_tray, /turf/open/floor/plating, /area/station/maintenance/abandon_exam) "jIV" = ( @@ -39098,7 +39098,7 @@ /area/station/cargo/storage) "kvj" = ( /obj/machinery/defibrillator_mount/directional/south, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/tile/blue/half, /obj/structure/table/reinforced, /turf/open/floor/iron/white/smooth_edge, @@ -41958,7 +41958,7 @@ /area/station/engineering/atmos/project) "liw" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /obj/structure/window/reinforced/spawner/directional/north, /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -58805,7 +58805,7 @@ /area/station/commons/dorms) "pPN" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/siding/blue{ dir = 6 }, diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm index a3b8e1ea24b4..068bf376693b 100644 --- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm +++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm @@ -38263,7 +38263,7 @@ /area/station/command/heads_quarters/captain/private) "kRg" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/machinery/status_display/evac/directional/south, /obj/item/reagent_containers/spray/cleaner, /turf/open/floor/iron/dark/smooth_large, @@ -41218,7 +41218,7 @@ dir = 6 }, /obj/effect/turf_decal/tile/blue/full, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/structure/sign/poster/official/random/directional/south, /obj/structure/sign/nanotrasen{ pixel_x = 32 @@ -50185,7 +50185,7 @@ dir = 5 }, /obj/effect/turf_decal/tile/blue/full, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/structure/sign/nanotrasen{ pixel_x = 32 }, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index e730dea04bc9..8f24d290d175 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -9929,7 +9929,7 @@ /area/centcom/central_command_areas/armory) "Vh" = ( /obj/structure/table/reinforced, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 10; pixel_x = 2 }, @@ -62229,7 +62229,7 @@ xt xt xt xt -xt +PG xt Vd zm @@ -62486,7 +62486,7 @@ xt xt xt xt -rq +xt xt xt zl diff --git a/_maps/map_files/generic/CentCom_nova_z2.dmm b/_maps/map_files/generic/CentCom_nova_z2.dmm index fb769da5139b..d60a296e2e81 100644 --- a/_maps/map_files/generic/CentCom_nova_z2.dmm +++ b/_maps/map_files/generic/CentCom_nova_z2.dmm @@ -17322,7 +17322,7 @@ dir = 1 }, /obj/structure/table/reinforced, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/iron/white, /area/centcom/holding/cafe) "wZh" = ( @@ -18014,7 +18014,7 @@ /area/centcom/holding/cafe) "ycL" = ( /obj/structure/table/optable, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/bot_blue, /turf/open/floor/iron/white, /area/centcom/interlink) diff --git a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_1.dmm b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_1.dmm index 7e99bf96803c..daec11b31a2c 100644 --- a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_1.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_1.dmm @@ -2735,7 +2735,7 @@ gs IK IK IK -pD +mg "} (53,1,1) = {" AN @@ -2771,7 +2771,7 @@ IK IK IK IK -pD +mg "} (54,1,1) = {" AN @@ -2804,10 +2804,10 @@ gs IK IK IK -pD -pD -pD -pD +mg +mg +mg +mg "} (55,1,1) = {" AN @@ -2840,7 +2840,7 @@ IK IK IK IK -pD +mg IK IK IK @@ -2875,8 +2875,8 @@ cV cV mg sf -pD -pD +mg +mg IK IK IK diff --git a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm index e7c0c22ad057..dd68accab503 100644 --- a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_2.dmm @@ -2907,7 +2907,7 @@ gs IK IK IK -pD +mg "} (53,1,1) = {" AN @@ -2943,7 +2943,7 @@ IK IK IK IK -pD +mg "} (54,1,1) = {" AN @@ -2976,10 +2976,10 @@ gs IK IK IK -pD -pD -pD -pD +mg +mg +mg +mg "} (55,1,1) = {" AN @@ -3012,7 +3012,7 @@ IK IK IK IK -pD +mg IK IK IK @@ -3047,8 +3047,8 @@ cV cV mg sf -pD -pD +mg +mg IK IK gs diff --git a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_3.dmm b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_3.dmm index 334f49ad8b60..83d22aaf3d8e 100644 --- a/_maps/map_files/tramstation/maintenance_modules/dormenginelower_3.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/dormenginelower_3.dmm @@ -2638,7 +2638,7 @@ gs IK IK IK -pD +mg "} (53,1,1) = {" AN @@ -2674,7 +2674,7 @@ IK IK IK IK -pD +mg "} (54,1,1) = {" AN @@ -2707,10 +2707,10 @@ gs IK IK IK -pD -pD -pD -pD +mg +mg +mg +mg "} (55,1,1) = {" AN @@ -2743,7 +2743,7 @@ IK IK IK IK -pD +mg IK IK IK @@ -2778,8 +2778,8 @@ cV cV mg sf -pD -pD +mg +mg IK IK gs diff --git a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_1.dmm b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_1.dmm index 5eae1f6e7ec9..cc4cbdcdd967 100644 --- a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_1.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_1.dmm @@ -1037,7 +1037,7 @@ a J J J -W +t J J J @@ -1060,10 +1060,10 @@ Z "} (29,1,1) = {" m -W -W -W -W +t +t +t +t J J J @@ -1086,7 +1086,7 @@ Z "} (30,1,1) = {" J -W +t J J J @@ -1111,8 +1111,8 @@ Z Z "} (31,1,1) = {" -W -W +t +t J J a diff --git a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_2.dmm b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_2.dmm index 02960cfadc51..df7d703de155 100644 --- a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_2.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_2.dmm @@ -136,10 +136,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor, /area/station/maintenance/starboard/greater) -"oT" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/station/asteroid) "oV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/button/door/directional/west{ @@ -1112,7 +1108,7 @@ Rk cV cV cV -oT +ja cV sj PC @@ -1135,10 +1131,10 @@ fX "} (29,1,1) = {" Cn -oT -oT -oT -oT +ja +ja +ja +ja cV sj sj @@ -1161,7 +1157,7 @@ fX "} (30,1,1) = {" cV -oT +ja cV cV cV @@ -1186,8 +1182,8 @@ fX fX "} (31,1,1) = {" -oT -oT +ja +ja cV cV Rk diff --git a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_3.dmm b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_3.dmm index 02618e94a681..12357ca0a2f8 100644 --- a/_maps/map_files/tramstation/maintenance_modules/servicecargolower_3.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/servicecargolower_3.dmm @@ -948,7 +948,7 @@ a J J J -W +t J J J @@ -971,10 +971,10 @@ Z "} (29,1,1) = {" m -W -W -W -W +t +t +t +t J J J @@ -997,7 +997,7 @@ Z "} (30,1,1) = {" J -W +t J J J @@ -1022,8 +1022,8 @@ Z Z "} (31,1,1) = {" -W -W +t +t J J a diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 0c1245591ec4..61a2572b0c3a 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -69,15 +69,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/station/asteroid) -"aam" = ( -/obj/machinery/power/solar{ - name = "Starboard Solar Array"; - id = "forestarboard" - }, -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "aan" = ( /turf/open/floor/iron/stairs/medium{ dir = 8 @@ -99,20 +90,10 @@ /obj/structure/marker_beacon/burgundy, /turf/open/misc/asteroid/airless, /area/station/asteroid) -"aas" = ( -/obj/effect/turf_decal/sand/plating, -/obj/machinery/light/small/directional/west, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "aat" = ( /obj/item/stack/cable_coil, /turf/open/misc/asteroid/airless, /area/station/asteroid) -"aau" = ( -/obj/effect/turf_decal/sand/plating, -/obj/machinery/light/small/directional/east, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "aaw" = ( /obj/item/storage/toolbox/electrical, /turf/open/misc/asteroid/airless, @@ -132,11 +113,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/plating, /area/station/commons/vacant_room) -"aaC" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "aaD" = ( /obj/structure/ore_box, /turf/open/misc/asteroid/airless, @@ -1332,27 +1308,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /turf/closed/wall/r_wall, /area/station/science/ordnance/burnchamber) -"aek" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/obj/machinery/power/solar{ - name = "Port Solar Array"; - id = "portsolar" - }, -/turf/open/floor/plating/airless, -/area/station/solars/port) -"ael" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/station/solars/port) -"aem" = ( -/obj/item/storage/toolbox/electrical, -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/turf/open/floor/plating/airless, -/area/station/solars/port) "aen" = ( /obj/effect/turf_decal/sand/plating, /obj/item/stack/ore/glass, @@ -4308,6 +4263,12 @@ /obj/effect/turf_decal/trimline/red/filled/line, /turf/open/floor/iron, /area/station/security/checkpoint/escape) +"aDO" = ( +/obj/effect/turf_decal/stripes/box, +/obj/structure/cable/multilayer/multiz, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "aDV" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -5770,6 +5731,10 @@ "aQO" = ( /turf/closed/wall/r_wall, /area/station/command/bridge) +"aQS" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "aQU" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -5911,9 +5876,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/sorting) -"aST" = ( -/turf/closed/wall/r_wall, -/area/station/solars/port) "aTa" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -6255,11 +6217,6 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/wood/large, /area/station/service/library) -"bck" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "bcq" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot, @@ -6426,6 +6383,12 @@ }, /turf/open/indestructible/tram, /area/station/hallway/primary/tram/left) +"bge" = ( +/obj/structure/cable/layer1, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "bgo" = ( /obj/structure/closet/crate/bin, /obj/effect/spawner/random/contraband/prison, @@ -6737,6 +6700,10 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) +"boa" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "boc" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -6946,13 +6913,6 @@ /obj/item/radio/off, /turf/open/floor/iron/dark, /area/station/command/teleporter) -"bsU" = ( -/obj/structure/cable, -/obj/structure/cable/layer1, -/obj/effect/turf_decal/sand/plating, -/obj/machinery/light/floor, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "bsW" = ( /obj/machinery/duct, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -7094,6 +7054,12 @@ /obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/station/cargo/miningfoundry) +"bvB" = ( +/obj/structure/ladder, +/obj/effect/turf_decal/stripes/box, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "bvH" = ( /obj/structure/table, /obj/machinery/microwave{ @@ -7851,15 +7817,6 @@ /obj/machinery/light/warm/directional/east, /turf/open/floor/iron/dark, /area/station/service/chapel) -"bKl" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hooded/ablative, -/obj/item/gun/energy/ionrifle, -/obj/item/gun/energy/temperature/security, -/obj/structure/reagent_dispensers/wall/peppertank/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) "bKs" = ( /obj/structure/table, /obj/item/fuel_pellet, @@ -8392,10 +8349,6 @@ /obj/structure/water_source/puddle, /turf/open/misc/asteroid, /area/station/security/prison/workout) -"bRE" = ( -/obj/structure/lattice/catwalk, -/turf/open/floor/plating/airless, -/area/station/solars/port) "bSd" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/large, @@ -8796,6 +8749,11 @@ /obj/effect/turf_decal/trimline/neutral/filled/line, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"bYc" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "bYd" = ( /obj/structure/chair/stool/bar/directional/south, /obj/effect/landmark/start/assistant, @@ -9558,17 +9516,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit) -"cko" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "ckr" = ( /obj/structure/table, /obj/item/assembly/timer{ @@ -10290,6 +10237,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/checker, /area/station/commons/lounge) +"cyj" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/obj/item/radio/intercom/directional/north, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/white, +/area/station/medical/surgery/aft) "cyq" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -10557,14 +10513,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/morgue) -"cCk" = ( -/obj/machinery/power/terminal{ - dir = 1 - }, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "cCr" = ( /obj/structure/cable, /obj/machinery/light/warm/directional/east, @@ -10578,6 +10526,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/prison) +"cDa" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, +/turf/open/openspace, +/area/station/maintenance/solars/port) "cDd" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, @@ -10951,14 +10907,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/service/bar/backroom) -"cIH" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing, -/obj/structure/railing{ - dir = 1 - }, -/turf/open/openspace, -/area/station/solars/starboard/fore) "cII" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -11077,6 +11025,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"cLR" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/railing{ + dir = 8 + }, +/turf/open/openspace, +/area/station/maintenance/solars/port) "cMa" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/machinery/camera/directional/south{ @@ -12232,12 +12191,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/cargo/drone_bay) -"deQ" = ( -/obj/structure/ladder, -/obj/effect/turf_decal/stripes/box, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "deU" = ( /obj/structure/closet/emcloset, /obj/machinery/light/dim/directional/west, @@ -12371,6 +12324,12 @@ }, /turf/open/floor/engine/vacuum, /area/station/engineering/atmos) +"dha" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/machinery/light/small/directional/west, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "dhg" = ( /obj/machinery/door/airlock{ name = "Private Quarters J"; @@ -12435,6 +12394,16 @@ }, /turf/open/floor/iron/dark, /area/station/commons/lounge) +"diW" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "djg" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -13984,13 +13953,14 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/circuit, /area/station/ai_monitored/turret_protected/ai) -"dMv" = ( -/obj/machinery/power/smes, -/obj/structure/cable, +"dMg" = ( +/turf/open/openspace, +/area/station/maintenance/solars/starboard/fore) +"dMr" = ( +/obj/structure/cable/layer1, /obj/effect/decal/cleanable/dirt, -/obj/machinery/light/dim/directional/south, /turf/open/floor/catwalk_floor, -/area/station/solars/port) +/area/station/maintenance/solars/port) "dMw" = ( /obj/machinery/door/airlock/hatch{ name = "Emergency Exit" @@ -14376,6 +14346,16 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/brig) +"dSs" = ( +/obj/structure/ladder, +/obj/effect/turf_decal/stripes/box, +/obj/structure/railing/corner{ + dir = 4 + }, +/obj/structure/railing/corner, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "dSy" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -14949,12 +14929,18 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics/garden) -"edx" = ( -/obj/effect/turf_decal/stripes/box, -/obj/structure/ladder, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/port) +"edC" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing/corner, +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/openspace, +/area/station/maintenance/solars/port) "edE" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner{ dir = 8 @@ -15148,6 +15134,18 @@ /obj/item/pen/red, /turf/open/floor/iron/dark, /area/station/security/courtroom/holding) +"eiZ" = ( +/obj/structure/cable/multilayer/multiz, +/obj/effect/turf_decal/stripes/box, +/obj/structure/railing/corner{ + dir = 8 + }, +/obj/structure/railing/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "eja" = ( /obj/structure/window/spawner/directional/south, /obj/structure/closet/crate, @@ -15509,12 +15507,6 @@ /obj/effect/landmark/navigate_destination/tcomms, /turf/open/floor/iron, /area/station/tcommsat/computer) -"eqJ" = ( -/obj/structure/cable/layer1, -/obj/structure/cable, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "eqK" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -16126,12 +16118,6 @@ /obj/structure/closet/secure_closet/personal, /turf/open/floor/iron, /area/station/commons/dorms) -"eBc" = ( -/obj/structure/cable/multilayer/multiz, -/obj/effect/turf_decal/stripes/box, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "eBd" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 9 @@ -16608,6 +16594,16 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/grimy, /area/station/service/library/lounge) +"eMH" = ( +/obj/structure/ladder, +/obj/effect/turf_decal/stripes/box, +/obj/structure/railing/corner, +/obj/structure/railing/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "eMT" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -16794,6 +16790,11 @@ /obj/effect/turf_decal/tile/purple/fourcorners, /turf/open/floor/iron/white, /area/station/science/research) +"eQc" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/south, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "eQm" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -16864,6 +16865,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/commons/vacant_room/commissary) +"eRe" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/east, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "eRi" = ( /obj/machinery/computer/prisoner/gulag_teleporter_computer{ dir = 4 @@ -17498,17 +17504,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/service/hydroponics) -"feN" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/solars/port) "feP" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 5 @@ -18482,11 +18477,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor, /area/station/hallway/secondary/exit) -"fvK" = ( -/obj/structure/cable/layer1, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "fvM" = ( /obj/structure/stairs/north, /turf/open/floor/iron/stairs/medium, @@ -19366,6 +19356,12 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/freezer, /area/station/commons/toilet) +"fNC" = ( +/obj/effect/turf_decal/stripes/box, +/obj/structure/ladder, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "fNR" = ( /obj/structure/closet/lasertag/blue, /obj/effect/landmark/start/hangover/closet, @@ -19610,11 +19606,6 @@ "fSr" = ( /turf/closed/wall, /area/station/security/checkpoint/arrivals) -"fSH" = ( -/obj/structure/cable/multilayer/connected, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "fSM" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 10 @@ -19923,6 +19914,10 @@ /obj/machinery/status_display/ai/directional/east, /turf/open/floor/circuit/green, /area/station/ai_monitored/turret_protected/ai_upload) +"fYB" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "fYW" = ( /obj/structure/grille, /obj/structure/lattice, @@ -20056,11 +20051,6 @@ /obj/effect/turf_decal/tile/neutral/tram, /turf/open/indestructible/tram/plate, /area/station/hallway/primary/tram/left) -"gbj" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "gbl" = ( /obj/structure/chair/office{ dir = 1 @@ -20158,6 +20148,19 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark, /area/station/service/hydroponics) +"gcJ" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "gdn" = ( /obj/machinery/air_sensor/nitrous_tank, /turf/open/floor/engine/n2o, @@ -21057,18 +21060,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"gtU" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/openspace, -/area/station/solars/starboard/fore) "gtZ" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/machinery/airalarm/directional/south, @@ -21117,6 +21108,17 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) +"guG" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "guI" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -21359,19 +21361,6 @@ /obj/effect/turf_decal/tile/purple/fourcorners, /turf/open/floor/iron/white, /area/station/science/research) -"gAC" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/solars/port) "gAH" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 1 @@ -21756,11 +21745,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"gGy" = ( -/obj/effect/turf_decal/sand/plating, -/obj/machinery/light/small/directional/south, -/turf/open/floor/plating/airless, -/area/station/solars/port) "gGV" = ( /obj/structure/table, /obj/item/instrument/harmonica, @@ -22186,6 +22170,12 @@ /obj/effect/mapping_helpers/airlock/unres, /turf/open/floor/iron/white/side, /area/station/science/research) +"gOX" = ( +/obj/item/storage/toolbox/electrical, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "gPA" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -22493,6 +22483,9 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/escapepodbay) +"gVY" = ( +/turf/closed/wall, +/area/station/solars/starboard/fore/asteriod) "gWd" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -23355,11 +23348,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"hlS" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "hmb" = ( /obj/effect/turf_decal/tile/bar{ dir = 8 @@ -24053,12 +24041,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) -"hDE" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/obj/structure/cable/layer1, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "hDF" = ( /obj/machinery/computer/apc_control{ dir = 1 @@ -26214,6 +26196,11 @@ }, /turf/open/floor/iron, /area/station/escapepodbay) +"itY" = ( +/obj/structure/cable, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "iub" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -26447,17 +26434,6 @@ /obj/machinery/status_display/evac/directional/east, /turf/open/floor/circuit/green, /area/station/ai_monitored/turret_protected/ai_upload) -"ixH" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/railing{ - dir = 8 - }, -/turf/open/space/openspace, -/area/space/nearstation) "ixO" = ( /obj/structure/chair/comfy/brown{ dir = 8; @@ -26772,6 +26748,11 @@ }, /turf/open/space/basic, /area/space/nearstation) +"iED" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "iEF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/circuit/telecomms, @@ -27797,17 +27778,6 @@ /obj/machinery/light/small/built/directional/north, /turf/open/floor/carpet, /area/station/commons/vacant_room/office) -"iXe" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/structure/cable, -/turf/open/openspace, -/area/station/solars/starboard/fore) "iXx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /obj/structure/lattice, @@ -28133,10 +28103,6 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/miningdock/oresilo) -"jcT" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/station/solars/port) "jde" = ( /obj/machinery/door/airlock/engineering{ name = "Vacant Office A" @@ -28332,12 +28298,6 @@ /obj/effect/mapping_helpers/airlock/access/all/science/xenobio, /turf/open/floor/engine, /area/station/science/xenobiology) -"jge" = ( -/obj/structure/cable/layer1, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "jgn" = ( /obj/structure/table/reinforced, /obj/structure/displaycase/forsale/kitchen{ @@ -28361,10 +28321,21 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"jgy" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "jgM" = ( /obj/structure/stairs/south, /turf/open/floor/iron/stairs/medium, /area/station/security/checkpoint/supply) +"jgQ" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/structure/cable/layer1, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "jha" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/trimline/neutral/filled/line{ @@ -30063,6 +30034,15 @@ }, /turf/open/floor/iron/checker, /area/station/commons/lounge) +"jJA" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "jJE" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -30220,6 +30200,13 @@ }, /turf/open/floor/iron/dark, /area/station/commons/lounge) +"jLR" = ( +/obj/machinery/power/smes, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/dim/directional/south, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "jLU" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/smart/simple/green/visible, @@ -30598,6 +30585,19 @@ /obj/machinery/atmospherics/pipe/bridge_pipe/dark/visible, /turf/open/space/basic, /area/space/nearstation) +"jUY" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "jVw" = ( /turf/open/floor/iron/white, /area/station/medical/medbay/central) @@ -31473,12 +31473,6 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) -"kgA" = ( -/obj/effect/turf_decal/stripes/box, -/obj/structure/cable/multilayer/multiz, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/port) "kgG" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -31902,10 +31896,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"koo" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "koq" = ( /obj/machinery/air_sensor/oxygen_tank, /turf/open/floor/engine/o2, @@ -32967,6 +32957,12 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/entry) +"kHb" = ( +/obj/structure/cable/multilayer/multiz, +/obj/effect/turf_decal/stripes/box, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "kHd" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -34033,6 +34029,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/virology) +"kXV" = ( +/obj/machinery/power/terminal, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "kXZ" = ( /obj/machinery/door/airlock{ name = "Private Quarters L"; @@ -34226,6 +34228,11 @@ "lbL" = ( /turf/open/floor/wood, /area/station/service/bar/backroom) +"lbM" = ( +/obj/structure/cable/multilayer/connected, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "lbZ" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -34499,11 +34506,6 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) -"lhT" = ( -/obj/structure/cable/multilayer/connected, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "lhV" = ( /obj/structure/displaycase/trophy, /obj/machinery/light/warm/directional/west, @@ -35161,12 +35163,6 @@ /obj/item/storage/box/drinkingglasses, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) -"lst" = ( -/obj/machinery/power/terminal, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "lsx" = ( /obj/structure/chair/stool/directional/north, /obj/effect/turf_decal/trimline/dark_blue/corner{ @@ -35585,15 +35581,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/tram/left) -"lzc" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "lzo" = ( /obj/machinery/door/window/left/directional/south, /turf/open/floor/grass, @@ -36322,11 +36309,6 @@ }, /turf/open/floor/iron/freezer, /area/station/commons/toilet) -"lMD" = ( -/obj/structure/cable/layer1, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "lMJ" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/turf_decal/siding/thinplating/dark{ @@ -36358,11 +36340,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/brig) -"lMS" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/turf/open/floor/plating/airless, -/area/station/solars/port) "lMZ" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 8 @@ -36740,6 +36717,9 @@ }, /turf/open/floor/iron, /area/station/security/prison/safe) +"lTs" = ( +/turf/closed/wall/r_wall, +/area/station/maintenance/solars/starboard/fore) "lTP" = ( /obj/structure/stairs/south, /turf/open/floor/iron/stairs/medium{ @@ -37272,6 +37252,10 @@ "mbJ" = ( /turf/closed/wall, /area/station/maintenance/tram/right) +"mbM" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "mbQ" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 4 @@ -37917,15 +37901,6 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/engineering/supermatter) -"mnp" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/solars/port) "mns" = ( /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 1 @@ -38029,6 +38004,18 @@ "mpd" = ( /turf/open/floor/engine/o2, /area/station/science/ordnance/storage) +"mpp" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing, +/obj/structure/railing/corner{ + dir = 4 + }, +/obj/structure/railing/corner{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/openspace, +/area/station/maintenance/solars/starboard/fore) "mpw" = ( /obj/machinery/hydroponics/soil, /turf/open/floor/grass, @@ -38195,6 +38182,9 @@ /obj/machinery/status_display/evac/directional/south, /turf/open/floor/carpet, /area/station/medical/psychology) +"msS" = ( +/turf/open/openspace, +/area/station/maintenance/solars/port) "msU" = ( /obj/structure/rack, /obj/effect/spawner/random/techstorage/tcomms_all, @@ -38289,16 +38279,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/tram/mid) -"muV" = ( -/obj/structure/cable, -/obj/machinery/power/solar_control{ - name = "Port Solar Control"; - dir = 1; - id = "portsolar" - }, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "muZ" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -38748,6 +38728,15 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/tram/right) +"mEo" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, +/obj/structure/cable, +/turf/open/openspace, +/area/station/maintenance/solars/starboard/fore) "mEs" = ( /turf/open/floor/iron/chapel{ dir = 10 @@ -38903,17 +38892,6 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/catwalk_floor, /area/station/hallway/primary/tram/center) -"mHm" = ( -/obj/effect/turf_decal/trimline/neutral/warning, -/obj/structure/table/reinforced, -/obj/item/table_clock{ - pixel_y = 8 - }, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/item/surgery_tray/full/morgue, -/obj/structure/window/reinforced/spawner/directional/west, -/turf/open/floor/iron/dark, -/area/station/medical/morgue) "mHt" = ( /obj/machinery/door/airlock/engineering{ name = "Tram Mechanical Room" @@ -39092,10 +39070,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/showroomfloor, /area/station/security/lockers) -"mJF" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "mJG" = ( /obj/structure/chair/stool/bar/directional/north, /obj/effect/turf_decal/siding/thinplating{ @@ -39113,17 +39087,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/brig) -"mKe" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/solars/port) "mKh" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -39190,6 +39153,11 @@ /obj/effect/turf_decal/trimline/blue/filled/corner, /turf/open/floor/iron/dark, /area/station/medical/storage) +"mLB" = ( +/obj/structure/cable/layer1, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "mLE" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -39530,6 +39498,14 @@ }, /turf/open/floor/engine/air, /area/station/engineering/atmos) +"mUm" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/openspace, +/area/station/maintenance/solars/starboard/fore) "mUu" = ( /obj/machinery/mass_driver/trash{ dir = 4 @@ -39584,19 +39560,6 @@ }, /turf/open/floor/plating, /area/station/science/ordnance) -"mWu" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/structure/cable, -/obj/structure/cable/layer1, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "mWC" = ( /obj/machinery/holopad, /obj/machinery/firealarm/directional/north, @@ -39924,11 +39887,6 @@ }, /turf/open/space/openspace, /area/station/solars/starboard/fore) -"ncE" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/station/solars/port) "ncF" = ( /turf/closed/wall, /area/station/maintenance/tram/left) @@ -39955,6 +39913,15 @@ name = "Holodeck Projector Floor" }, /area/station/holodeck/rec_center) +"ndg" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/machinery/power/solar{ + name = "Port Solar Array"; + id = "portsolar" + }, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "ndt" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/window/reinforced/spawner/directional/north, @@ -40045,18 +40012,6 @@ "ney" = ( /turf/open/floor/circuit/telecomms/mainframe, /area/station/tcommsat/server) -"neB" = ( -/obj/structure/cable/multilayer/multiz, -/obj/effect/turf_decal/stripes/box, -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "neC" = ( /obj/structure/railing{ dir = 1 @@ -40473,10 +40428,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/engineering/engine_smes) -"nkU" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "nle" = ( /obj/machinery/door/airlock/security{ name = "Evidence Storage" @@ -40584,6 +40535,13 @@ /obj/machinery/light/small/dim/directional/east, /turf/open/floor/iron/freezer, /area/station/commons/toilet) +"nmo" = ( +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "nms" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41336,12 +41294,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/courtroom) -"nzN" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/obj/structure/cable/layer1, -/turf/open/floor/plating/airless, -/area/station/solars/port) "nzO" = ( /mob/living/carbon/human/species/monkey, /turf/open/misc/dirt/jungle{ @@ -41361,6 +41313,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/cafeteria, /area/station/security/prison) +"nAl" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/openspace, +/area/station/maintenance/solars/starboard/fore) "nAB" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -42043,10 +42006,6 @@ /obj/structure/ladder, /turf/open/floor/iron/smooth, /area/station/maintenance/tram/mid) -"nNw" = ( -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "nNz" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -42079,9 +42038,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) -"nOd" = ( -/turf/open/openspace, -/area/station/solars/starboard/fore) "nOe" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 6 @@ -43128,6 +43084,13 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor, /area/station/maintenance/department/crew_quarters/dorms) +"ohM" = ( +/obj/machinery/power/smes, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/dim/directional/north, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "ohS" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -43255,18 +43218,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood/large, /area/station/service/library) -"ojP" = ( -/obj/structure/cable/multilayer/multiz, -/obj/effect/turf_decal/stripes/box, -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/structure/railing/corner{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/port) "ojQ" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/effect/turf_decal/trimline/blue/filled/corner{ @@ -44022,15 +43973,6 @@ /obj/machinery/light/small/dim/directional/east, /turf/open/floor/iron/freezer, /area/station/security/prison) -"oAg" = ( -/obj/machinery/power/solar_control{ - name = "Starboard Solar Control"; - id = "forestarboard" - }, -/obj/structure/cable, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "oAn" = ( /obj/machinery/airlock_sensor/incinerator_ordmix{ pixel_x = 23; @@ -45278,6 +45220,12 @@ "pbH" = ( /turf/closed/wall/r_wall, /area/station/science/server) +"pbI" = ( +/obj/structure/cable/layer1, +/obj/structure/cable, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "pbL" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/machinery/door/firedoor, @@ -45344,12 +45292,6 @@ /obj/structure/cable, /turf/open/floor/circuit, /area/station/ai_monitored/turret_protected/ai) -"pcZ" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable, -/obj/machinery/light/small/directional/west, -/turf/open/floor/plating/airless, -/area/station/solars/starboard/fore) "pdf" = ( /obj/machinery/camera/directional/north{ network = list("ss13","engineering","Security"); @@ -45662,6 +45604,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/checkpoint/arrivals) +"pjw" = ( +/turf/closed/wall, +/area/station/solars/port/asteriod) "pjC" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 9 @@ -45773,9 +45718,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/cargo/miningdock) -"plk" = ( -/turf/closed/wall/r_wall, -/area/station/solars/starboard/fore) "pln" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 8 @@ -46048,13 +45990,6 @@ }, /turf/open/floor/iron/grimy, /area/station/service/library/lounge) -"ppQ" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/obj/structure/cable, -/obj/machinery/light/floor, -/turf/open/floor/plating, -/area/station/solars/port) "ppU" = ( /obj/structure/railing, /obj/effect/turf_decal/trimline/tram/filled/line{ @@ -46966,6 +46901,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"pDP" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "pEa" = ( /obj/machinery/atmospherics/components/unary/passive_vent{ name = "killroom vent"; @@ -46980,6 +46919,12 @@ /obj/machinery/bluespace_vendor/directional/north, /turf/open/floor/iron, /area/station/hallway/secondary/exit) +"pEf" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/fish_mount/bar/directional/north, +/turf/open/floor/wood/large, +/area/station/service/theater) "pEx" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -47363,12 +47308,6 @@ /obj/structure/sign/poster/official/here_for_your_safety/directional/south, /turf/open/floor/iron/dark, /area/station/security/courtroom/holding) -"pKX" = ( -/obj/structure/cable, -/obj/structure/cable/layer1, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "pKZ" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -48154,15 +48093,6 @@ }, /turf/open/floor/iron/checker, /area/station/commons/lounge) -"pZG" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/turf/open/openspace, -/area/station/solars/port) "pZH" = ( /obj/structure/lattice/catwalk, /turf/open/space/basic, @@ -49051,6 +48981,10 @@ /obj/machinery/microwave, /turf/open/floor/iron/white, /area/station/commons/vacant_room) +"qoV" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "qoX" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 6 @@ -49854,15 +49788,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/cargo/miningdock) -"qCU" = ( -/obj/structure/lattice/catwalk, -/obj/machinery/power/solar{ - name = "Starboard Solar Array"; - id = "forestarboard" - }, -/obj/structure/cable, -/turf/open/space/basic, -/area/space/nearstation) "qCW" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -50682,6 +50607,17 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"qTJ" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "qTK" = ( /obj/structure/chair{ dir = 8 @@ -51045,17 +50981,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"qZq" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/railing{ - dir = 8 - }, -/turf/open/openspace, -/area/station/solars/port) +"qZj" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "qZx" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/effect/decal/cleanable/dirt, @@ -52207,6 +52136,17 @@ "rtp" = ( /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation/entertainment) +"rtF" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "run" = ( /turf/closed/wall/r_wall, /area/station/security/medical) @@ -52302,6 +52242,15 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/dark, /area/station/security/courtroom/holding) +"rvB" = ( +/obj/machinery/door/airlock/external{ + name = "Solar Maintenance" + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "rvH" = ( /obj/structure/fluff/tram_rail/electric/anchor{ dir = 1 @@ -52354,6 +52303,12 @@ }, /turf/open/floor/iron/white, /area/station/science/lower) +"rxv" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/structure/cable/layer1, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "rxw" = ( /obj/structure/girder, /obj/structure/grille, @@ -52414,6 +52369,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/station/hallway/primary/tram/right) +"ryc" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "ryn" = ( /obj/structure/lattice, /turf/open/openspace, @@ -53615,6 +53574,18 @@ "rUR" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/command/nuke_storage) +"rUX" = ( +/obj/structure/cable/multilayer/multiz, +/obj/effect/turf_decal/stripes/box, +/obj/structure/railing/corner{ + dir = 1 + }, +/obj/structure/railing/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "rUZ" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner, /obj/effect/turf_decal/trimline/yellow/filled/corner{ @@ -54021,6 +53992,15 @@ /obj/machinery/microwave, /turf/open/floor/iron/white/side, /area/station/service/kitchen) +"scW" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing, +/turf/open/openspace, +/area/station/maintenance/solars/port) "scZ" = ( /obj/structure/flora/bush/flowers_yw/style_random, /obj/structure/flora/bush/grassy/style_random, @@ -54163,14 +54143,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark/smooth_large, /area/station/cargo/bitrunning/den) -"sgf" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/turf/open/openspace, -/area/station/solars/port) "sgB" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/structure/cable, @@ -54685,6 +54657,14 @@ "soq" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/science) +"spk" = ( +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "spm" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/firedoor/heavy, @@ -54832,9 +54812,6 @@ }, /turf/closed/wall/r_wall, /area/station/engineering/supermatter/room) -"srF" = ( -/turf/open/openspace, -/area/station/solars/port) "srN" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/structure/cable, @@ -55248,6 +55225,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/service) +"sxq" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/west, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "sxA" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ @@ -55582,10 +55564,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"sEZ" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "sFc" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -55653,11 +55631,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/command) -"sGN" = ( -/obj/structure/cable, -/obj/machinery/light/floor, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "sGO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -58199,6 +58172,15 @@ }, /turf/open/floor/iron/white, /area/station/medical/virology) +"tAf" = ( +/obj/machinery/power/solar_control{ + name = "Starboard Solar Control"; + id = "forestarboard" + }, +/obj/structure/cable, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "tAo" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 @@ -58257,6 +58239,18 @@ /obj/machinery/transport/power_rectifier, /turf/open/floor/iron, /area/station/hallway/primary/tram/center) +"tAN" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/ablative, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/item/gun/energy/temperature/security, +/obj/structure/reagent_dispensers/wall/peppertank/directional/north, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/security/armory) "tBa" = ( /obj/structure/table, /obj/item/raw_anomaly_core/random{ @@ -59974,6 +59968,12 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) +"uhd" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "uhf" = ( /obj/machinery/door/firedoor/border_only, /obj/structure/cable, @@ -61848,16 +61848,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/tram/left) -"uHW" = ( -/obj/structure/ladder, -/obj/effect/turf_decal/stripes/box, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/structure/railing/corner, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/port) "uIk" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible, /obj/effect/turf_decal/trimline/purple/filled/line{ @@ -62295,13 +62285,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/engineering/gravity_generator) -"uPo" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/trimline/blue/filled/line, -/obj/item/radio/intercom/directional/south, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/fore) "uPv" = ( /obj/machinery/washing_machine, /turf/open/floor/iron/cafeteria, @@ -63599,11 +63582,6 @@ /obj/effect/landmark/navigate_destination/bar, /turf/open/floor/iron/dark, /area/station/service/bar) -"vnW" = ( -/obj/structure/cable/layer1, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "vob" = ( /obj/structure/bookcase/random/religion, /turf/open/floor/iron/dark, @@ -63891,6 +63869,13 @@ /obj/machinery/light/dim/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/tram/center) +"vrP" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/obj/structure/cable, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/station/maintenance/solars/port) "vrS" = ( /obj/machinery/vending/coffee, /obj/effect/turf_decal/tile/purple/fourcorners, @@ -64128,6 +64113,15 @@ }, /turf/open/floor/iron, /area/station/science/lower) +"vwk" = ( +/obj/machinery/power/solar{ + name = "Starboard Solar Array"; + id = "forestarboard" + }, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "vwq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -64159,11 +64153,6 @@ /obj/structure/railing/corner, /turf/open/space/openspace, /area/station/solars/starboard/fore) -"vwR" = ( -/obj/structure/cable, -/obj/machinery/light/floor, -/turf/open/floor/plating, -/area/station/solars/port) "vwT" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -64319,20 +64308,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/tcommsat/computer) -"vAj" = ( -/obj/structure/ladder, -/obj/effect/turf_decal/stripes/box, -/obj/structure/railing/corner, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) -"vAx" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/solars/port) "vAF" = ( /obj/structure/chair, /obj/effect/turf_decal/trimline/neutral/filled/line, @@ -65372,13 +65347,6 @@ /obj/machinery/modular_computer/preset/id, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) -"vTh" = ( -/obj/machinery/power/smes, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/dim/directional/north, -/turf/open/floor/catwalk_floor, -/area/station/solars/starboard/fore) "vTj" = ( /obj/effect/turf_decal/trimline/neutral/warning, /obj/machinery/door/window/brigdoor/left/directional/north{ @@ -65667,6 +65635,11 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"vZd" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/station/solars/port/asteriod) "vZB" = ( /obj/machinery/airalarm/directional/north, /turf/open/floor/wood/large, @@ -65683,15 +65656,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/service) -"vZX" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing, -/obj/structure/cable, -/turf/open/openspace, -/area/station/solars/starboard/fore) "vZZ" = ( /obj/machinery/duct, /obj/structure/cable, @@ -65892,6 +65856,17 @@ /obj/structure/sign/calendar/directional/east, /turf/open/floor/iron/cafeteria, /area/station/science/breakroom) +"wdx" = ( +/obj/effect/turf_decal/trimline/neutral/warning, +/obj/structure/table/reinforced, +/obj/item/table_clock{ + pixel_y = 8 + }, +/obj/structure/window/reinforced/spawner/directional/north, +/obj/effect/spawner/surgery_tray/full/morgue, +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/iron/dark, +/area/station/medical/morgue) "wdC" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, @@ -66449,6 +66424,11 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/station/ai_monitored/security/armory) +"wpq" = ( +/obj/structure/cable, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "wpu" = ( /obj/structure/table/glass, /obj/item/radio/intercom/directional/north, @@ -69768,10 +69748,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/checkpoint/medical) -"xCe" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/solars/port) "xCm" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/blue/anticorner/contrasted, @@ -69809,16 +69785,6 @@ /obj/structure/extinguisher_cabinet/directional/south, /turf/open/misc/asteroid/snow/coldroom, /area/station/service/kitchen/coldroom) -"xDy" = ( -/obj/machinery/door/airlock/external{ - name = "Solar Maintenance" - }, -/obj/structure/cable, -/obj/structure/cable/layer1, -/obj/effect/mapping_helpers/airlock/access/all/engineering/general, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/station/solars/starboard/fore) "xDJ" = ( /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/freezer, @@ -70051,6 +70017,9 @@ /obj/machinery/vending/wallmed/directional/north, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"xKt" = ( +/turf/closed/wall/r_wall, +/area/station/maintenance/solars/port) "xKB" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark, @@ -70408,6 +70377,11 @@ }, /turf/open/floor/glass/reinforced, /area/station/command/heads_quarters/rd) +"xPX" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable/layer1, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "xQv" = ( /turf/closed/wall/r_wall, /area/station/construction/mining/aux_base) @@ -70568,18 +70542,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/genetics) -"xTA" = ( -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/railing/corner, -/obj/structure/railing/corner{ - dir = 8 - }, -/turf/open/openspace, -/area/station/solars/port) "xTM" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/nitrogen_output{ dir = 1 @@ -70641,6 +70603,13 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/iron, /area/station/maintenance/tram/mid) +"xUY" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/trimline/blue/filled/line, +/obj/item/radio/intercom/directional/south, +/obj/effect/spawner/surgery_tray/full, +/turf/open/floor/iron/white, +/area/station/medical/surgery/fore) "xVp" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -70982,6 +70951,16 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/science) +"ybZ" = ( +/obj/structure/cable, +/obj/machinery/power/solar_control{ + name = "Port Solar Control"; + dir = 1; + id = "portsolar" + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) "ycg" = ( /obj/effect/landmark/start/station_engineer, /turf/open/floor/iron, @@ -70998,15 +70977,6 @@ }, /turf/open/floor/glass/reinforced, /area/station/security/brig) -"ycs" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 1 - }, -/obj/item/radio/intercom/directional/north, -/obj/item/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/aft) "yct" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 @@ -71326,6 +71296,12 @@ /obj/item/stack/package_wrap, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) +"yhI" = ( +/obj/structure/cable, +/obj/structure/cable/layer1, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "yhN" = ( /obj/machinery/holopad, /obj/effect/turf_decal/trimline/tram/filled/line{ @@ -71377,6 +71353,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/checkpoint/arrivals) +"yiB" = ( +/obj/structure/cable/multilayer/connected, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/starboard/fore) "yiI" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 4 @@ -71549,6 +71530,11 @@ }, /turf/open/floor/plating/airless, /area/station/science/ordnance/bomb) +"ylq" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/station/solars/starboard/fore/asteriod) "ylr" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/dim/directional/east, @@ -71591,6 +71577,11 @@ }, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"ymj" = ( +/obj/structure/cable/layer1, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/solars/port) (1,1,1) = {" vXM @@ -87703,13 +87694,13 @@ abM aaa aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg xRm xRm xRm @@ -87963,7 +87954,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -88218,11 +88209,11 @@ aaa aac aac aac -aek -ncE -jcT -jcT -aek +ndg +vZd +ryc +ryc +ndg aac aac vXM @@ -88477,7 +88468,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -88731,13 +88722,13 @@ aaa aaa aac aac -aek -jcT -jcT -jcT -jcT -jcT -aek +ndg +ryc +ryc +ryc +ryc +ryc +ndg aac aac vXM @@ -88991,7 +88982,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -89248,7 +89239,7 @@ aac aac aac aac -ncE +vZd aac aac aac @@ -89503,13 +89494,13 @@ aaa aaa aac aac -aek -ncE -ncE -ncE -jcT -jcT -aek +ndg +vZd +vZd +vZd +ryc +ryc +ndg xRm xRm xRm @@ -89763,7 +89754,7 @@ aac aac aac aac -ncE +vZd aac aac aac @@ -90018,11 +90009,11 @@ aaa aaa aac aac -aek -ncE -ncE -ncE -aek +ndg +vZd +vZd +vZd +ndg aac aac vXM @@ -90277,7 +90268,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -90531,13 +90522,13 @@ aaa aaa aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg aac vXM vXM @@ -90791,7 +90782,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -91048,8 +91039,8 @@ aac aac aac aac -gGy -qEH +eQc +pjw aac aac aac @@ -91303,13 +91294,13 @@ aaa aac aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg aac vXM vXM @@ -91563,7 +91554,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -91818,11 +91809,11 @@ aac aac aac aac -aek -jcT -jcT -jcT -aek +ndg +ryc +ryc +ryc +ndg aac aac vXM @@ -92077,7 +92068,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -92331,13 +92322,13 @@ aaa aac aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg xRm xRm xRm @@ -92591,7 +92582,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -92846,11 +92837,11 @@ aaa aac aac aac -ncE -ncE -ncE -jcT -jcT +vZd +vZd +vZd +ryc +ryc aac aac aac @@ -93102,16 +93093,16 @@ aaa aaa aac aac -ncE -ncE -aST -aST -aST -jcT -jcT -jcT +vZd +vZd +xKt +xKt +xKt +ryc +ryc +ryc aac -aek +ndg xRm xRm xRm @@ -93357,18 +93348,18 @@ abM abM aaa aac -ncE -ncE -ncE -aST -aST -edx -aST -aST -aST -jcT +vZd +vZd +vZd +xKt +xKt +fNC +xKt +xKt +xKt +ryc aac -jcT +ryc vXM rWa vXM @@ -93614,18 +93605,18 @@ abM aaa aaa aac -ncE -xCe -xCe -xCe -vnW -lMD -lMD -fSH -aST -jcT +vZd +aQS +aQS +aQS +ymj +dMr +dMr +lbM +xKt +ryc aac -jcT +ryc vXM oQf vXM @@ -93871,19 +93862,19 @@ aaa aaa aaa aac -ael -mKe -ppQ -gAC -eqJ -muV -lst -dMv -aST -ncE -ncE -ncE -bRE +uhd +guG +vrP +jUY +pbI +ybZ +kXV +jLR +xKt +vZd +vZd +vZd +ryc oQf oQf oQf @@ -94128,18 +94119,18 @@ aaa aaa aac aac -nzN -xCe -xCe -xCe -nNw -gbj -vAx -vAx -aST -ncE +jgQ +aQS +aQS +aQS +qoV +jgy +boa +boa +xKt +vZd aac -jcT +ryc vXM oQf vXM @@ -94385,18 +94376,18 @@ aac aac aac aac -nzN -ncE -ncE -aST -aST -kgA -aST -aST -aST -ncE +jgQ +vZd +vZd +xKt +xKt +aDO +xKt +xKt +xKt +vZd aac -jcT +ryc vXM rWa vXM @@ -94642,18 +94633,18 @@ aac aac aac aac -aem +gOX aac -ncE -ncE -aST -aST -aST -ncE -ncE -ncE +vZd +vZd +xKt +xKt +xKt +vZd +vZd +vZd aac -aek +ndg xRm xRm xRm @@ -94899,14 +94890,14 @@ aac aac aac aac -lMS +iED aac aac -ncE -ncE -ncE -ncE -ncE +vZd +vZd +vZd +vZd +vZd aac aac aac @@ -95154,9 +95145,9 @@ aac aac aac aac -jcT -lMS -lMS +iED +iED +iED aac aac aac @@ -107144,7 +107135,7 @@ aac aac aac aac -csA +gVY aac aac aac @@ -107398,13 +107389,13 @@ xRm xRm xRm aac -aam -hlS -hlS -pcZ -hlS -hlS -aam +vwk +ylq +ylq +dha +ylq +ylq +vwk aac aac aaa @@ -107658,7 +107649,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -107913,11 +107904,11 @@ vXM vXM aac aac -aam -hlS -hlS -hlS -aam +vwk +ylq +ylq +ylq +vwk aac aac aac @@ -108172,7 +108163,7 @@ aac aac aac aac -nkU +mbM aat aac aac @@ -108426,14 +108417,14 @@ vXM vXM vXM aac -aam -nkU -nkU -nkU -nkU -nkU -nkU -aam +vwk +mbM +mbM +mbM +mbM +mbM +mbM +vwk aac aac aaa @@ -108687,7 +108678,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -108942,11 +108933,11 @@ vXM vXM aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -109201,7 +109192,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -109455,14 +109446,14 @@ xRm xRm xRm aac -aam -hlS -nkU -nkU -nkU -nkU -hlS -aam +vwk +ylq +mbM +mbM +mbM +mbM +ylq +vwk aac aaa aaa @@ -109716,7 +109707,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -109971,11 +109962,11 @@ vXM vXM aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -110230,7 +110221,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -110484,14 +110475,14 @@ vXM vXM aac aac -aam -nkU -nkU -aau -nkU -nkU -hlS -aam +vwk +mbM +mbM +eRe +mbM +mbM +ylq +vwk aac aaa aaa @@ -110744,8 +110735,8 @@ aac aac aac aac -csA -nkU +gVY +mbM aac aac aac @@ -111002,7 +110993,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -111259,7 +111250,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -111514,11 +111505,11 @@ aac aac aac aac -nkU -nkU -nkU -nkU -nkU +mbM +mbM +mbM +mbM +mbM aac aac aac @@ -111769,14 +111760,14 @@ xRm aai aac aac -nkU -nkU -nkU -plk -plk -plk -nkU -nkU +mbM +mbM +mbM +lTs +lTs +lTs +mbM +mbM aac aac aaa @@ -112026,16 +112017,16 @@ vXM aac aac aac -nkU -plk -plk -plk -deQ -plk -plk -hlS -hlS -hlS +mbM +lTs +lTs +lTs +bvB +lTs +lTs +ylq +ylq +ylq aac aac aaa @@ -112283,16 +112274,16 @@ pdy aac aac aac -nkU -plk -lhT -fvK -fvK -jge -sEZ -sEZ -sEZ -hlS +mbM +lTs +yiB +mLB +mLB +bge +qZj +qZj +qZj +ylq aac aac aac @@ -112538,24 +112529,24 @@ pZH aev aev aev -hlS -hlS -hlS -plk -vTh -cCk -oAg -pKX -xDy -bsU -mWu -hDE -aaC -aaC -aaC -aaC -aaC -aaC +ylq +ylq +ylq +lTs +ohM +spk +tAf +yhI +diW +nmo +gcJ +rxv +xPX +xPX +xPX +xPX +xPX +xPX aac aaa aaa @@ -112797,22 +112788,22 @@ pdy pdy aac aac -hlS -plk -koo -koo -bck -mJF -sEZ -sEZ -sEZ -hlS +ylq +lTs +pDP +pDP +bYc +fYB +qZj +qZj +qZj +ylq aac aac aac aac aac -aaC +xPX aac aaa aac @@ -113046,7 +113037,7 @@ vXM pZH vXM vXM -qCU +bwp vXM vXM aev @@ -113054,22 +113045,22 @@ vXM vXM aac aac -hlS -plk -plk -plk -eBc -plk -plk -hlS -hlS -hlS +ylq +lTs +lTs +lTs +kHb +lTs +lTs +ylq +ylq +ylq aac aac aac aac aac -aaC +xPX aac aac aac @@ -113311,14 +113302,14 @@ xRm xRm xRm aai -hlS -hlS -nkU -plk -plk -plk -nkU -nkU +ylq +ylq +mbM +lTs +lTs +lTs +mbM +mbM aac aac aac @@ -113326,7 +113317,7 @@ aac aac aac aac -aaC +xPX aac aac aac @@ -113334,8 +113325,8 @@ aac aac aaa aaa -aaC -aaC +xPX +xPX aac aac aac @@ -113570,11 +113561,11 @@ vXM aac aac aac -nkU -nkU -nkU -nkU -nkU +mbM +mbM +mbM +mbM +mbM aac aac aac @@ -113583,15 +113574,15 @@ aac aac aac aac -aaC -aaC -aaC -aaC -aaC -aaC -aaC -aaC -aaC +xPX +xPX +xPX +xPX +xPX +xPX +xPX +xPX +xPX aac aac aac @@ -113829,7 +113820,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -114086,7 +114077,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -114343,8 +114334,8 @@ aac aac aac aac -hlS -csA +ylq +gVY aac aac aac @@ -114597,14 +114588,14 @@ vXM vXM aac aac -aam -hlS -hlS -hlS -aas -nkU -hlS -aam +vwk +ylq +ylq +ylq +sxq +mbM +ylq +vwk aac aac aac @@ -114858,7 +114849,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -115113,11 +115104,11 @@ vXM aac aac aac -aam -nkU -nkU -nkU -aam +vwk +mbM +mbM +mbM +vwk aac aac aac @@ -115372,7 +115363,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -115626,14 +115617,14 @@ xRm xRm aac aac -aam -hlS -hlS -hlS -nkU -nkU -nkU -aam +vwk +ylq +ylq +ylq +mbM +mbM +mbM +vwk aac aac aac @@ -115887,7 +115878,7 @@ aac aac aac aaw -nkU +mbM aac aac aac @@ -116142,11 +116133,11 @@ aac aac aac aac -aam -nkU -hlS -hlS -aam +vwk +mbM +ylq +ylq +vwk aac aac aac @@ -116401,7 +116392,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -116655,14 +116646,14 @@ vXM vXM aac aac -aam -nkU -nkU -hlS -nkU -nkU -nkU -aam +vwk +mbM +mbM +ylq +mbM +mbM +mbM +vwk aac aac aac @@ -116916,7 +116907,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -117171,11 +117162,11 @@ aac aac aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -117430,7 +117421,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -117684,13 +117675,13 @@ xRm aac aac aac -aam -nkU -nkU -aau -nkU -nkU -aam +vwk +mbM +mbM +eRe +mbM +mbM +vwk aac aac aac @@ -117944,7 +117935,7 @@ aac aac aac aac -csA +gVY aac aac aac @@ -155978,7 +155969,7 @@ dEv dEv dEv dEv -bKl +tAN oBY htq avg @@ -158640,9 +158631,9 @@ aac aac tMW tMW -aST -aST -aST +xKt +xKt +xKt mAG mAG mAG @@ -158896,12 +158887,12 @@ aac aac aac tMW -aST -aST -uHW -aST -aST -aST +xKt +xKt +dSs +xKt +xKt +xKt mAG mAG mAG @@ -159153,14 +159144,14 @@ aac aac lNm rLx -aST -srF -sgf -srF -srF -xCe -xCe -xCe +xKt +msS +cDa +msS +msS +aQS +aQS +aQS mAG pMW tMW @@ -159410,14 +159401,14 @@ aac aac fxW jQm -aST -srF -xTA -qZq -qZq -mnp -vwR -feN +xKt +msS +edC +cLR +cLR +jJA +itY +qTJ bME vKe kXk @@ -159667,14 +159658,14 @@ aac aac grc lfq -aST -srF -pZG -srF -srF -xCe -xCe -xCe +xKt +msS +scW +msS +msS +aQS +aQS +aQS tMW pMW tMW @@ -159683,7 +159674,7 @@ opb oOJ oOJ stK -ixH +gnp sOg oOJ uXM @@ -159924,12 +159915,12 @@ aac aac aac aac -aST -aST -ojP -aST -aST -aST +xKt +xKt +eiZ +xKt +xKt +xKt tMW tMW tMW @@ -160182,9 +160173,9 @@ aac aac aac aac -aST -aST -aST +xKt +xKt +xKt tMW tMW tMW @@ -166327,9 +166318,9 @@ hjz xRx aLw pVk -uPo +xUY xRx -ycs +cyj hou aNr apC @@ -171170,7 +171161,7 @@ eDV pnD iZn dME -evW +pEf sRA hrF wLd @@ -173517,7 +173508,7 @@ hiZ wTP sFA uKP -mHm +wdx qfS gNN whz @@ -177308,9 +177299,9 @@ saH uRv iCA iCA -plk -plk -plk +lTs +lTs +lTs fZL fZL pMW @@ -177564,11 +177555,11 @@ pMW iCA iCA iCA -plk -plk -vAj -plk -plk +lTs +lTs +eMH +lTs +lTs fZL pMW pMW @@ -177819,13 +177810,13 @@ uRv uRv uRv iCA -sEZ -sEZ -sEZ -nOd -cIH -nOd -plk +qZj +qZj +qZj +dMg +mUm +dMg +lTs uAZ hNg pMW @@ -178076,13 +178067,13 @@ viR viR viR bwT -lzc -sGN -cko -iXe -gtU -nOd -plk +rvB +wpq +rtF +nAl +mpp +dMg +lTs ceQ rNO pMW @@ -178333,13 +178324,13 @@ uRv uRv uRv iCA -sEZ -sEZ -sEZ -nOd -vZX -nOd -plk +qZj +qZj +qZj +dMg +mEo +dMg +lTs jPo mdl pMW @@ -178592,11 +178583,11 @@ pMW iCA iCA iCA -plk -plk -neB -plk -plk +lTs +lTs +rUX +lTs +lTs fZL pMW pMW @@ -178850,9 +178841,9 @@ uRv uRv iCA fZL -plk -plk -plk +lTs +lTs +lTs fZL fZL pMW diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index dafa2c4d1a09..6a10ba0e99ab 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -146,18 +146,6 @@ "acc" = ( /turf/closed/wall, /area/station/maintenance/central/lesser) -"aco" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hooded/ablative, -/obj/item/gun/energy/temperature/security, -/obj/item/gun/energy/ionrifle, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/ai_monitored/security/armory) "acA" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -554,6 +542,21 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/plating, /area/station/cargo/storage) +"ait" = ( +/obj/structure/table, +/obj/item/reagent_containers/cup/rag{ + pixel_x = -5; + pixel_y = 8 + }, +/obj/machinery/reagentgrinder{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/effect/turf_decal/tile/dark_red/opposingcorners, +/obj/machinery/light/directional/west, +/obj/structure/fish_mount/bar/directional/west, +/turf/open/floor/iron/dark, +/area/station/service/bar) "aiE" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, @@ -2163,13 +2166,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"aJM" = ( -/obj/machinery/light/small/directional/north, -/obj/item/surgery_tray/full/morgue{ - is_portable = 0 - }, -/turf/open/floor/iron/dark/textured, -/area/station/medical/morgue) "aJP" = ( /obj/machinery/door/airlock/external/glass{ name = "Mining Dock Airlock" @@ -4659,14 +4655,6 @@ /obj/item/clothing/neck/tie/black, /turf/open/floor/plating, /area/station/commons/vacant_room/commissary) -"bFP" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/item/ammo_casing/a357/spent, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron/white/small, -/area/station/science/lobby) "bFS" = ( /turf/open/openspace, /area/station/ai_monitored/turret_protected/aisat/foyer) @@ -5690,6 +5678,14 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark/textured_large, /area/station/ai_monitored/security/armory) +"caq" = ( +/obj/effect/spawner/surgery_tray/full/deployed, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/white/textured, +/area/station/medical/surgery/theatre) "cas" = ( /obj/effect/turf_decal/tile/dark_blue/half/contrasted, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6248,6 +6244,14 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/engine, /area/station/command/heads_quarters/captain/private) +"clA" = ( +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/effect/spawner/surgery_tray/full/deployed, +/obj/effect/turf_decal/tile/blue/full, +/obj/machinery/light_switch/directional/south, +/turf/open/floor/iron/white, +/area/station/medical/surgery) "clG" = ( /obj/machinery/duct, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -8069,6 +8073,14 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/xenobiology) +"cVt" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/item/ammo_casing/c357/spent, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/white/small, +/area/station/science/lobby) "cVL" = ( /obj/structure/closet/firecloset, /turf/open/floor/iron/textured, @@ -20253,6 +20265,15 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"hgA" = ( +/obj/structure/broken_flooring/pile{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/crowbar/large, +/turf/open/floor/plating, +/area/station/maintenance/department/medical/central) "hgB" = ( /obj/machinery/door/airlock/maintenance/external, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, @@ -21689,17 +21710,6 @@ dir = 8 }, /area/station/service/chapel) -"hGy" = ( -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/decal/cleanable/blood/tracks{ - dir = 4 - }, -/obj/item/ammo_casing/a357/spent, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse/upper) "hGB" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -34385,14 +34395,6 @@ /obj/machinery/light_switch/directional/west, /turf/open/floor/iron, /area/station/hallway/secondary/command) -"mhI" = ( -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/item/surgery_tray/full/deployed, -/obj/effect/turf_decal/tile/blue/full, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/white, -/area/station/medical/surgery) "mhO" = ( /obj/structure/table/reinforced, /obj/item/storage/box/beakers{ @@ -34664,6 +34666,17 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"mlh" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/item/ammo_casing/c357/spent, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse/upper) "mlk" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w, /turf/open/space/basic, @@ -34884,11 +34897,6 @@ /obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible, /turf/open/floor/iron, /area/station/engineering/atmos) -"moT" = ( -/obj/effect/turf_decal/siding/white, -/obj/item/ammo_casing/a357/spent, -/turf/open/floor/iron/white/small, -/area/station/science/lobby) "moU" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -36262,6 +36270,13 @@ /obj/machinery/light/directional/west, /turf/open/floor/catwalk_floor/iron_dark, /area/station/command/corporate_dock) +"mNQ" = ( +/obj/effect/spawner/surgery_tray/full/deployed, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/white/textured, +/area/station/medical/surgery/theatre) "mNZ" = ( /turf/closed/mineral/random/stationside/asteroid/porus, /area/station/asteroid) @@ -38133,14 +38148,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/glass/reinforced, /area/station/security/prison) -"nvT" = ( -/obj/item/surgery_tray/full/deployed, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron/white/textured, -/area/station/medical/surgery/theatre) "nwc" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/camera/autoname/directional/south, @@ -46861,6 +46868,11 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/station/security) +"qFa" = ( +/obj/effect/turf_decal/siding/white, +/obj/item/ammo_casing/c357/spent, +/turf/open/floor/iron/white/small, +/area/station/science/lobby) "qFj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/caution/stand_clear, @@ -56385,6 +56397,10 @@ /obj/machinery/telecomms/bus/preset_one, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) +"tOw" = ( +/obj/item/crowbar/large/old, +/turf/open/misc/asteroid, +/area/station/asteroid) "tOA" = ( /obj/machinery/door/airlock/highsecurity{ name = "Gravity Generator Room" @@ -56639,6 +56655,21 @@ /obj/machinery/duct, /turf/open/floor/iron/white/smooth_large, /area/station/medical/treatment_center) +"tTz" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/ablative, +/obj/item/gun/energy/temperature/security, +/obj/item/gun/energy/ionrifle, +/obj/item/gun/ballistic/automatic/battle_rifle{ + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/ai_monitored/security/armory) "tTE" = ( /obj/effect/landmark/start/hangover, /turf/open/floor/iron/showroomfloor, @@ -58321,13 +58352,6 @@ "uxt" = ( /turf/open/openspace, /area/station/hallway/secondary/exit/departure_lounge) -"uxw" = ( -/obj/item/surgery_tray/full/deployed, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/airalarm/directional/west, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron/white/textured, -/area/station/medical/surgery/theatre) "uxy" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/effect/decal/cleanable/dirt, @@ -63770,6 +63794,11 @@ "wxh" = ( /turf/open/openspace, /area/station/maintenance/central/greater) +"wxi" = ( +/obj/machinery/light/small/directional/north, +/obj/effect/spawner/surgery_tray/full/morgue/deployed, +/turf/open/floor/iron/dark/textured, +/area/station/medical/morgue) "wxk" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -63872,20 +63901,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/white, /area/station/security/prison/mess) -"wyj" = ( -/obj/structure/table, -/obj/item/reagent_containers/cup/rag{ - pixel_x = -5; - pixel_y = 8 - }, -/obj/machinery/reagentgrinder{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/dark_red/opposingcorners, -/obj/machinery/light/directional/west, -/turf/open/floor/iron/dark, -/area/station/service/bar) "wyl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -65379,10 +65394,6 @@ /obj/machinery/telecomms/message_server/preset, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) -"wZU" = ( -/obj/item/crowbar/large/heavy, -/turf/open/misc/asteroid, -/area/station/asteroid) "xad" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/science/robotics, @@ -68223,15 +68234,6 @@ }, /turf/open/floor/wood/tile, /area/station/service/bar) -"yaX" = ( -/obj/structure/broken_flooring/pile{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/mapping_helpers/broken_floor, -/obj/item/crowbar/large/heavy, -/turf/open/floor/plating, -/area/station/maintenance/department/medical/central) "ybh" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -80360,9 +80362,9 @@ rnk rnk xBS xBS -uxw +mNQ dBM -nvT +caq xBS tUo tUo @@ -80614,7 +80616,7 @@ dnO qvA qvA qvA -mhI +clA xBS nvp tZO @@ -92680,7 +92682,7 @@ uWr hRB hmg ghQ -wyj +ait xYz gqX qzu @@ -150756,7 +150758,7 @@ pCT ydC pWg jLV -hGy +mlh jpx aLE vOu @@ -150982,7 +150984,7 @@ fye uaT ccI cPP -aco +tTz hED vxX fYe @@ -151041,7 +151043,7 @@ xYG sQD kod iMq -aJM +wxi hru vIt vWH @@ -157730,7 +157732,7 @@ bzj eMq dwI uqI -yaX +hgA rnk cvn rnk @@ -168458,8 +168460,8 @@ hhX fYe fYe jam -bFP -moT +cVt +qFa wny gOc gOc @@ -168716,7 +168718,7 @@ fYe uif jam iBs -moT +qFa wny gOc gOc @@ -169287,7 +169289,7 @@ lQL pVB pHr mpc -wZU +tOw vxX vxX vxX diff --git a/_maps/modular_generic/ice_l_storage.dmm b/_maps/modular_generic/ice_l_storage.dmm index 6aca9bec648f..a130f69cdd1b 100644 --- a/_maps/modular_generic/ice_l_storage.dmm +++ b/_maps/modular_generic/ice_l_storage.dmm @@ -213,7 +213,7 @@ "M" = ( /obj/effect/turf_decal/bot/right, /obj/structure/closet/crate/large, -/obj/item/crowbar/large/heavy, +/obj/item/crowbar/large/twenty_force, /turf/open/floor/plating, /area/template_noop) "N" = ( diff --git a/_maps/modular_generic/station_l_morgue.dmm b/_maps/modular_generic/station_l_morgue.dmm index 4b4eb63458d1..3b5adf14d410 100644 --- a/_maps/modular_generic/station_l_morgue.dmm +++ b/_maps/modular_generic/station_l_morgue.dmm @@ -361,7 +361,7 @@ dir = 4 }, /obj/structure/table/reinforced/plastitaniumglass, -/obj/item/surgery_tray/full/morgue, +/obj/effect/spawner/surgery_tray/full/morgue, /obj/structure/railing{ dir = 4 }, diff --git a/_maps/shuttles/emergency_birdshot.dmm b/_maps/shuttles/emergency_birdshot.dmm index cdf903f03459..1cf44657848d 100644 --- a/_maps/shuttles/emergency_birdshot.dmm +++ b/_maps/shuttles/emergency_birdshot.dmm @@ -749,7 +749,7 @@ /area/shuttle/escape) "Ko" = ( /obj/structure/table/optable, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/mask/surgical, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/mineral/titanium/white, diff --git a/_maps/shuttles/emergency_donut.dmm b/_maps/shuttles/emergency_donut.dmm index f81c084e90bf..27f9cd7f1ace 100644 --- a/_maps/shuttles/emergency_donut.dmm +++ b/_maps/shuttles/emergency_donut.dmm @@ -317,7 +317,7 @@ /turf/open/floor/plating/airless, /area/shuttle/escape) "ed" = ( -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/suit/apron/surgical, /obj/item/clothing/mask/surgical, /obj/structure/table/optable, diff --git a/_maps/shuttles/emergency_fish.dmm b/_maps/shuttles/emergency_fish.dmm index b99aa01b096b..43ec2aa16201 100644 --- a/_maps/shuttles/emergency_fish.dmm +++ b/_maps/shuttles/emergency_fish.dmm @@ -844,7 +844,7 @@ /area/shuttle/escape) "VD" = ( /obj/structure/table/glass, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 6 }, /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ diff --git a/_maps/shuttles/emergency_humpback.dmm b/_maps/shuttles/emergency_humpback.dmm index 195f342cd3ca..89ab755acbf5 100644 --- a/_maps/shuttles/emergency_humpback.dmm +++ b/_maps/shuttles/emergency_humpback.dmm @@ -418,7 +418,7 @@ /area/shuttle/escape) "zn" = ( /obj/structure/table, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/iron/showroomfloor, /area/shuttle/escape) "zr" = ( diff --git a/_maps/shuttles/emergency_lance.dmm b/_maps/shuttles/emergency_lance.dmm index c17d1767b13a..2f62bc945bdd 100644 --- a/_maps/shuttles/emergency_lance.dmm +++ b/_maps/shuttles/emergency_lance.dmm @@ -62,7 +62,7 @@ /area/shuttle/escape) "bV" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/turf_decal/trimline/dark_blue/arrow_ccw{ dir = 8 @@ -125,7 +125,7 @@ /area/shuttle/escape) "dW" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -287,7 +287,7 @@ /area/shuttle/escape) "jo" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/turf_decal/trimline/dark_blue/arrow_ccw{ dir = 8 @@ -533,7 +533,7 @@ /area/shuttle/escape) "pu" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -573,7 +573,7 @@ /area/shuttle/escape) "qe" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/access/any/engineering/general, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -609,7 +609,7 @@ /area/shuttle/escape) "rw" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/access/any/engineering/general, /obj/effect/mapping_helpers/airlock/cyclelink_helper, @@ -682,7 +682,7 @@ /area/shuttle/escape) "uK" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -868,7 +868,7 @@ /area/shuttle/escape) "Cx" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -887,7 +887,7 @@ /area/shuttle/escape) "CR" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -968,8 +968,8 @@ /obj/item/book/manual/wiki/surgery{ pixel_x = -15 }, -/obj/item/surgery_tray/full, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full{ pixel_x = 5 }, /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ @@ -1199,7 +1199,7 @@ /area/shuttle/escape) "LD" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 diff --git a/_maps/shuttles/emergency_mini.dmm b/_maps/shuttles/emergency_mini.dmm index 73c5f42b38f0..89579283e931 100644 --- a/_maps/shuttles/emergency_mini.dmm +++ b/_maps/shuttles/emergency_mini.dmm @@ -227,7 +227,7 @@ "W" = ( /obj/structure/table, /obj/item/clothing/suit/apron/surgical, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/mineral/titanium/white, /area/shuttle/escape) "X" = ( diff --git a/_maps/shuttles/emergency_nature.dmm b/_maps/shuttles/emergency_nature.dmm index 0f793c714753..16e1b1072126 100644 --- a/_maps/shuttles/emergency_nature.dmm +++ b/_maps/shuttles/emergency_nature.dmm @@ -497,7 +497,7 @@ /area/shuttle/escape) "sF" = ( /obj/effect/turf_decal/trimline/blue/filled/line, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 5 }, /obj/structure/rack, diff --git a/_maps/shuttles/emergency_nebula.dmm b/_maps/shuttles/emergency_nebula.dmm index 7b729f72167f..39359e5c29e9 100644 --- a/_maps/shuttles/emergency_nebula.dmm +++ b/_maps/shuttles/emergency_nebula.dmm @@ -2447,7 +2447,7 @@ "XV" = ( /obj/structure/table/reinforced, /obj/item/radio/intercom/directional/east, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/machinery/defibrillator_mount/directional/south, /obj/machinery/light/small/directional/south, /turf/open/floor/iron/kitchen_coldroom/freezerfloor, diff --git a/_maps/shuttles/emergency_northstar.dmm b/_maps/shuttles/emergency_northstar.dmm index 798a4d9671a4..672dd9b58e23 100644 --- a/_maps/shuttles/emergency_northstar.dmm +++ b/_maps/shuttles/emergency_northstar.dmm @@ -127,7 +127,7 @@ "nC" = ( /obj/structure/table/reinforced/rglass, /obj/item/defibrillator/loaded, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 13 }, /obj/effect/turf_decal/tile/blue/anticorner{ diff --git a/_maps/shuttles/emergency_raven.dmm b/_maps/shuttles/emergency_raven.dmm index 7e3937568001..7eb255fc2d42 100644 --- a/_maps/shuttles/emergency_raven.dmm +++ b/_maps/shuttles/emergency_raven.dmm @@ -742,7 +742,7 @@ /area/shuttle/escape) "cd" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /turf/open/floor/plating, /area/shuttle/escape) @@ -1456,7 +1456,7 @@ /area/shuttle/escape) "eo" = ( /obj/machinery/door/airlock/external/ruin{ - name = "Emegency Shuttle External Airlock" + name = "Emergency Shuttle External Airlock" }, /obj/docking_port/mobile/emergency{ name = "CentCom Raven Cruiser" diff --git a/_maps/shuttles/emergency_russiafightpit.dmm b/_maps/shuttles/emergency_russiafightpit.dmm index 33baf94c7ecf..a00f6804bbcb 100644 --- a/_maps/shuttles/emergency_russiafightpit.dmm +++ b/_maps/shuttles/emergency_russiafightpit.dmm @@ -438,7 +438,7 @@ "iJ" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/gloves/fingerless, /turf/open/floor/iron, /area/shuttle/escape) diff --git a/_maps/shuttles/emergency_shadow.dmm b/_maps/shuttles/emergency_shadow.dmm index 5afa72919cb2..f5c2cd049f11 100644 --- a/_maps/shuttles/emergency_shadow.dmm +++ b/_maps/shuttles/emergency_shadow.dmm @@ -1000,7 +1000,7 @@ "Sb" = ( /obj/structure/table, /obj/structure/window/reinforced/spawner/directional/west, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/suit/apron/surgical, /obj/item/clothing/mask/surgical, /obj/item/clothing/gloves/latex/nitrile{ diff --git a/_maps/shuttles/emergency_tram.dmm b/_maps/shuttles/emergency_tram.dmm index 5ec40d242d67..38b2608865be 100644 --- a/_maps/shuttles/emergency_tram.dmm +++ b/_maps/shuttles/emergency_tram.dmm @@ -203,7 +203,7 @@ /area/shuttle/escape) "aX" = ( /obj/structure/table/optable, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/mask/surgical, /turf/open/floor/mineral/titanium/blue, /area/shuttle/escape) diff --git a/_maps/shuttles/emergency_tranquility.dmm b/_maps/shuttles/emergency_tranquility.dmm index ae3924becbc0..0de15be89cbc 100644 --- a/_maps/shuttles/emergency_tranquility.dmm +++ b/_maps/shuttles/emergency_tranquility.dmm @@ -2530,7 +2530,7 @@ /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/structure/table, /obj/item/lazarus_injector, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/item/clothing/gloves/latex/nitrile{ pixel_y = 4 }, diff --git a/_maps/shuttles/hunter_mi13_foodtruck.dmm b/_maps/shuttles/hunter_mi13_foodtruck.dmm index 34e6bb730ca6..4dca72eaae8c 100644 --- a/_maps/shuttles/hunter_mi13_foodtruck.dmm +++ b/_maps/shuttles/hunter_mi13_foodtruck.dmm @@ -15,7 +15,7 @@ /area/shuttle/hunter/mi13_foodtruck) "af" = ( /obj/structure/table/reinforced/plastitaniumglass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/structure/sign/poster/contraband/hacking_guide/directional/south, /turf/open/floor/circuit/red/off, /area/shuttle/hunter/mi13_foodtruck) diff --git a/_maps/shuttles/nova/emergency_nova.dmm b/_maps/shuttles/nova/emergency_nova.dmm index ead17d8442fe..f4e3ca09d123 100644 --- a/_maps/shuttles/nova/emergency_nova.dmm +++ b/_maps/shuttles/nova/emergency_nova.dmm @@ -96,7 +96,7 @@ /area/shuttle/escape) "gI" = ( /obj/structure/table/reinforced/rglass, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 8 }, /turf/open/floor/iron/dark/textured_large, diff --git a/_maps/shuttles/nova/emergency_outpost.dmm b/_maps/shuttles/nova/emergency_outpost.dmm index 7c210566e08f..b1952cb225b5 100644 --- a/_maps/shuttles/nova/emergency_outpost.dmm +++ b/_maps/shuttles/nova/emergency_outpost.dmm @@ -228,7 +228,7 @@ /area/shuttle/escape) "vD" = ( /obj/structure/table/glass, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /turf/open/floor/mineral/titanium/white, /area/shuttle/escape) "vI" = ( diff --git a/_maps/shuttles/nova/ruin_blackmarket_burst.dmm b/_maps/shuttles/nova/ruin_blackmarket_burst.dmm index a90680550933..77970728bade 100644 --- a/_maps/shuttles/nova/ruin_blackmarket_burst.dmm +++ b/_maps/shuttles/nova/ruin_blackmarket_burst.dmm @@ -69,10 +69,6 @@ }, /turf/open/floor/plating, /area/shuttle/blackmarket_burst) -"jK" = ( -/obj/structure/fluff/metalpole/end, -/turf/template_noop, -/area/template_noop) "ka" = ( /obj/structure/marker_beacon/burgundy, /turf/closed/wall/mineral/titanium, @@ -208,10 +204,18 @@ /obj/effect/mapping_helpers/airalarm/away_general_access, /turf/open/floor/iron/shuttle/ferry, /area/shuttle/blackmarket_burst) -"Dx" = ( +"CN" = ( +/obj/machinery/light/floor, +/obj/effect/turf_decal/siding/wideplating/dark{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, +/turf/open/floor/iron/shuttle/cargo, +/area/shuttle/blackmarket_burst) +"Dx" = ( /obj/machinery/button/door/directional/south{ id = "burstcargo"; name = "Blast Door Control" @@ -297,12 +301,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/shuttle/cargo, /area/shuttle/blackmarket_burst) -"MH" = ( -/obj/structure/fluff/metalpole/end{ - dir = 1 - }, -/turf/template_noop, -/area/template_noop) "NC" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/shuttle/ferry, @@ -317,7 +315,6 @@ /turf/open/floor/catwalk_floor, /area/shuttle/blackmarket_burst) "OR" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/siding/wideplating/dark/corner{ dir = 1 }, @@ -438,7 +435,7 @@ /area/shuttle/blackmarket_burst) (1,1,1) = {" -MH +Ov fp YP Ee @@ -483,7 +480,7 @@ Fr Vy JW lK -Vy +CN OR Ii zH @@ -551,6 +548,6 @@ YX en YX fp -jK +Ov Ov "} diff --git a/_maps/shuttles/nova/whiteship_blueshift.dmm b/_maps/shuttles/nova/whiteship_blueshift.dmm index 98b06ec62487..7cb2cf1eff4c 100644 --- a/_maps/shuttles/nova/whiteship_blueshift.dmm +++ b/_maps/shuttles/nova/whiteship_blueshift.dmm @@ -5366,7 +5366,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/structure/alien/weeds, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/iron, /area/shuttle/abandoned/medbay) "YN" = ( diff --git a/_maps/shuttles/ruin_cyborg_mothership.dmm b/_maps/shuttles/ruin_cyborg_mothership.dmm index ea07e4354de6..a0cb642c086a 100644 --- a/_maps/shuttles/ruin_cyborg_mothership.dmm +++ b/_maps/shuttles/ruin_cyborg_mothership.dmm @@ -709,7 +709,7 @@ /area/shuttle/ruin/cyborg_mothership) "Oq" = ( /obj/structure/table, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/effect/turf_decal/bot, /obj/structure/sink/directional/east, /obj/item/toy/figure/borg{ diff --git a/_maps/shuttles/whiteship_birdshot.dmm b/_maps/shuttles/whiteship_birdshot.dmm index ed1936e3a1cf..e076c841605c 100644 --- a/_maps/shuttles/whiteship_birdshot.dmm +++ b/_maps/shuttles/whiteship_birdshot.dmm @@ -146,7 +146,7 @@ pixel_y = 3 }, /obj/item/reagent_containers/blood, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_x = 2; pixel_y = 9 }, @@ -736,7 +736,6 @@ /turf/open/floor/iron/grimy, /area/shuttle/abandoned/crew) "yM" = ( -/obj/machinery/light/cold/directional/south, /obj/effect/decal/cleanable/dirt, /obj/machinery/light/broken/directional/south, /obj/machinery/firealarm/directional/east, @@ -1084,15 +1083,6 @@ }, /turf/open/floor/iron/small, /area/shuttle/abandoned/pod) -"Jk" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ - dir = 4 - }, -/turf/open/floor/iron/smooth_large, -/area/shuttle/abandoned/cargo) "Jn" = ( /obj/structure/dresser, /obj/effect/decal/cleanable/dirt, @@ -1712,7 +1702,7 @@ wE RX gV EX -Jk +Ui kQ Jn iS diff --git a/_maps/shuttles/whiteship_box.dmm b/_maps/shuttles/whiteship_box.dmm index ed2e2a17b907..9a20e38ebcd5 100644 --- a/_maps/shuttles/whiteship_box.dmm +++ b/_maps/shuttles/whiteship_box.dmm @@ -104,7 +104,7 @@ }, /obj/machinery/airalarm/directional/north, /obj/effect/mapping_helpers/airalarm/all_access, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 4 }, /obj/item/clothing/suit/apron/surgical, diff --git a/_maps/shuttles/whiteship_delta.dmm b/_maps/shuttles/whiteship_delta.dmm index f75f87001b51..e7981b169b8a 100644 --- a/_maps/shuttles/whiteship_delta.dmm +++ b/_maps/shuttles/whiteship_delta.dmm @@ -1621,7 +1621,7 @@ /area/shuttle/abandoned/medbay) "dO" = ( /obj/structure/table, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = 4 }, /obj/effect/decal/cleanable/dirt, diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index 410cad31a81c..659a066347b5 100644 --- a/_maps/templates/battlecruiser_starfury.dmm +++ b/_maps/templates/battlecruiser_starfury.dmm @@ -4752,7 +4752,7 @@ "Gz" = ( /obj/structure/cable, /mob/living/basic/bot/medbot{ - desc = "A medical bot of syndicate origins. Probably plots about how to stab you full of toxins in its free time."; + desc = "A medical bot of syndicate origins. Probably plots about stabbing you full of toxins in its free time."; faction = list("neutral","silicon","turret","Syndicate"); name = "Syndicate Medibot"; skin = "bezerk"; diff --git a/_maps/templates/holodeck_medicalsim.dmm b/_maps/templates/holodeck_medicalsim.dmm index 7e4162ce074a..269b9c41f017 100644 --- a/_maps/templates/holodeck_medicalsim.dmm +++ b/_maps/templates/holodeck_medicalsim.dmm @@ -109,10 +109,12 @@ /area/template_noop) "gr" = ( /obj/structure/table/glass, -/obj/item/retractor, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/item/stack/medical/gauze, +/obj/item/retractor, +/obj/item/cautery, /turf/open/floor/holofloor{ icon_state = "white" }, @@ -467,12 +469,10 @@ }, /area/template_noop) "Qu" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/gauze, -/obj/item/cautery, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/structure/closet/crate/freezer/organ, /turf/open/floor/holofloor{ icon_state = "white" }, diff --git a/_maps/templates/lazy_templates/ninja_den.dmm b/_maps/templates/lazy_templates/ninja_den.dmm index 5d5acde1c35f..cfbae9388bf7 100644 --- a/_maps/templates/lazy_templates/ninja_den.dmm +++ b/_maps/templates/lazy_templates/ninja_den.dmm @@ -1081,7 +1081,6 @@ /obj/machinery/vending/coffee{ default_price = 0; extra_price = 0; - fair_market_price = 0; name = "\improper Jim Norton's Quebecois Coffee" }, /turf/open/floor/wood/large, @@ -1689,7 +1688,7 @@ /area/centcom/central_command_areas/holding) "Mz" = ( /obj/structure/closet, -/obj/item/surgery_tray/full, +/obj/effect/spawner/surgery_tray/full, /obj/machinery/iv_drip, /obj/item/emergency_bed, /obj/item/storage/medkit/regular, diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm index e0d583c0521c..128f0e3e256f 100644 --- a/_maps/templates/lazy_templates/nukie_base.dmm +++ b/_maps/templates/lazy_templates/nukie_base.dmm @@ -68,6 +68,17 @@ /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 8 }, +/obj/structure/closet/syndicate/personal, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, +/obj/item/reagent_containers/cup/beaker/large, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/expansion_chemicalwarfare) "bo" = ( @@ -111,7 +122,7 @@ dir = 5 }, /obj/structure/table/reinforced/plasmarglass, -/obj/item/surgery_tray/full{ +/obj/effect/spawner/surgery_tray/full{ pixel_y = -11 }, /obj/item/storage/belt/medical, diff --git a/_maps/virtual_domains/ancientmilsim_nova.dmm b/_maps/virtual_domains/ancientmilsim_nova.dmm index eaaa5b13d10f..6d9e4b02b74f 100644 --- a/_maps/virtual_domains/ancientmilsim_nova.dmm +++ b/_maps/virtual_domains/ancientmilsim_nova.dmm @@ -714,7 +714,7 @@ /turf/open/floor/plating, /area/virtual_domain/ancient_milsim/janitor) "tA" = ( -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/iron/white, /area/virtual_domain/ancient_milsim/medbay) "tH" = ( diff --git a/_maps/virtual_domains/island_brawl.dmm b/_maps/virtual_domains/island_brawl.dmm index 62a63f81bab2..f1f291b152a2 100644 --- a/_maps/virtual_domains/island_brawl.dmm +++ b/_maps/virtual_domains/island_brawl.dmm @@ -854,10 +854,6 @@ }, /turf/open/floor/plating, /area/virtual_domain) -"kI" = ( -/obj/effect/turf_decal/sand, -/turf/closed/wall/mineral/wood, -/area/virtual_domain) "kJ" = ( /obj/machinery/shower/directional/south, /obj/effect/turf_decal/siding/wood{ @@ -3177,10 +3173,6 @@ }, /turf/open/floor/iron/white/textured_large, /area/virtual_domain) -"NZ" = ( -/obj/effect/turf_decal/sand, -/turf/closed/wall/mineral/wood, -/area/virtual_domain/fullbright) "Of" = ( /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ pixel_x = -17; @@ -7866,9 +7858,9 @@ bX ev ka ka -NZ -NZ -eK +Bq +Bq +Bq JN JN ka @@ -7948,7 +7940,7 @@ bX Yo sz ka -NZ +Bq YI LD JN @@ -8030,9 +8022,9 @@ Yo Yo sz ka -NZ -kI -eK +Bq +Bq +Bq JN JN ka @@ -8112,7 +8104,7 @@ Yo ka ka ka -NZ +Bq Qk Uf JN @@ -8194,9 +8186,9 @@ ka th ka eK -kI -kI -eK +Bq +Bq +Bq JN JN ka @@ -8276,7 +8268,7 @@ ka ka ka ka -NZ +Bq ZB sa JN @@ -8358,9 +8350,9 @@ ka ka ka ka -eK -eK -eK +Bq +Bq +Bq JN JN ka @@ -11225,8 +11217,8 @@ cO oa th ka -NZ -NZ +eK +eK eK ka ka @@ -11307,7 +11299,7 @@ cO wb MT ka -NZ +eK EA xe ka diff --git a/_maps/virtual_domains/meta_central.dmm b/_maps/virtual_domains/meta_central.dmm index 2fc87ae17c81..3fc4ed7f21e1 100644 --- a/_maps/virtual_domains/meta_central.dmm +++ b/_maps/virtual_domains/meta_central.dmm @@ -4780,7 +4780,7 @@ "NO" = ( /obj/machinery/airalarm/directional/west, /obj/structure/broken_flooring/singular/always_floorplane/directional/east, -/obj/item/surgery_tray/full/deployed, +/obj/effect/spawner/surgery_tray/full/deployed, /turf/open/floor/plating, /area/virtual_domain) "NR" = ( diff --git a/_maps/virtual_domains/stairs_and_cliffs.dmm b/_maps/virtual_domains/stairs_and_cliffs.dmm index 4c1d364d7778..e95f96ffe516 100644 --- a/_maps/virtual_domains/stairs_and_cliffs.dmm +++ b/_maps/virtual_domains/stairs_and_cliffs.dmm @@ -233,7 +233,7 @@ "KA" = ( /obj/structure/statue/snow/snowman{ name = "Norm"; - desc = "Norm has seen many a man roll down these cliffs, some more stubborn than others. Its usually the stubborn ones who stop getting back up." + desc = "Norm has seen many a man roll down these cliffs, some more stubborn than others. It's usually the stubborn ones who stop getting back up." }, /obj/item/pickaxe/mini, /turf/open/misc/asteroid/snow, diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index 9b3b239034b9..4dff2007b39e 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -142,6 +142,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define NO_BOH (1<<18) /// This area prevents fishing from removing unique/limited loot from sources that're also used outside of it. #define UNLIMITED_FISHING (1<<19) +/// This area is prevented from having gravity (ie. space, nearstation, or outside solars) +#define NO_GRAVITY (1<<20) /* These defines are used specifically with the atom/pass_flags bitmask diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 3e6a48ed561e..49fdae0f23ed 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -48,40 +48,40 @@ #define R_EVERYTHING (1<<15)-1 //the sum of all other rank permissions, used for +EVERYTHING -#define ADMIN_QUE(user) "(?)" -#define ADMIN_FLW(user) "(FLW)" -#define ADMIN_PP(user) "(PP)" -#define ADMIN_VV(atom) "(VV)" -#define ADMIN_SM(user) "(SM)" -#define ADMIN_TP(user) "(TP)" -#define ADMIN_SP(user) "(SP)" -#define ADMIN_KICK(user) "(KICK)" -#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" -#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" -#define ADMIN_SC(user) "(SC)" -#define ADMIN_SMITE(user) "(SMITE)" +#define ADMIN_QUE(user) "(?)" +#define ADMIN_FLW(user) "(FLW)" +#define ADMIN_PP(user) "(PP)" +#define ADMIN_VV(atom) "(VV)" +#define ADMIN_SM(user) "(SM)" +#define ADMIN_TP(user) "(TP)" +#define ADMIN_SP(user) "(SP)" +#define ADMIN_KICK(user) "(KICK)" +#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" +#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" +#define ADMIN_SC(user) "(SC)" +#define ADMIN_SMITE(user) "(SMITE)" #define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]" #define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]" -#define ADMIN_SET_SD_CODE "(SETCODE)" +#define ADMIN_SET_SD_CODE "(SETCODE)" #define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" #define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" -#define ADMIN_JMP(src) "(JMP)" +#define ADMIN_JMP(src) "(JMP)" #define COORD(src) "[src ? src.Admin_Coordinates_Readable() : "nonexistent location"]" #define AREACOORD(src) "[src ? src.Admin_Coordinates_Readable(TRUE) : "nonexistent location"]" #define ADMIN_COORDJMP(src) "[src ? src.Admin_Coordinates_Readable(FALSE, TRUE) : "nonexistent location"]" #define ADMIN_VERBOSEJMP(src) "[src ? src.Admin_Coordinates_Readable(TRUE, TRUE) : "nonexistent location"]" -#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" -#define ADMIN_TAG(datum) "(TAG)" -#define ADMIN_LUAVIEW(state) "(VIEW STATE)" -#define ADMIN_LUAVIEW_CHUNK(state, log_index) "(VIEW CODE)" +#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" +#define ADMIN_TAG(datum) "(TAG)" +#define ADMIN_LUAVIEW(state) "(VIEW STATE)" +#define ADMIN_LUAVIEW_CHUNK(state, log_index) "(VIEW CODE)" /// Displays "(SHOW)" in the chat, when clicked it tries to show atom(paper). First you need to set the request_state variable to TRUE for the paper. -#define ADMIN_SHOW_PAPER(atom) "(SHOW)" +#define ADMIN_SHOW_PAPER(atom) "(SHOW)" /// Displays "(PRINT)" in the chat, when clicked it will try to print the atom(paper) on the CentCom/Syndicate fax machine. -#define ADMIN_PRINT_FAX(atom, sender, destination) "(PRINT)" +#define ADMIN_PRINT_FAX(atom, sender, destination) "(PRINT)" /// Displays "(PLAY)" in the chat, when clicked it tries to play internet sounds from the request. -#define ADMIN_PLAY_INTERNET(text, credit) "(PLAY)" +#define ADMIN_PLAY_INTERNET(text, credit) "(PLAY)" /// Displays "(SEE Z-LEVEL LAYOUT)" in the chat, when clicked it shows the z-level layouts for the current world state. -#define ADMIN_SEE_ZLEVEL_LAYOUT "(SEE Z-LEVEL LAYOUT)" +#define ADMIN_SEE_ZLEVEL_LAYOUT "(SEE Z-LEVEL LAYOUT)" /atom/proc/Admin_Coordinates_Readable(area_name, admin_jump_ref) var/turf/turf_at_coords = Safe_COORD_Location() diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index b5a7ad1ddfaa..f7f77a7169ea 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -195,6 +195,14 @@ #define BB_DRILLABLE_ICE "BB_drillable_ice" +//emotions we displays depending on our happiness +///emotions we display when happy +#define BB_HAPPY_EMOTIONS "happy_emotions" +///emotions we display when neutral +#define BB_MODERATE_EMOTIONS "moderate_emotions" +///emotions we display when depressed +#define BB_SAD_EMOTIONS "sad_emotions" + // Keys used by one and only one behavior // Used to hold state without making bigass lists /// For /datum/ai_behavior/find_potential_targets, what if any field are we using currently diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 330e2d48eb22..d77817a20398 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -304,3 +304,11 @@ #define BB_DEER_RESTING "deer_resting" ///time till our next rest duration #define BB_DEER_NEXT_REST_TIMER "deer_next_rest_timer" + +//turtle +///our tree's ability +#define BB_TURTLE_TREE_ABILITY "turtle_tree_ability" +///people we headbutt! +#define BB_TURTLE_HEADBUTT_VICTIM "turtle_headbutt_victim" +///flore we must smell +#define BB_TURTLE_FLORA_TARGET "turtle_flora_target" diff --git a/code/__DEFINES/ai/pets.dm b/code/__DEFINES/ai/pets.dm index 6af24b6cdd97..067569a8a9ac 100644 --- a/code/__DEFINES/ai/pets.dm +++ b/code/__DEFINES/ai/pets.dm @@ -19,6 +19,8 @@ #define BB_BABIES_CHILD_TYPES "BB_babies_child" ///Current partner target #define BB_BABIES_TARGET "BB_babies_target" +///Timeout for finding partners when theres too many of us in 1 location +#define BB_PARTNER_SEARCH_TIMEOUT "BB_partner_search_timeout" ///Finding adult mob ///key holds the adult we found diff --git a/code/__DEFINES/anomaly.dm b/code/__DEFINES/anomaly.dm index 7422af3fc65d..6ca1db70678d 100644 --- a/code/__DEFINES/anomaly.dm +++ b/code/__DEFINES/anomaly.dm @@ -4,7 +4,7 @@ */ ///Time in ticks before the anomaly goes poof/explodes depending on type. -#define ANOMALY_COUNTDOWN_TIMER (99 SECONDS) +#define ANOMALY_COUNTDOWN_TIMER (120 SECONDS) /** * Nuisance/funny anomalies diff --git a/code/__DEFINES/bodyparts.dm b/code/__DEFINES/bodyparts.dm index 34a26376e2f6..5b55de283788 100644 --- a/code/__DEFINES/bodyparts.dm +++ b/code/__DEFINES/bodyparts.dm @@ -47,4 +47,6 @@ // Color priorities for bodyparts #define LIMB_COLOR_HULK 10 #define LIMB_COLOR_CARP_INFUSION 20 +/// Base priority for atom colors, gets atom priorities added to it +#define LIMB_COLOR_ATOM_COLOR 30 #define LIMB_COLOR_SYNTH 100 // NOVA EDIT ADDITION - High priority diff --git a/code/__DEFINES/chat.dm b/code/__DEFINES/chat.dm index 516fe8c4e193..21901a934456 100644 --- a/code/__DEFINES/chat.dm +++ b/code/__DEFINES/chat.dm @@ -11,6 +11,7 @@ #define MESSAGE_TYPE_SYSTEM "system" #define MESSAGE_TYPE_LOCALCHAT "localchat" #define MESSAGE_TYPE_RADIO "radio" +#define MESSAGE_TYPE_ENTERTAINMENT = "entertainment" #define MESSAGE_TYPE_INFO "info" #define MESSAGE_TYPE_WARNING "warning" #define MESSAGE_TYPE_DEADCHAT "deadchat" @@ -44,9 +45,11 @@ /// Used for debug messages to the server #define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]") /// Adds a generic box around whatever message you're sending in chat. Really makes things stand out. -#define examine_block(str) ("
" + str + "
") -/// Makes a fieldset with a name in the middle top part. Can apply additional classes -#define fieldset_block(title, content, classes) ("
" + title + "
" + content + "
") +#define boxed_message(str) ("
" + str + "
") +/// Adds a box around whatever message you're sending in chat. Can apply color and/or additional classes. Available colors: red, green, blue, purple. Use it like red_box +#define custom_boxed_message(classes, str) ("
" + str + "
") +/// Makes a fieldset with a neaty styled name. Can apply additional classes. +#define fieldset_block(title, content, classes) ("
" + title + "" + content + "
") /// Makes a horizontal line with text in the middle #define separator_hr(str) ("
" + str + "
") /// Emboldens runechat messages diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index d1fff3b20edf..823f49b38925 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -11,6 +11,19 @@ #define FIXED_COLOUR_PRIORITY 4 ///how many colour priority levels there are. #define COLOUR_PRIORITY_AMOUNT 4 +/// If this is a plain atom color +#define ATOM_COLOR_TYPE_NORMAL "normal" +/// If this is a color filter +#define ATOM_COLOR_TYPE_FILTER "filter" +// Indexes for color arrays +#define ATOM_COLOR_VALUE_INDEX 1 +#define ATOM_COLOR_TYPE_INDEX 2 +#define ATOM_PRIORITY_COLOR_FILTER "atom_priority_color" +#define ATOM_PRIORITY_COLOR_FILTER_PRIORITY -1 +/// Multiply pixel's saturation by color's saturation. Paints accents while keeping dim areas dim. +#define SATURATION_MULTIPLY "multiply" +/// Always affects the original pixel's saturation and lightness. +#define SATURATION_OVERRIDE "always" #define COLOR_DARKMODE_BACKGROUND "#202020" #define COLOR_DARKMODE_DARKBACKGROUND "#171717" @@ -455,6 +468,8 @@ GLOBAL_LIST_INIT(heretic_path_to_color, list( // Lowest priority #define EYE_COLOR_ORGAN_PRIORITY 1 +/// Base priority for atom colors, gets atom priorities added to it +#define EYE_COLOR_ATOM_COLOR_PRIORITY 2 #define EYE_COLOR_SPECIES_PRIORITY 10 #define EYE_COLOR_WEED_PRIORITY 20 #define EYE_COLOR_CULT_PRIORITY 30 diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 60b4130a244a..867d8a51d416 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -98,6 +98,7 @@ DEFINE_BITFIELD(status_flags, list( #define CLICK_CD_RAPID 2 #define CLICK_CD_HYPER_RAPID 1 #define CLICK_CD_SLOW 10 +#define CLICK_CD_ACTIVATE_ABILITY 1 #define CLICK_CD_THROW 8 #define CLICK_CD_RANGE 4 @@ -154,6 +155,13 @@ DEFINE_BITFIELD(status_flags, list( #define ATTACK_EFFECT_MECHTOXIN "mech_toxin" #define ATTACK_EFFECT_BOOP "boop" //Honk +/// Attack animation for sharp items +#define ATTACK_ANIMATION_SLASH "slash" +/// Attack animation for pointy items +#define ATTACK_ANIMATION_PIERCE "pierce" +/// Animation for blunt attacks +#define ATTACK_ANIMATION_BLUNT "blunt" + //the define for visible message range in combat #define SAMETILE_MESSAGE_RANGE 1 #define COMBAT_MESSAGE_RANGE 3 @@ -183,8 +191,11 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define EMBED_CHANCE_SPEED_BONUS 10 //Gun weapon weight +/// Default normal ol' gun. Akimboable, one handed. #define WEAPON_LIGHT 1 +/// Can't be used akimbo, but only needs one hand to fire #define WEAPON_MEDIUM 2 +/// Can't be used akimbo, and needs two hands to fire #define WEAPON_HEAVY 3 //Gun trigger guards #define TRIGGER_GUARD_ALLOW_ALL -1 diff --git a/code/__DEFINES/construction/rcd.dm b/code/__DEFINES/construction/rcd.dm index a8d98215af1d..4f898d5ae86e 100644 --- a/code/__DEFINES/construction/rcd.dm +++ b/code/__DEFINES/construction/rcd.dm @@ -51,3 +51,6 @@ #define RCD_MEMORY_COST_BUFF 8 /// If set to TRUE in rcd_vals, will bypass the cooldown on slowing down frequent use #define RCD_RESULT_BYPASS_FREQUENT_USE_COOLDOWN "bypass_frequent_use_cooldown" + +/// How much longer does it take to deconstruct rwalls? +#define RCD_RWALL_DELAY_MULT 2 diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index 2e42957aa3a0..586a67e23954 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -145,3 +145,6 @@ /// From whoever has been revealed (atom/revealed) #define COMSIG_ATOM_REVEAL "atom_reveal" + +/// From /atom/proc/set_density(new_value) for when an atom changes density +#define COMSIG_ATOM_DENSITY_CHANGED "atom_density_change" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm index bedfaf2fa037..bb5b344a89a4 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm @@ -92,3 +92,6 @@ /// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target #define COMSIG_ATOM_SABOTEUR_ACT "hit_by_saboteur" #define COMSIG_SABOTEUR_SUCCESS 1 + +/// signal sent when a mouse is hovering over us, sent by atom/proc/on_mouse_entered +#define COMSIG_ATOM_MOUSE_ENTERED "mouse_entered" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index ba43900425bd..3569b9af1e61 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -244,6 +244,7 @@ ///from /mob/living/proc/check_block(): (atom/hit_by, damage, attack_text, attack_type, armour_penetration, damage_type) #define COMSIG_LIVING_CHECK_BLOCK "living_check_block" + #define FAILED_BLOCK NONE #define SUCCESSFUL_BLOCK (1<<0) ///Hit by successful disarm attack (mob/living/attacker, zone_targeted, item/weapon) @@ -287,6 +288,8 @@ /// From /datum/element/basic_eating/finish_eating() #define COMSIG_MOB_ATE "mob_ate" + ///cancel post eating + #define COMSIG_MOB_TERMINATE_EAT (1<<0) ///From mob/living/carbon/proc/throw_mode_on and throw_mode_off #define COMSIG_LIVING_THROW_MODE_TOGGLE "living_throw_mode_toggle" diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 7e7a5f17837a..a83badb9ee06 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -546,3 +546,11 @@ ///Sent from /obj/item/skillchip/on_remove() #define COMSIG_SKILLCHIP_REMOVED "skillchip_removed" + +/// from /obj/machinery/computer/camera_advanced/shuttle_docker/gatherNavComputerOverlays() : (list/images_out) +#define COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED "shuttle_nav_computer_image_requested" + +/// Sent from /obj/item/organ/wings/functional/proc/open_wings(): (mob/living/carbon/owner) +#define COMSIG_WINGS_OPENED "wings_opened" +/// Sent from /obj/item/organ/wings/functional/proc/close_wings(): (mob/living/carbon/owner) +#define COMSIG_WINGS_CLOSED "wings_closed" diff --git a/code/__DEFINES/dcs/signals/signals_species.dm b/code/__DEFINES/dcs/signals/signals_species.dm index ee5cc33ba359..5c9998a1f80b 100644 --- a/code/__DEFINES/dcs/signals/signals_species.dm +++ b/code/__DEFINES/dcs/signals/signals_species.dm @@ -1,5 +1,5 @@ // /datum/species signals -///from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) +///from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species, pref_load, regenerate_icons) #define COMSIG_SPECIES_GAIN "species_gain" ///from datum/species/on_species_loss(): (datum/species/lost_species) #define COMSIG_SPECIES_LOSS "species_loss" diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index efa29f98dc2a..41a9268e0aa1 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -4,6 +4,8 @@ #define FISHING_RANDOM_SEED "Random seed" ///Used in the surgery fishing spot to define a random organ reward #define FISHING_RANDOM_ORGAN "Random organ" +///Used in the dimensional rift fishing spot to define influence gain +#define FISHING_INFLUENCE "Influence" // Baseline fishing difficulty levels #define FISHING_DEFAULT_DIFFICULTY 15 @@ -135,6 +137,17 @@ ///The coefficient for maximum weight/size divergence relative to the averages. #define MAX_FISH_DEVIATION_COEFF 2.5 +/** + * Base multiplier of the difference between current size and weight and their maximum value + * used to calculate how much fish grow each time they're fed, alongside with the current hunger, + * and the current size and weight, meaning bigger fish naturally tend to grow way slowier + */ +#define FISH_GROWTH_MULT 0.38 +/// Growth peaks at 45% hunger but very rapidly wanes past that. +#define FISH_GROWTH_PEAK 0.45 +/// Used as part of the divisor to slow down growth of bigger fish +#define FISH_SIZE_WEIGHT_GROWTH_MALUS 0.5 + ///The volume of the grind results is multiplied by the fish' weight and divided by this. #define FISH_GRIND_RESULTS_WEIGHT_DIVISOR 500 ///The number of fillets is multiplied by the fish' size and divided by this. @@ -261,6 +274,8 @@ #define FISH_SOURCE_FLAG_NO_BLUESPACE_ROD (1<<1) /// When examined by someone with enough fishing skill, this will also display fish that doesn't have FISH_FLAG_SHOW_IN_CATALOG #define FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG (1<<2) +/// This fish source will not spawn fish on explosions +#define FISH_SOURCE_FLAG_EXPLOSIVE_NONE (1<<3) /** * A macro to ensure the wikimedia filenames of fish icons are unique, especially since there're a couple fish that have diff --git a/code/__DEFINES/gravity.dm b/code/__DEFINES/gravity.dm index da81c0465cab..83177b7ebb3f 100644 --- a/code/__DEFINES/gravity.dm +++ b/code/__DEFINES/gravity.dm @@ -47,7 +47,8 @@ * This should only be possible on multi-z maps because it works like shit on maps that aren't. */ #define NEGATIVE_GRAVITY -1 - +/// Used to indicate no gravity +#define ZERO_GRAVITY 0 #define STANDARD_GRAVITY 1 //Anything above this is high gravity, anything below no grav until negative gravity /// The gravity strength threshold for high gravity damage. #define GRAVITY_DAMAGE_THRESHOLD 3 diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 79535d71652e..975b6037f6bb 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -34,24 +34,6 @@ Therefore, the top right corner (except during admin shenanigans) is at "15,15" */ -/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5) - var/x_off = i % 2 ? 0 : -1 - var/y_off = round((i-1) / 2) - return"CENTER+[x_off]:16,SOUTH+[y_off]:5" - -/proc/ui_equip_position(mob/M) - var/y_off = round((M.held_items.len-1) / 2) //values based on old equip ui position (CENTER: +/-16,SOUTH+1:5) - return "CENTER:-16,SOUTH+[y_off+1]:5" - -/proc/ui_swaphand_position(mob/M, which = 1) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5) - var/x_off = which == 1 ? -1 : 0 - var/y_off = round((M.held_items.len-1) / 2) - return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5" - -/proc/ui_perk_position(perk_count) - var/y_off = perk_count < 1 ? 0 : perk_count/2 - return "WEST+0.5:12,NORTH-2-[y_off]:20" - // Middle #define around_player "CENTER-1,CENTER-1" @@ -72,8 +54,10 @@ #define ui_combo "CENTER+4:24,SOUTH+1:7" //combo meter for martial arts //Lower right, persistent menu -#define ui_drop_throw "EAST-1:28,SOUTH+1:7" +#define ui_rest "EAST-1:28,SOUTH+1:7" +#define ui_drop_throw "EAST-1:28,SOUTH+1:24" #define ui_above_movement "EAST-2:26,SOUTH+1:7" +#define ui_above_movement_top "EAST-2:26, SOUTH+1:24" #define ui_above_intent "EAST-3:24, SOUTH+1:7" #define ui_movi "EAST-2:26,SOUTH:5" #define ui_acti "EAST-3:24,SOUTH:5" @@ -83,8 +67,7 @@ #define ui_crafting "EAST-4:22,SOUTH:5" #define ui_building "EAST-4:22,SOUTH:21" #define ui_language_menu "EAST-4:6,SOUTH:21" -#define ui_navigate_menu "EAST-4:22,SOUTH:5" -#define ui_floor_changer "EAST-3:24, SOUTH+1:3" +#define ui_navigate_menu "EAST-4:6,SOUTH:5" //Upper left (action buttons) #define ui_action_palette "WEST+0:23,NORTH-1:5" @@ -118,7 +101,11 @@ #define ui_living_healthdoll "EAST-1:28,CENTER-1:15" //Humans -#define ui_human_floor_changer "EAST-4:22, SOUTH+1:7" +#define ui_human_floor_changer "EAST-4:22,SOUTH:5" +#define ui_human_crafting "EAST-3:24,SOUTH+1:7" +#define ui_human_navigate "EAST-3:7,SOUTH+1:7" +#define ui_human_language "EAST-3:7,SOUTH+1:24" +#define ui_human_area "EAST-3:24,SOUTH+1:24" //Drones #define ui_drone_drop "CENTER+1:18,SOUTH:5" @@ -141,7 +128,7 @@ #define ui_borg_camera "CENTER+3:21,SOUTH:5" #define ui_borg_alerts "CENTER+4:21,SOUTH:5" #define ui_borg_language_menu "CENTER+4:19,SOUTH+1:6" -#define ui_borg_navigate_menu "CENTER+4:19,SOUTH+1:6" +#define ui_borg_navigate_menu "CENTER+4:3,SOUTH+1:6" #define ui_borg_floor_changer "EAST-1:28,SOUTH+1:39" //Aliens @@ -150,7 +137,7 @@ #define ui_alien_queen_finder "EAST,CENTER-3:15" #define ui_alien_storage_r "CENTER+1:18,SOUTH:5" #define ui_alien_language_menu "EAST-4:20,SOUTH:5" -#define ui_alien_navigate_menu "EAST-4:20,SOUTH:5" +#define ui_alien_navigate_menu "EAST-4:4,SOUTH:5" //AI #define ui_ai_core "BOTTOM:6,RIGHT-4" @@ -191,7 +178,7 @@ #define ui_pai_view_images "SOUTH:6,WEST+12" #define ui_pai_radio "SOUTH:6,WEST+13" #define ui_pai_language_menu "SOUTH+1:8,WEST+12:31" -#define ui_pai_navigate_menu "SOUTH+1:8,WEST+12:31" +#define ui_pai_navigate_menu "SOUTH+1:8,WEST+12:15" //Ghosts #define ui_ghost_spawners_menu "SOUTH:6,CENTER-3:24" @@ -200,8 +187,8 @@ #define ui_ghost_teleport "SOUTH:6,CENTER:24" #define ui_ghost_pai "SOUTH: 6, CENTER+1:24" #define ui_ghost_minigames "SOUTH: 6, CENTER+2:24" -#define ui_ghost_language_menu "SOUTH: 22, CENTER+3:22" -#define ui_ghost_floor_changer "SOUTH: 6, CENTER+3:23" +#define ui_ghost_language_menu "SOUTH: 6, CENTER+3:24" +#define ui_ghost_floor_changer "SOUTH: 6, CENTER+3:8" //Blobbernauts #define ui_blobbernaut_overmind_health "EAST-1:28,CENTER+0:19" diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index b851abe38006..a49da8c70632 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -228,6 +228,7 @@ DEFINE_BITFIELD(smoothing_junction, list( //NOVA EDIT END #define SMOOTH_GROUP_GRAV_FIELD S_OBJ(69) +#define SMOOTH_GROUP_GIRDER S_OBJ(75) /// Performs the work to set smoothing_groups and canSmoothWith. /// An inlined function used in both turf/Initialize and atom/Initialize. diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 9d57d3a85904..bcca4a994af5 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -148,6 +148,10 @@ DEFINE_BITFIELD(no_equip_flags, list( //defines for the index of hands #define LEFT_HANDS 1 #define RIGHT_HANDS 2 +/// Checks if the value is "left" - same as ISEVEN, but used primarily for hand or foot index contexts +#define IS_RIGHT_INDEX(value) (value % 2 == 0) +/// Checks if the value is "right" - same as ISODD, but used primarily for hand or foot index contexts +#define IS_LEFT_INDEX(value) (value % 2 != 0) //flags for female outfits: How much the game can safely "take off" the uniform without it looking weird /// For when there's simply no need for a female version of this uniform. @@ -309,6 +313,38 @@ GLOBAL_LIST_INIT(mining_suit_allowed, list( /obj/item/storage/belt/machete, // NOVA EDIT ADDITION )) +/// List of all "tools" that can fit into belts or work from toolboxes + +GLOBAL_LIST_INIT(tool_items, list( + /obj/item/airlock_painter, + /obj/item/analyzer, + /obj/item/assembly/signaler, + /obj/item/construction/rcd, + /obj/item/construction/rld, + /obj/item/construction/rtd, + /obj/item/crowbar, + /obj/item/extinguisher/mini, + /obj/item/flashlight, + /obj/item/forcefield_projector, + /obj/item/geiger_counter, + /obj/item/holosign_creator/atmos, + /obj/item/holosign_creator/engineering, + /obj/item/inducer, + /obj/item/lightreplacer, + /obj/item/multitool, + /obj/item/pipe_dispenser, + /obj/item/pipe_painter, + /obj/item/plunger, + /obj/item/radio, + /obj/item/screwdriver, + /obj/item/stack/cable_coil, + /obj/item/t_scanner, + /obj/item/weldingtool, + /obj/item/wirecutters, + /obj/item/wrench, + /obj/item/spess_knife, +)) + /// String for items placed into the left pocket. #define LOCATION_LPOCKET "in your left pocket" /// String for items placed into the right pocket diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 8548c284ced8..6308ad94c897 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -253,8 +253,6 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define ismecha(A) (istype(A, /obj/vehicle/sealed/mecha)) -#define ismopable(A) (A && ((PLANE_TO_TRUE(A.plane) == FLOOR_PLANE) ? (A.layer <= FLOOR_CLEAN_LAYER) : (A.layer <= GAME_CLEAN_LAYER))) //If something can be cleaned by floor-cleaning devices such as mops or clean bots - #define isorgan(A) (istype(A, /obj/item/organ)) #define isclothing(A) (istype(A, /obj/item/clothing)) @@ -305,6 +303,9 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( #define isProbablyWallMounted(O) (O.pixel_x > 20 || O.pixel_x < -20 || O.pixel_y > 20 || O.pixel_y < -20) #define isbook(O) (is_type_in_typecache(O, GLOB.book_types)) +// Is this an iron tile, or a material tile made from iron? +#define ismetaltile(tile_thing) (istype(tile_thing, /obj/item/stack/tile/iron) || istype(tile_thing, /obj/item/stack/tile/material) && tile_thing.has_material_type(/datum/material/iron)) + GLOBAL_LIST_INIT(book_types, typecacheof(list( /obj/item/book, /obj/item/spellbook, diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 5f025ad99cff..8ae95933e646 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -4,6 +4,9 @@ #define COMSIG_KB_ACTIVATED (1<<0) #define COMSIG_KB_EMOTE "keybinding_emote_down" +///Signal sent when a keybind is deactivated +#define DEACTIVATE_KEYBIND(A) "[A]_DEACTIVATED" + //Admin #define COMSIG_KB_ADMIN_ASAY_DOWN "keybinding_admin_asay_down" #define COMSIG_KB_ADMIN_DSAY_DOWN "keybinding_admin_dsay_down" @@ -54,6 +57,7 @@ #define COMSIG_KB_LIVING_DISABLE_COMBAT_DOWN "keybinding_living_disable_combat_down" #define COMSIG_KB_LIVING_TOGGLEMOVEINTENT_DOWN "keybinding_mob_togglemoveintent_down" #define COMSIG_KB_LIVING_TOGGLEMOVEINTENTALT_DOWN "keybinding_mob_togglemoveintentalt_down" +#define COMSIG_KB_LIVING_VIEW_PET_COMMANDS "keybinding_living_view_pet_commands" //Mob #define COMSIG_KB_MOB_FACENORTH_DOWN "keybinding_mob_facenorth_down" diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index e94918abff30..a2a676a04a06 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -157,9 +157,7 @@ #define CATWALK_LAYER (14 + TOPDOWN_LAYER) #define LOWER_RUNE_LAYER (15 + TOPDOWN_LAYER) #define RUNE_LAYER (16 + TOPDOWN_LAYER) -/// [GAME_CLEAN_LAYER] but for floors. -/// Basically any layer below this (numerically) is "on" a floor for the purposes of washing -#define FLOOR_CLEAN_LAYER (21 + TOPDOWN_LAYER) +#define CLEANABLE_FLOOR_OBJECT_LAYER (21 + TOPDOWN_LAYER) //Placeholders in case the game plane and possibly other things between it and the floor plane are ever made into topdown planes @@ -186,9 +184,7 @@ #define BOT_PATH_LAYER 2.497 #define LOW_OBJ_LAYER 2.5 #define HIGH_PIPE_LAYER 2.54 -// Anything above this layer is not "on" a turf for the purposes of washing -// I hate this life of ours -#define GAME_CLEAN_LAYER 2.55 +#define CLEANABLE_OBJECT_LAYER 2.55 #define TRAM_STRUCTURE_LAYER 2.57 #define TRAM_FLOOR_LAYER 2.58 #define TRAM_WALL_LAYER 2.59 @@ -202,6 +198,7 @@ #define DOOR_HELPER_LAYER 2.72 //keep this above DOOR_ACCESS_HELPER_LAYER and OPEN_DOOR_LAYER since the others tend to have tiny sprites that tend to be covered up. #define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible #define TABLE_LAYER 2.8 +#define GIB_LAYER 2.85 // sit on top of tables, but below machines #define BELOW_OBJ_LAYER 2.9 #define LOW_ITEM_LAYER 2.95 //#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 67fb080ee135..906f7fb98559 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -23,8 +23,12 @@ #define STATIC_TO_DYNAMIC_CHANNEL(static_channel) (static_channel - (AREA_USAGE_STATIC_START - AREA_USAGE_DYNAMIC_START)) //Power use + +/// dont use power #define NO_POWER_USE 0 +/// use idle_power_usage i.e. the power needed just to keep the machine on #define IDLE_POWER_USE 1 +/// use active_power_usage i.e. the power the machine consumes to perform a specific task #define ACTIVE_POWER_USE 2 ///Base global power consumption for idling machines diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index 35c8d3edaf63..a96a950559ae 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -132,6 +132,9 @@ // E.g: 540 becomes 180. -180 becomes 180. #define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360)) +// 180s an angle +#define REVERSE_ANGLE(degrees) (SIMPLIFY_DEGREES(degrees + 180)) + #define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360)) //Finds the shortest angle that angle A has to change to get to angle B. Aka, whether to move clock or counterclockwise. diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index ce3f9f10860f..ca9dd0e6d0bd 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -669,6 +669,7 @@ // Hair masks #define HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM "hide_above_45deg_medium" #define HAIR_MASK_HIDE_ABOVE_45_DEG_LOW "hide_above_45deg_low" +#define HAIR_MASK_HIDE_WINTERHOOD "hide_winterhood" // Height defines // - They are numbers so you can compare height values (x height < y height) @@ -898,6 +899,10 @@ GLOBAL_LIST_INIT(layers_to_offset, list( /// The default mob sprite size (used for shrinking or enlarging the mob sprite to regular size) #define RESIZE_DEFAULT_SIZE 1 +//Lying angles, which way your head points +#define LYING_ANGLE_EAST 90 +#define LYING_ANGLE_WEST 270 + /// Get the client from the var #define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (istype(I, /client) ? I : (istype(I, /datum/mind) ? I:current?:client : null))) diff --git a/code/__DEFINES/pipe_construction.dm b/code/__DEFINES/pipe_construction.dm index 540cadabc47a..415df95bb344 100644 --- a/code/__DEFINES/pipe_construction.dm +++ b/code/__DEFINES/pipe_construction.dm @@ -1,12 +1,21 @@ //Construction Categories -#define PIPE_STRAIGHT 0 //2 directions: N/S, E/W -#define PIPE_BENDABLE 1 //6 directions: N/S, E/W, N/E, N/W, S/E, S/W -#define PIPE_TRINARY 2 //4 directions: N/E/S, E/S/W, S/W/N, W/N/E -#define PIPE_TRIN_M 3 //8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N -#define PIPE_UNARY 4 //4 directions: N, S, E, W -#define PIPE_ONEDIR 5 //1 direction: N/S/E/W -#define PIPE_UNARY_FLIPPABLE 6 //8 directions: N/S/E/W/N-flipped/S-flipped/E-flipped/W-flipped -#define PIPE_ONEDIR_FLIPPABLE 7 //2 direction: N/S/E/W, N-flipped/S-flipped/E-flipped/W-flipped + +///2 directions: N/S, E/W +#define PIPE_STRAIGHT 0 +///6 directions: N/S, E/W, N/E, N/W, S/E, S/W +#define PIPE_BENDABLE 1 +///4 directions: N/E/S, E/S/W, S/W/N, W/N/E +#define PIPE_TRINARY 2 +///8 directions: N->S+E, S->N+E, N->S+W, S->N+W, E->W+S, W->E+S, E->W+N, W->E+N +#define PIPE_TRIN_M 3 +///4 directions: N, S, E, W +#define PIPE_UNARY 4 +///1 direction: N/S/E/W +#define PIPE_ONEDIR 5 +///8 directions: N/S/E/W/N-flipped/S-flipped/E-flipped/W-flipped +#define PIPE_UNARY_FLIPPABLE 6 +///2 direction: N/S/E/W, N-flipped/S-flipped/E-flipped/W-flipped +#define PIPE_ONEDIR_FLIPPABLE 7 //Disposal pipe relative connection directions #define DISP_DIR_BASE 0 diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm index c3e861b56c99..416aae5ec7fb 100644 --- a/code/__DEFINES/projectiles.dm +++ b/code/__DEFINES/projectiles.dm @@ -25,11 +25,11 @@ /// The caliber used by the detective's revolver. #define CALIBER_38 ".38" /// The caliber used by the C-20r SMG, the tommygun, and the M1911 pistol. -#define CALIBER_45 ".45" +#define CALIBER_45 ".460 Ceres" // NOVA EDIT CHANGE - ORIGINAL: #define CALIBER_45 ".45" /// The caliber used by sniper rifles. -#define CALIBER_50BMG ".50BMG" +#define CALIBER_50BMG ".416 Stabilis" // NOVA EDIT - CHANGE - ORIGINAL: #define CALIBER_50BMG ".50BMG" /// The caliber used by the desert eagle. -#define CALIBER_50AE ".50AE" +#define CALIBER_50AE ".454 Trucidator" // NOVA EDIT CHANGE - ORIGINAL: #define CALIBER_50AE ".50AE" /// The caliber used by the gyrojet pistol. #define CALIBER_75 ".75" /// The caliber used by [one revolver variant][/obj/item/gun/ballistic/revolver/nagant]. @@ -62,6 +62,8 @@ #define CALIBER_TENTACLE "tentacle" /// The caliber used by pipeguns and pipe pistols #define CALIBER_JUNK "junk" +/// The caliber used by the (gatfruit) peashooter +#define CALIBER_PEA "pea" /// For gunpoints, how many tiles around the target the shooter can roam without losing their shot #define GUNPOINT_SHOOTER_STRAY_RANGE 2 diff --git a/code/__DEFINES/radial_defines.dm b/code/__DEFINES/radial_defines.dm new file mode 100644 index 000000000000..35ae6eebb598 --- /dev/null +++ b/code/__DEFINES/radial_defines.dm @@ -0,0 +1,6 @@ +#define NEXT_PAGE_ID "__next__" +#define DEFAULT_CHECK_DELAY 2 SECONDS + +#define BUTTON_SLIDE_IN (1<<0) +#define BUTTON_FADE_IN (1<<1) +#define BUTTON_FADE_OUT (1<<2) diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index bf0271ca5a9a..ac1a2e3a5222 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -1,7 +1,3 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - #define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes. #define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes. @@ -46,7 +42,8 @@ ///Health threshold for synthflesh and rezadone to unhusk someone #define UNHUSK_DAMAGE_THRESHOLD 50 ///Amount of synthflesh required to unhusk someone -#define SYNTHFLESH_UNHUSK_AMOUNT 100 +#define SYNTHFLESH_UNHUSK_AMOUNT 60 +#define SYNTHFLESH_UNHUSK_MAX 100 //used by chem masters and pill presses // The categories of reagent packaging diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index d7a04afeede4..84f0c5d0334c 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -161,10 +161,19 @@ #define rustg_git_revparse(rev) RUSTG_CALL(RUST_G, "rg_git_revparse")(rev) /** - * Returns the date of the given revision in the format YYYY-MM-DD. - * Returns null if the revision is invalid. + * Returns the date of the given revision using the provided format. + * Defaults to returning %F which is YYYY-MM-DD. */ -#define rustg_git_commit_date(rev) RUSTG_CALL(RUST_G, "rg_git_commit_date")(rev) +/proc/rustg_git_commit_date(rev, format = "%F") + return RUSTG_CALL(RUST_G, "rg_git_commit_date")(rev, format) + +/** + * Returns the formatted datetime string of HEAD using the provided format. + * Defaults to returning %F which is YYYY-MM-DD. + * This is different to rustg_git_commit_date because it only needs the logs directory. + */ +/proc/rustg_git_commit_date_head(format = "%F") + return RUSTG_CALL(RUST_G, "rg_git_commit_date_head")(format) #define RUSTG_HTTP_METHOD_GET "get" #define RUSTG_HTTP_METHOD_PUT "put" @@ -187,6 +196,20 @@ #define rustg_noise_get_at_coordinates(seed, x, y) RUSTG_CALL(RUST_G, "noise_get_at_coordinates")(seed, x, y) +/** + * Generates a 2D poisson disk distribution ('blue noise'), which is relatively uniform. + * + * params: + * `seed`: str + * `width`: int, width of the noisemap (see world.maxx) + * `length`: int, height of the noisemap (see world.maxy) + * `radius`: int, distance between points on the noisemap + * + * returns: + * a width*length length string of 1s and 0s representing a 2D poisson sample collapsed into a 1D string + */ +#define rustg_noise_poisson_map(seed, width, length, radius) RUSTG_CALL(RUST_G, "noise_poisson_map")(seed, width, length, radius) + /* * Takes in a string and json_encode()"d lists to produce a sanitized string. * This function operates on whitelists, there is currently no way to blacklist. @@ -238,3 +261,45 @@ #define url_decode(text) rustg_url_decode(text) #endif +/// Provided a static RSC file path or a raw text file path, returns the duration of the file in deciseconds as a float. +/proc/rustg_sound_length(file_path) + var/static/list/sound_cache + if(isnull(sound_cache)) + sound_cache = list() + + . = 0 + + if(!istext(file_path)) + if(!isfile(file_path)) + CRASH("rustg_sound_length error: Passed non-text object") + + if(length("[file_path]")) // Runtime generated RSC references stringify into 0-length strings. + file_path = "[file_path]" + else + CRASH("rustg_sound_length does not support non-static file refs.") + + var/cached_length = sound_cache[file_path] + if(!isnull(cached_length)) + return cached_length + + var/ret = RUSTG_CALL(RUST_G, "sound_len")(file_path) + var/as_num = text2num(ret) + if(isnull(ret)) + . = 0 + CRASH("rustg_sound_length error: [ret]") + + sound_cache[file_path] = as_num + return as_num + + +#define RUSTG_SOUNDLEN_SUCCESSES "successes" +#define RUSTG_SOUNDLEN_ERRORS "errors" +/** + * Returns a nested key-value list containing "successes" and "errors" + * The format is as follows: + * list( + * RUSTG_SOUNDLEN_SUCCESES = list("sounds/test.ogg" = 25.34), + * RUSTG_SOUNDLEN_ERRORS = list("sound/bad.png" = "SoundLen: Unable to decode file."), + *) +*/ +#define rustg_sound_length_list(file_paths) json_decode(RUSTG_CALL(RUST_G, "sound_len_list")(json_encode(file_paths))) diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index fc230740b29b..313b4cc2caa9 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -103,9 +103,9 @@ #define MODE_RANGE_INTERCOM 1 // A link given to ghost alice to follow bob -#define FOLLOW_LINK(alice, bob) "(F)" -#define TURF_LINK(alice, turfy) "(T)" -#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "(F)" +#define FOLLOW_LINK(alice, bob) "(F)" +#define TURF_LINK(alice, turfy) "(T)" +#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "(F)" //Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam #define MAX_MESSAGE_LEN 2048 //NOVA EDIT CHANGE - ORIGINAL 1024 - I SAID DOUBLE IT!! FUCK THE WARNING! diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index 759121e3b8dd..12f15ab1e68d 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -62,6 +62,7 @@ #define ENGINE_COEFF_MIN 0.5 #define ENGINE_COEFF_MAX 2 #define ENGINE_DEFAULT_MAXSPEED_ENGINES 5 +#define ENGINE_START_TIME 100 // Alert level related #define ALERT_COEFF_AUTOEVAC_NORMAL 2.5 @@ -120,3 +121,12 @@ #define SHUTTLE_EVENT_MISS_SHUTTLE 1 << 0 ///spawned stuff should hit the shuttle #define SHUTTLE_EVENT_HIT_SHUTTLE 1 << 1 + +// Hijack stages + +#define HIJACK_NOT_BEGUN 0 +#define HIJACK_STAGE_1 1 +#define HIJACK_STAGE_2 2 +#define HIJACK_STAGE_3 3 +#define HIJACK_STAGE_4 4 +#define HIJACK_COMPLETED 5 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 5baadf09f71b..79a231b66ca9 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -21,6 +21,43 @@ #define CHANNEL_JUKEBOX_START 1006 #define CHANNEL_HEV 1005 //NOVA EDIT CHANGE END +/// This is the lowest volume that can be used by playsound otherwise it gets ignored +/// Most sounds around 10 volume can barely be heard. Almost all sounds at 5 volume or below are inaudible +/// This is to prevent sound being spammed at really low volumes due to distance calculations +/// Recommend setting this to anywhere from 10-3 (or 0 to disable any sound minimum volume restrictions) +/// Ex. For a 70 volume sound, 17 tile range, 3 exponent, 2 falloff_distance: +/// Setting SOUND_AUDIBLE_VOLUME_MIN to 0 for the above will result in 17x17 radius (289 turfs) +/// Setting SOUND_AUDIBLE_VOLUME_MIN to 5 for the above will result in 14x14 radius (196 turfs) +/// Setting SOUND_AUDIBLE_VOLUME_MIN to 10 for the above will result in 11x11 radius (121 turfs) +#define SOUND_AUDIBLE_VOLUME_MIN 3 + +/* Calculates the max distance of a sound based on audible volume + * + * Note - you should NEVER pass in a volume that is lower than SOUND_AUDIBLE_VOLUME_MIN otherwise distance will be insanely large (like +250,000) + * + * Arguments: + * * volume: The initial volume of the sound being played + * * max_distance: The range of the sound in tiles (technically not real max distance since the furthest areas gets pruned due to SOUND_AUDIBLE_VOLUME_MIN) + * * falloff_distance: Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range. + * * falloff_exponent: Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive. + * Returns: The max distance of a sound based on audible volume range + */ +#define CALCULATE_MAX_SOUND_AUDIBLE_DISTANCE(volume, max_distance, falloff_distance, falloff_exponent)\ + floor(((((-(max(max_distance - falloff_distance, 0) ** (1 / falloff_exponent)) / volume) * (SOUND_AUDIBLE_VOLUME_MIN - volume)) ** falloff_exponent) + falloff_distance)) + +/* Calculates the volume of a sound based on distance + * + * https://www.desmos.com/calculator/sqdfl8ipgf + * + * Arguments: + * * volume: The initial volume of the sound being played + * * distance: How far away the sound is in tiles from the source + * * falloff_distance: Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range. + * * falloff_exponent: Rate of falloff for the audio. Higher means quicker drop to low volume. Should generally be over 1 to indicate a quick dive to 0 rather than a slow dive. + * Returns: The max distance of a sound based on audible volume range + */ +#define CALCULATE_SOUND_VOLUME(volume, distance, max_distance, falloff_distance, falloff_exponent)\ + ((max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * volume) ///Default range of a sound. #define SOUND_RANGE 17 diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index b180c7b33494..955e046edefc 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -13,10 +13,15 @@ #define MAX_SATIETY 600 // bitflags for machine stat variable + +/// physically broken #define BROKEN (1<<0) +/// not powered #define NOPOWER (1<<1) -#define MAINT (1<<2) // under maintaince -#define EMPED (1<<3) // temporary broken by EMP pulse +/// under maintaince +#define MAINT (1<<2) +/// temporary broken by EMP pulse +#define EMPED (1<<3) //ai power requirement defines #define POWER_REQ_ALL 1 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3d90e086c806..2f2f7030e5c5 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -168,6 +168,7 @@ #define INIT_ORDER_RESTAURANT 34 #define INIT_ORDER_POLLUTION 32 //NOVA EDIT ADDITION - //Needs to be above atoms #define INIT_ORDER_TTS 33 +#define INIT_ORDER_FLUIDS 32 // Needs to be above atoms, as some atoms may want to start fluids/gases on init #define INIT_ORDER_ATOMS 30 #define INIT_ORDER_ARMAMENTS 27 // NOVA EDIT ADDITION - Needs to be between atoms and default so it runs before gun companies #define INIT_ORDER_LANGUAGE 25 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index 42f2d5fc31fe..7e1ba820dd8b 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,7 +1,7 @@ // tgstation-server DMAPI // The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119. -#define TGS_DMAPI_VERSION "7.3.0" +#define TGS_DMAPI_VERSION "7.3.1" // All functions and datums outside this document are subject to change with any version and should not be relied on. @@ -58,6 +58,11 @@ #define TGS_FILE2TEXT_NATIVE file2text #endif +// SpacemanDMM compatibility +#ifndef CAN_BE_REDEFINED +#define CAN_BE_REDEFINED(X) +#endif + // EVENT CODES /// Before a reboot mode change, extras parameters are the current and new reboot mode enums. @@ -160,6 +165,7 @@ * * http_handler - Optional user defined [/datum/tgs_http_handler]. */ /world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler) + CAN_BE_REDEFINED(TRUE) return /** @@ -170,6 +176,7 @@ * This function should not be called before ..() in [/world/proc/New]. */ /world/proc/TgsInitializationComplete() + CAN_BE_REDEFINED(TRUE) return /// Consumers MUST run this macro at the start of [/world/proc/Topic]. @@ -177,6 +184,7 @@ /// Consumers MUST call this as late as possible in [world/proc/Reboot] (BEFORE ..()). /world/proc/TgsReboot() + CAN_BE_REDEFINED(TRUE) return // DATUM DEFINITIONS @@ -214,6 +222,7 @@ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards. */ /datum/tgs_version/proc/Wildcard() + CAN_BE_REDEFINED(TRUE) return /** @@ -222,6 +231,7 @@ * other_version - The [/datum/tgs_version] to compare against. */ /datum/tgs_version/proc/Equals(datum/tgs_version/other_version) + CAN_BE_REDEFINED(TRUE) return /// Represents a merge of a GitHub pull request. @@ -459,16 +469,19 @@ /// Returns the maximum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMaximumApiVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the minimum supported [/datum/tgs_version] of the DMAPI. /world/proc/TgsMinimumApiVersion() + CAN_BE_REDEFINED(TRUE) return /** * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise. */ /world/proc/TgsAvailable() + CAN_BE_REDEFINED(TRUE) return // No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called. @@ -480,6 +493,7 @@ * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again. */ /world/proc/TgsEndProcess() + CAN_BE_REDEFINED(TRUE) return /** @@ -490,6 +504,7 @@ * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. */ /world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE) + CAN_BE_REDEFINED(TRUE) return /** @@ -500,6 +515,7 @@ * user: The [/datum/tgs_chat_user] to PM. */ /world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user) + CAN_BE_REDEFINED(TRUE) return /** @@ -510,42 +526,52 @@ * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. */ /world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null) + CAN_BE_REDEFINED(TRUE) return /// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the running engine type /world/proc/TgsEngine() + CAN_BE_REDEFINED(TRUE) return /// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsApiVersion() + CAN_BE_REDEFINED(TRUE) return /// Returns the name of the TGS instance running the game if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsInstanceName() + CAN_BE_REDEFINED(TRUE) return /// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsRevision() + CAN_BE_REDEFINED(TRUE) return /// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsSecurityLevel() + CAN_BE_REDEFINED(TRUE) return /// Returns the current BYOND visibility level as a TGS_VISIBILITY_ define if TGS is present, null otherwise. Requires TGS to be using interop API version 5 or higher otherwise the string "___unimplemented" wil be returned. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsVisibility() + CAN_BE_REDEFINED(TRUE) return /// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsTestMerges() + CAN_BE_REDEFINED(TRUE) return /// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsChatChannelInfo() + CAN_BE_REDEFINED(TRUE) return /** @@ -556,6 +582,7 @@ * wait_for_completion - If set, this function will not return until the event has run to completion. */ /world/proc/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE) + CAN_BE_REDEFINED(TRUE) return /* diff --git a/code/__DEFINES/traits/_traits.dm b/code/__DEFINES/traits/_traits.dm index 46fef90160aa..7ebf1ad65904 100644 --- a/code/__DEFINES/traits/_traits.dm +++ b/code/__DEFINES/traits/_traits.dm @@ -1,5 +1,5 @@ -#define SIGNAL_ADDTRAIT(trait_ref) "addtrait [trait_ref]" -#define SIGNAL_REMOVETRAIT(trait_ref) "removetrait [trait_ref]" +#define SIGNAL_ADDTRAIT(trait_ref) ("addtrait " + trait_ref) +#define SIGNAL_REMOVETRAIT(trait_ref) ("removetrait " + trait_ref) // trait accessor defines #define ADD_TRAIT(target, trait, source) \ diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 6508940f97d8..8dd3f3d5f2d7 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -807,6 +807,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ROD_ATTRACT_SHINY_LOVERS "rod_attract_shiny_lovers" /// This rod can be used to fish on lava #define TRAIT_ROD_LAVA_USABLE "rod_lava_usable" +/// This rod was infused by a heretic, making it awesome and improving influence gain +#define TRAIT_ROD_MANSUS_INFUSED "rod_infused" /// Stuff that can go inside fish cases and aquariums #define TRAIT_AQUARIUM_CONTENT "aquarium_content" /// If the item can be used as a bit. @@ -839,6 +841,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH "stop_fish_reproduction_and_growth" /// This is an aquarium with an open panel #define TRAIT_AQUARIUM_PANEL_OPEN "aquarium_panel_open" +/// For locations that prevent fish flopping animation, namely aquariums +#define TRAIT_STOP_FISH_FLOPPING "stop_fish_flopping" /// Plants that were mutated as a result of passive instability, not a mutation threshold. #define TRAIT_PLANT_WILDMUTATE "wildmutation" /// If you hit an APC with exposed internals with this item it will try to shock you @@ -918,6 +922,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai // Debug traits /// This object has light debugging tools attached to it #define TRAIT_LIGHTING_DEBUGGED "lighting_debugged" +/// This object has sound debugging tools attached to it +#define TRAIT_SOUND_DEBUGGED "sound_debugged" /// Gives you the Shifty Eyes quirk, rarely making people who examine you think you examined them back even when you didn't #define TRAIT_SHIFTY_EYES "shifty_eyes" @@ -1029,6 +1035,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///fish traits #define TRAIT_FISH_STASIS "fish_stasis" #define TRAIT_FISH_FLOPPING "fish_flopping" +#define TRAIT_RESIST_PSYCHIC "resist_psychic" #define TRAIT_RESIST_EMULSIFY "resist_emulsify" #define TRAIT_FISH_SELF_REPRODUCE "fish_self_reproduce" #define TRAIT_FISH_NO_MATING "fish_no_mating" @@ -1160,8 +1167,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_MAGNETIC_ID_CARD "magnetic_id_card" /// ID cards with this trait have special appraisal text. #define TRAIT_TASTEFULLY_THICK_ID_CARD "impressive_very_nice" -/// things with this trait are treated as having no access in /atom/movable/proc/check_access(obj/item) -#define TRAIT_ALWAYS_NO_ACCESS "alwaysnoaccess" ///The entity has Silicon 'access', so is either a silicon, has an access wand, or is an admin ghost AI. ///This is put on the mob, it is used on the client for Admins but they are the exception as they use `isAdminGhostAI`. @@ -1393,6 +1398,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai * (This may be changed later but I chose to do it this way to avoid messing up interactions which require combat mode) */ #define TRAIT_COMBAT_MODE_SKIP_INTERACTION "combat_mode_skip_interaction" +// bars change of combat mode +#define TRAIT_COMBAT_MODE_LOCK "combat_mode_lock" ///A "fake" effect that should not be subject to normal effect removal methods (like the effect remover component) #define TRAIT_ILLUSORY_EFFECT "illusory_effect" @@ -1402,6 +1409,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Trait given to atoms currently affected by projectile dampeners #define TRAIT_GOT_DAMPENED "got_dampened" +/// Apply to movables to say "hey, this movable is technically flat on the floor, so it'd be mopped up by a mop" +#define TRAIT_MOPABLE "mopable" + // /obj/item /// Applied to a satchel that is being worn on the belt. Iris addition. #define TRAIT_BELT_SATCHEL "belt_satchel" diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm index 4deb39251412..c4e952ed77b7 100644 --- a/code/__DEFINES/traits/sources.dm +++ b/code/__DEFINES/traits/sources.dm @@ -312,3 +312,6 @@ /// From the aquarium component #define AQUARIUM_TRAIT "aquarium" + +/// Trait aquired from being painted a certain color +#define ATOM_COLOR_TRAIT "atom_color" diff --git a/code/__DEFINES/turbine_defines.dm b/code/__DEFINES/turbine_defines.dm index 4dc2bde1b8fe..2a985ddb7b63 100644 --- a/code/__DEFINES/turbine_defines.dm +++ b/code/__DEFINES/turbine_defines.dm @@ -1,7 +1,15 @@ +///String to enquire about the turbines max rpm for its tier +#define TURBINE_MAX_RPM "turbine_max_rpm" +///String to enquire about the turbines max temperature for its tier +#define TURBINE_MAX_TEMP "turbine_max_temp" +///String to enquire about the turbines max efficiency for its tier +#define TURBINE_MAX_EFFICIENCY "turbine_max_efficiency" +///Maximum rpm for all tier 1 turbine parts +#define TURBINE_MAX_BASE_RPM 50000 ///Multiplier for converting work into rpm and rpm into power #define TURBINE_RPM_CONVERSION 15 ///Efficiency of the turbine to turn work into energy, higher values will yield more power -#define TURBINE_ENERGY_RECTIFICATION_MULTIPLIER 0.25 +#define TURBINE_ENERGY_RECTIFICATION_MULTIPLIER 0.3 ///Max allowed damage per tick #define TURBINE_MAX_TAKEN_DAMAGE 10 ///Amount of damage healed when under the heat threshold diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index a83ef71ddc69..2b66fca251ea 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -50,7 +50,7 @@ #define GET_VV_VAR_TARGET href_list[VV_HK_VARNAME] //Helper for getting something to vv_do_topic in general -#define VV_TOPIC_LINK(datum, href_key, text) "text" +#define VV_TOPIC_LINK(datum, href_key, text) "text" //Helpers for vv_get_dropdown() #define VV_DROPDOWN_OPTION(href_key, name) . += "" diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm index f69c8a44e81c..c0ae6da61688 100644 --- a/code/__DEFINES/wounds.dm +++ b/code/__DEFINES/wounds.dm @@ -322,8 +322,8 @@ GLOBAL_LIST_INIT(biotypes_to_scar_file, list( // ~random wound balance defines /// how quickly sanitization removes infestation and decays per second #define WOUND_BURN_SANITIZATION_RATE 0.075 -/// how much blood you can lose per tick per slash max. -#define WOUND_SLASH_MAX_BLOODFLOW 4.5 +/// how much blood you can lose per tick per wound max. +#define WOUND_MAX_BLOODFLOW 4.5 /// further slash attacks on a bodypart with a slash wound have their blood_flow further increased by damage * this (10 damage slash adds .25 flow) #define WOUND_SLASH_DAMAGE_FLOW_COEFF 0.025 /// if we suffer a bone wound to the head that creates brain traumas, the timer for the trauma cycle is +/- by this percent (0-100) diff --git a/code/__DEFINES/~nova_defines/admin.dm b/code/__DEFINES/~nova_defines/admin.dm index 951facce61a8..966c608ef451 100644 --- a/code/__DEFINES/~nova_defines/admin.dm +++ b/code/__DEFINES/~nova_defines/admin.dm @@ -1 +1 @@ -#define ADMIN_PASS_OPFOR(src) "(PASS)" +#define ADMIN_PASS_OPFOR(src) "(PASS)" diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 1d247c12e6ee..8e818e0e7f46 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(list( return newA = new area_choice newA.setup(str) - newA.has_gravity = oldA.has_gravity + newA.default_gravity = oldA.default_gravity require_area_resort() //new area registered. resort the names else newA = area_choice diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index efee782aaeb8..aa13b74f0e1c 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -215,3 +215,8 @@ var/position_a = fluids_priority.Find(initial(a.required_fluid_type)) var/position_b = fluids_priority.Find(initial(b.required_fluid_type)) return cmp_numeric_asc(position_a, position_b) || cmp_text_asc(initial(b.name), initial(a.name)) + +///Sorts stock parts based on tier +/proc/cmp_rped_sort(obj/item/first_item, obj/item/second_item) + ///even though stacks aren't stock parts, get_part_rating() is defined on the item level (see /obj/item/proc/get_part_rating()) and defaults to returning 0. + return second_item.get_part_rating() - first_item.get_part_rating() diff --git a/code/__HELPERS/colors.dm b/code/__HELPERS/colors.dm index 3a20e5ad60c0..28677669768e 100644 --- a/code/__HELPERS/colors.dm +++ b/code/__HELPERS/colors.dm @@ -148,3 +148,116 @@ return "#[num2hex(c, 2)][num2hex(m, 2)][num2hex(x, 2)]" #define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255))) + +/* Generates an HSL color transition matrix filter which nicely paints an object + * without making it a deep fried blob of color + * saturation_behavior determines how we handle color saturation: + * SATURATION_MULTIPLY - Multiply pixel's saturation by color's saturation. Paints accents while keeping dim areas dim. + * SATURATION_OVERRIDE- Affects original lightness/saturation to ensure that pale objects still get doused in color + */ +/proc/color_transition_filter(new_color, saturation_behavior = SATURATION_MULTIPLY) + if (islist(new_color)) + new_color = rgb(new_color[1], new_color[2], new_color[3]) + new_color = rgb2num(new_color, COLORSPACE_HSL) + var/hue = new_color[1] / 360 + var/saturation = new_color[2] / 100 + var/added_saturation = 0 + var/deducted_light = 0 + if (saturation_behavior == SATURATION_OVERRIDE) + added_saturation = saturation * 0.75 + deducted_light = saturation * 0.5 + saturation = min(saturation, 1 - added_saturation) + + var/list/new_matrix = list( + 0, 0, 0, 0, // Ignore original hue + 0, saturation, 0, 0, // Multiply the saturation by ours + 0, 0, 1 - deducted_light, 0, // If we're highly saturated then remove a bit of lightness to keep some color in + 0, 0, 0, 1, // Preserve alpha + hue, added_saturation, 0, 0, // And apply our preferred hue and some saturation if we're oversaturated + ) + return color_matrix_filter(new_matrix, FILTER_COLOR_HSL) + +/// Applies a color filter to a hex/RGB list color +/proc/apply_matrix_to_color(color, list/matrix, colorspace = COLORSPACE_HSL) + if (islist(color)) + color = rgb(color[1], color[2], color[3], color[4]) + color = rgb2num(color, colorspace) + // Pad alpha if we're lacking it + if (length(color) < 4) + color += 255 + + // Do we have a constants row? + var/has_constants = FALSE + // Do we have an alpha row/parameters? + var/has_alpha = FALSE + + switch (length(matrix)) + if (9) + has_constants = FALSE + has_alpha = FALSE + if (12) + has_constants = TRUE + has_alpha = FALSE + if (16) + has_constants = FALSE + has_alpha = TRUE + if (20) + has_constants = TRUE + has_alpha = TRUE + else + CRASH("Matrix of invalid length [length(matrix)] was passed into apply_matrix_to_color!") + + var/list/new_color = list(0, 0, 0, 0) + var/row_length = 3 + if (has_alpha) + row_length = 4 + else + new_color[4] = 255 + + for (var/row_index in 1 to length(matrix) / row_length) + for (var/row_elem in 1 to row_length) + var/elem = matrix[(row_index - 1) * row_length + row_elem] + if (!has_constants || row_index != (length(matrix) / row_length)) + new_color[row_index] += color[row_elem] * elem + continue + + // Constant values at the end of the list (if we have such) + if (colorspace != COLORSPACE_HSV && colorspace != COLORSPACE_HCY && colorspace != COLORSPACE_HSL) + new_color[row_elem] += elem * 255 + continue + + // HSV/HSL/HCY have non-255 maximums for their values + var/multiplier = 255 + switch (row_elem) + // Hue goes from 0 to 360 + if (1) + multiplier = 360 + // Value, luminance, chroma, etc go from 0 to 100 + if (2 to 3) + multiplier = 100 + // Alpha still goes from 0 to 255 + if (4) + multiplier = 255 + new_color[row_elem] += elem * multiplier + + var/rgbcolor = rgb(new_color[1], new_color[2], new_color[3], new_color[4], space = colorspace) + return rgbcolor + +/// Recursively applies a filter to a passed in static appearance, returns the modified appearance +/proc/filter_appearance_recursive(mutable_appearance/filter, filter_to_apply) + var/mutable_appearance/modify = new(filter) + var/list/existing_filters = modify.filters.Copy() + modify.filters = list(filter_to_apply) + existing_filters + + // Ideally this should be recursive to check for KEEP_APART elements that need this applied to it + // and RESET_COLOR flags but this is much simpler, and hopefully we don't have that point of layering here + if(modify.appearance_flags & KEEP_TOGETHER) + return modify + + for(var/overlay_index in 1 to length(modify.overlays)) + modify.overlays[overlay_index] = filter_appearance_recursive(modify.overlays[overlay_index], filter_to_apply) + + for(var/underlay_index in 1 to length(modify.underlays)) + modify.underlays[underlay_index] = filter_appearance_recursive(modify.underlays[underlay_index], filter_to_apply) + + return modify diff --git a/code/__HELPERS/construction.dm b/code/__HELPERS/construction.dm index 166a009f0666..a0ebb3db0340 100644 --- a/code/__HELPERS/construction.dm +++ b/code/__HELPERS/construction.dm @@ -46,9 +46,9 @@ return 0 /** - * Splits a stack. we don't use /obj/item/stack/proc/fast_split_stack because Byond complains that should only be called asynchronously. + * Splits a stack. we don't use /obj/item/stack/proc/split_stack because Byond complains that should only be called asynchronously. * This proc is also more faster because it doesn't deal with mobs, copying evidences or refreshing atom storages - * Has special internal uses for e.g. by the material container + * Has special internal uses for e.g. by the material container & RPED * * Arguments: * - [target][obj/item/stack]: the stack to split diff --git a/code/__HELPERS/filters.dm b/code/__HELPERS/filters.dm index 930c889b09ca..f84c812e0be7 100644 --- a/code/__HELPERS/filters.dm +++ b/code/__HELPERS/filters.dm @@ -322,3 +322,8 @@ GLOBAL_LIST_INIT(master_filter_info, list( continue animate(filter, x = 0, y = 0, size = 0, offset = 0, time = remove_duration) addtimer(CALLBACK(in_atom, TYPE_PROC_REF(/datum, remove_filter), "wibbly-[i]"), remove_duration) + +/proc/convert_list_to_filter(list/list_filter) + var/list/arguments = list_filter.Copy() + arguments -= "priority" + return filter(arglist(arguments)) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 2c285a348fac..9b80dbfc169c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -349,4 +349,4 @@ message = html_encode(message) else message = copytext(message, 2) - to_chat(target, span_purple(examine_block("[source]: [message]"))) + to_chat(target, custom_boxed_message("purple_box", span_purple("[source]: [message]"))) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 2c9bd5aa0bde..df63fca7e559 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -188,6 +188,7 @@ GLOBAL_LIST_INIT(WALLITEMS_INTERIOR, typecacheof(list( /obj/structure/wall_torch, // NOVA EDIT ADDITION - Wall-mounted torches /obj/machinery/barsign, /obj/structure/extinguisher_cabinet, + /obj/structure/fish_mount, /obj/structure/fireaxecabinet, /obj/structure/mirror, /obj/structure/noticeboard, diff --git a/code/__HELPERS/hud.dm b/code/__HELPERS/hud.dm new file mode 100644 index 000000000000..d7d053c40bb1 --- /dev/null +++ b/code/__HELPERS/hud.dm @@ -0,0 +1,13 @@ +/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5) + var/x_off = IS_LEFT_INDEX(i) ? 0 : -1 + var/y_off = round((i-1) / 2) + return"CENTER+[x_off]:16,SOUTH+[y_off]:5" + +/proc/ui_swaphand_position(mob/M, which = LEFT_HANDS) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5) + var/x_off = (which == LEFT_HANDS) ? -1 : null + var/y_off = round((M.held_items.len-1) / 2) + return "CENTER[x_off]:16,SOUTH+[y_off+1]:5" + +/proc/ui_perk_position(perk_count) + var/y_off = perk_count < 1 ? 0 : perk_count/2 + return "WEST+0.5:12,NORTH-2-[y_off]:20" diff --git a/code/__HELPERS/logging/_logging.dm b/code/__HELPERS/logging/_logging.dm index b18d13f903cd..4cea02482741 100644 --- a/code/__HELPERS/logging/_logging.dm +++ b/code/__HELPERS/logging/_logging.dm @@ -233,11 +233,11 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global")) if(key) if(C?.holder && C.holder.fakekey && !include_name) if(include_link) - . += "" + . += "" . += "Administrator" else if(include_link) - . += "" + . += "" . += key if(!C) . += "\[DC\]" diff --git a/code/__HELPERS/logging/attack.dm b/code/__HELPERS/logging/attack.dm index 16fd656137fa..2e2b7a77f49d 100644 --- a/code/__HELPERS/logging/attack.dm +++ b/code/__HELPERS/logging/attack.dm @@ -80,5 +80,5 @@ GLOB.bombers += bomb_message var/area/bomb_area = get_area(bomb) - if(message_admins && !(bomb_area.area_flags & QUIET_LOGS)) // Don't spam the logs with deathmatch bombs + if(message_admins && !(bomb_area?.area_flags & QUIET_LOGS)) // Don't spam the logs with deathmatch bombs message_admins("[user ? "[ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(user)] " : ""][details][bomb ? " [bomb.name] at [ADMIN_VERBOSEJMP(bomb)]": ""][additional_details ? " [additional_details]" : ""].") diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 27d3c5d38ab6..fbd76a1d0bef 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -249,7 +249,3 @@ for(var/zero in 1 to how_many_zeros) zeros += "0" return "[zeros][number]" - -/// 180s an angle -/proc/reverse_angle(angle) - return (angle + 180) % 360 diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 47286c26c57d..1755c382dd47 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(skin_tone_names, list( var/atom/target_loc = target?.loc var/drifting = FALSE - if(GLOB.move_manager.processing_on(user, SSnewtonian_movement)) + if(!isnull(user.drift_handler)) drifting = TRUE var/holding = user.get_active_held_item() @@ -287,7 +287,7 @@ GLOBAL_LIST_INIT(skin_tone_names, list( if(!QDELETED(progbar)) progbar.update(world.time - starttime) - if(drifting && !GLOB.move_manager.processing_on(user, SSnewtonian_movement)) + if(drifting && isnull(user.drift_handler)) drifting = FALSE user_loc = user.loc diff --git a/code/__HELPERS/movement.dm b/code/__HELPERS/movement.dm index e820b3dfff12..49b7fb35432b 100644 --- a/code/__HELPERS/movement.dm +++ b/code/__HELPERS/movement.dm @@ -1,2 +1,5 @@ /// Converts w_class into newtons from throwing it, in (0.6 ~ 2.2) range #define WEIGHT_TO_NEWTONS(w_class, arguments...) 0.2 NEWTONS + w_class * 0.4 NEWTONS + +/// Converts movement delay into drift force required to achieve that speed +#define MOVE_DELAY_TO_DRIFT(move_delay) ((DEFAULT_INERTIA_SPEED / move_delay - 1) / INERTIA_SPEED_COEF + 1) diff --git a/code/__HELPERS/paths/path.dm b/code/__HELPERS/paths/path.dm index da1c9917b6be..5e29757e9f86 100644 --- a/code/__HELPERS/paths/path.dm +++ b/code/__HELPERS/paths/path.dm @@ -264,8 +264,8 @@ * Passed into CanAStarPass to provide context for a pathing attempt * * Also used to check if using a cached path_map is safe - * There are some vars here that are unused. They exist to cover cases where caller_ref is used - * They're the properties of caller_ref used in those cases. + * There are some vars here that are unused. They exist to cover cases where requester_ref is used + * They're the properties of requester_ref used in those cases. * It's kinda annoying, but there's some proc chains we can't convert to this datum */ /datum/can_pass_info @@ -314,7 +314,7 @@ /// Weakref to the requester used to generate this info /// Should not use this almost ever, it's for context and to allow for proc chains that /// Require a movable - var/datum/weakref/caller_ref = null + var/datum/weakref/requester_ref = null /datum/can_pass_info/New(atom/movable/construct_from, list/access, no_id = FALSE, call_depth = 0) // No infiniloops @@ -327,7 +327,7 @@ if(isnull(construct_from)) return - src.caller_ref = WEAKREF(construct_from) + src.requester_ref = WEAKREF(construct_from) src.pass_flags = construct_from.pass_flags src.movement_type = construct_from.movement_type src.thrown = !!construct_from.throwing @@ -361,8 +361,8 @@ GLOBAL_LIST_INIT(can_pass_info_vars, GLOBAL_PROC_REF(can_pass_check_vars)) var/datum/isaac = new() var/list/altar = assoc_to_keys(lamb.vars - isaac.vars) // Don't compare against calling atom, it's not relevant here - altar -= "caller_ref" - ASSERT("caller_ref" in lamb.vars, "caller_ref var was not found in /datum/can_pass_info, why are we filtering for it?") + altar -= "requester_ref" + ASSERT("requester_ref" in lamb.vars, "requester_ref var was not found in /datum/can_pass_info, why are we filtering for it?") // We will bespoke handle pulling_info altar -= "pulling_info" ASSERT("pulling_info" in lamb.vars, "pulling_info var was not found in /datum/can_pass_info, why are we filtering for it?") diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index cd375f2b3328..89f28bdde0d8 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -346,7 +346,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) if(GLOB.round_id) var/statspage = CONFIG_GET(string/roundstatsurl) - var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id + var/info = statspage ? "[GLOB.round_id]" : GLOB.round_id parts += "[FOURSPACES]Round ID: [info]" parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[FOURSPACES]Station Integrity: [GLOB.station_was_nuked ? span_redtext("Destroyed") : "[popcount["station_integrity"]]%"]" @@ -677,7 +677,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) var/datum/action/report/R = new C.player_details.player_actions += R R.Grant(C.mob) - to_chat(C,span_infoplain("Show roundend report again")) + to_chat(C,span_infoplain("Show roundend report again")) /datum/action/report name = "Show roundend report" diff --git a/code/__HELPERS/shuttle.dm b/code/__HELPERS/shuttle.dm new file mode 100644 index 000000000000..4f866e22384d --- /dev/null +++ b/code/__HELPERS/shuttle.dm @@ -0,0 +1,52 @@ +/// Helper proc that tests to ensure all whiteship templates can spawn at their docking port, and logs their sizes +/// This should be a unit test, but too much of our other code breaks during shuttle movement, so not yet, not yet. +/proc/test_whiteship_sizes() + var/obj/docking_port/stationary/port_type = /obj/docking_port/stationary/picked/whiteship + var/datum/turf_reservation/docking_yard = SSmapping.request_turf_block_reservation( + initial(port_type.width), + initial(port_type.height), + 1, + ) + var/turf/bottom_left = docking_yard.bottom_left_turfs[1] + var/turf/spawnpoint = locate( + bottom_left.x + initial(port_type.dwidth), + bottom_left.y + initial(port_type.dheight), + bottom_left.z, + ) + + var/obj/docking_port/stationary/picked/whiteship/port = new(spawnpoint) + var/list/ids = port.shuttlekeys + var/height = 0 + var/width = 0 + var/dheight = 0 + var/dwidth = 0 + var/delta_height = 0 + var/delta_width = 0 + for(var/id in ids) + var/datum/map_template/shuttle/our_template = SSmapping.shuttle_templates[id] + // We do a standard load here so any errors will properly runtimes + var/obj/docking_port/mobile/ship = SSshuttle.action_load(our_template, port) + if(ship) + ship.jumpToNullSpace() + ship = null + // Yes this is very hacky, but we need to both allow loading a template that's too big to be an error state + // And actually get the sizing information from every shuttle + SSshuttle.load_template(our_template) + var/obj/docking_port/mobile/theoretical_ship = SSshuttle.preview_shuttle + if(theoretical_ship) + height = max(theoretical_ship.height, height) + width = max(theoretical_ship.width, width) + dheight = max(theoretical_ship.dheight, dheight) + dwidth = max(theoretical_ship.dwidth, dwidth) + delta_height = max(theoretical_ship.height - theoretical_ship.dheight, delta_height) + delta_width = max(theoretical_ship.width - theoretical_ship.dwidth, delta_width) + theoretical_ship.jumpToNullSpace() + qdel(port, TRUE) + log_world("Whiteship sizing information. Use this to set the docking port, and the map size\n\ + Max Height: [height] \n\ + Max Width: [width] \n\ + Max DHeight: [dheight] \n\ + Max DWidth: [dwidth] \n\ + The following are the safest bet for map sizing. Anything smaller then this could in the worst case not fit in the docking port\n\ + Max Combined Width: [height + dheight] \n\ + Max Combinded Height [width + dwidth]") diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 03d308e34d63..aae96c386014 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -99,6 +99,9 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, else return null +///Returns a single dir rotated by x degrees clockwise, adhering to the cardinal directions. +#define turn_cardinal(dir, rotation) ( angle2dir_cardinal ( dir2angle(dir) + rotation ) ) + //Returns the angle in english /proc/angle2text(degree) return dir2text(angle2dir(degree)) diff --git a/code/_experiments.dm b/code/_experiments.dm index 8cc5edb429c3..c7fdad2f7887 100644 --- a/code/_experiments.dm +++ b/code/_experiments.dm @@ -17,6 +17,6 @@ #define EXPERIMENT_MY_COOL_FEATURE #endif -#if DM_VERSION >= 516 - #error "Remove all 515 experiments" +#if DM_VERSION >= 517 + #error "Remove all 516 experiments" #endif diff --git a/code/_globalvars/lists/pipe_recipes.dm b/code/_globalvars/lists/pipe_recipes.dm new file mode 100644 index 000000000000..384248623bc1 --- /dev/null +++ b/code/_globalvars/lists/pipe_recipes.dm @@ -0,0 +1,70 @@ +GLOBAL_LIST_INIT(atmos_pipe_recipes, list( + "Pipes" = list( + new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/smart, TRUE), + new /datum/pipe_info/pipe("Layer Adapter", /obj/machinery/atmospherics/pipe/layer_manifold, TRUE), + new /datum/pipe_info/pipe("Color Adapter", /obj/machinery/atmospherics/pipe/color_adapter, TRUE), + new /datum/pipe_info/pipe("Bridge Pipe", /obj/machinery/atmospherics/pipe/bridge_pipe, TRUE), + new /datum/pipe_info/pipe("Multi-Deck Adapter", /obj/machinery/atmospherics/pipe/multiz, FALSE), + ), + "Binary" = list( + new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve, TRUE), + new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital, TRUE), + new /datum/pipe_info/pipe("Gas Pump", /obj/machinery/atmospherics/components/binary/pump, TRUE), + new /datum/pipe_info/pipe("Volume Pump", /obj/machinery/atmospherics/components/binary/volume_pump, TRUE), + new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate, TRUE), + new /datum/pipe_info/pipe("Pressure Valve", /obj/machinery/atmospherics/components/binary/pressure_valve, TRUE), + new /datum/pipe_info/pipe("Temperature Gate", /obj/machinery/atmospherics/components/binary/temperature_gate, TRUE), + new /datum/pipe_info/pipe("Temperature Pump", /obj/machinery/atmospherics/components/binary/temperature_pump, TRUE), + ), + "Devices" = list( + new /datum/pipe_info/pipe("Gas Filter", /obj/machinery/atmospherics/components/trinary/filter, TRUE), + new /datum/pipe_info/pipe("Gas Mixer", /obj/machinery/atmospherics/components/trinary/mixer, TRUE), + new /datum/pipe_info/pipe("Connector", /obj/machinery/atmospherics/components/unary/portables_connector, TRUE), + new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector, TRUE), + new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber, TRUE), + new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump, TRUE), + new /datum/pipe_info/pipe("Passive Vent", /obj/machinery/atmospherics/components/unary/passive_vent, TRUE), + new /datum/pipe_info/meter("Meter"), + ), + "Heat Exchange" = list( + new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/heat_exchanging/simple, FALSE), + new /datum/pipe_info/pipe("Manifold", /obj/machinery/atmospherics/pipe/heat_exchanging/manifold, FALSE), + new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w, FALSE), + new /datum/pipe_info/pipe("Junction", /obj/machinery/atmospherics/pipe/heat_exchanging/junction, FALSE), + new /datum/pipe_info/pipe("Heat Exchanger", /obj/machinery/atmospherics/components/unary/heat_exchanger, FALSE), + ) +)) + +GLOBAL_LIST_INIT(disposal_pipe_recipes, list( + "Disposal Pipes" = list( + new /datum/pipe_info/disposal("Pipe", /obj/structure/disposalpipe/segment, PIPE_BENDABLE), + new /datum/pipe_info/disposal("Junction", /obj/structure/disposalpipe/junction, PIPE_TRIN_M), + new /datum/pipe_info/disposal("Y-Junction", /obj/structure/disposalpipe/junction/yjunction), + new /datum/pipe_info/disposal("Sort Junction", /obj/structure/disposalpipe/sorting/mail, PIPE_TRIN_M), + new /datum/pipe_info/disposal("Rotator", /obj/structure/disposalpipe/rotator, PIPE_ONEDIR_FLIPPABLE), + new /datum/pipe_info/disposal("Trunk", /obj/structure/disposalpipe/trunk), + new /datum/pipe_info/disposal("Down Turn", /obj/structure/disposalpipe/trunk/multiz/down), + new /datum/pipe_info/disposal("Up Turn", /obj/structure/disposalpipe/trunk/multiz), + new /datum/pipe_info/disposal("Bin", /obj/machinery/disposal/bin, PIPE_ONEDIR), + new /datum/pipe_info/disposal("Outlet", /obj/structure/disposaloutlet), + new /datum/pipe_info/disposal("Chute", /obj/machinery/disposal/delivery_chute), + ) +)) + +GLOBAL_LIST_INIT(transit_tube_recipes, list( + "Transit Tubes" = list( + new /datum/pipe_info/transit("Straight Tube", /obj/structure/c_transit_tube, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Straight Tube with Crossing", /obj/structure/c_transit_tube/crossing, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Curved Tube", /obj/structure/c_transit_tube/curved, PIPE_UNARY_FLIPPABLE), + new /datum/pipe_info/transit("Diagonal Tube", /obj/structure/c_transit_tube/diagonal, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Diagonal Tube with Crossing", /obj/structure/c_transit_tube/diagonal/crossing, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Junction", /obj/structure/c_transit_tube/junction, PIPE_UNARY_FLIPPABLE), + ), + "Station Equipment" = list( + new /datum/pipe_info/transit("Through Tube Station", /obj/structure/c_transit_tube/station, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Terminus Tube Station", /obj/structure/c_transit_tube/station/reverse, PIPE_UNARY_FLIPPABLE), + new /datum/pipe_info/transit("Through Tube Dispenser Station", /obj/structure/c_transit_tube/station/dispenser, PIPE_STRAIGHT), + new /datum/pipe_info/transit("Terminus Tube Dispenser Station", /obj/structure/c_transit_tube/station/dispenser/reverse, PIPE_UNARY_FLIPPABLE), + new /datum/pipe_info/transit("Transit Tube Pod", /obj/structure/c_transit_tube_pod, PIPE_ONEDIR), + ) +)) diff --git a/code/_globalvars/pipe_info.dm b/code/_globalvars/pipe_info.dm new file mode 100644 index 000000000000..5e0f279d314b --- /dev/null +++ b/code/_globalvars/pipe_info.dm @@ -0,0 +1,106 @@ +///Pipe info +/datum/pipe_info + ///Name of this pipe + var/name + ///Icon state of this pipe + var/icon_state + ///Type path of this recipe + var/id = -1 + /// see code/__DEFINES/pipe_construction.dm + var/dirtype = PIPE_BENDABLE + /// Is this pipe layer indenpendent + var/all_layers + +/datum/pipe_info/pipe/New(label, obj/machinery/atmospherics/path, use_five_layers) + name = label + id = path + all_layers = use_five_layers + icon_state = initial(path.pipe_state) + var/obj/item/pipe/c = initial(path.construction_type) + dirtype = initial(c.RPD_type) + +/** + * Get preview image of an pipe + * Arguments + * + * * selected_dir - the direction of the pipe to get preview of + * * selected - is this pipe meant to be highlighted in the UI + */ +/datum/pipe_info/proc/get_preview(selected_dir, selected = FALSE) + SHOULD_BE_PURE(TRUE) + + var/list/dirs + switch(dirtype) + if(PIPE_STRAIGHT, PIPE_BENDABLE) + dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal") + if(dirtype == PIPE_BENDABLE) + dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East", + "[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South") + if(PIPE_TRINARY) + dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West", + "[EAST]" = "North West South", "[WEST]" = "South East North") + if(PIPE_TRIN_M) + dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South", + "[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North", + "[WEST]" = "West North East", "[SOUTHEAST]" = "West South East", + "[NORTHWEST]" = "East North West", "[EAST]" = "East South West",) + if(PIPE_UNARY) + dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East") + if(PIPE_ONEDIR) + dirs = list("[SOUTH]" = name) + if(PIPE_UNARY_FLIPPABLE) + dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West", + "[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped") + if(PIPE_ONEDIR_FLIPPABLE) + dirs = list("[SOUTH]" = name, "[SOUTHEAST]" = "[name] Flipped") + + var/list/rows = list() + for(var/dir in dirs) + var/numdir = text2num(dir) + var/flipped = ((dirtype == PIPE_TRIN_M) || (dirtype == PIPE_UNARY_FLIPPABLE) || (dirtype == PIPE_ONEDIR_FLIPPABLE)) && (ISDIAGONALDIR(numdir)) + var/is_variant_selected = selected && (!selected_dir ? FALSE : (dirtype == PIPE_ONEDIR ? TRUE : (numdir == selected_dir))) + rows += list(list( + "selected" = is_variant_selected, + "dir" = dir2text(numdir), + "dir_name" = dirs[dir], + "icon_state" = icon_state, + "flipped" = flipped, + )) + + return rows + +//============================================================================================== + +///Meter pipe info +/datum/pipe_info/meter + icon_state = "meter" + dirtype = PIPE_ONEDIR + all_layers = TRUE + +/datum/pipe_info/meter/New(label) + name = label + +//============================================================================================== + +///Disposal pipe info +/datum/pipe_info/disposal/New(label, obj/path, dt=PIPE_UNARY) + name = label + id = path + + icon_state = initial(path.icon_state) + if(ispath(path, /obj/structure/disposalpipe)) + icon_state = "con[icon_state]" + + dirtype = dt + + +//============================================================================================== + +///Transient tube pipe info +/datum/pipe_info/transit/New(label, obj/path, dt=PIPE_UNARY) + name = label + id = path + dirtype = dt + icon_state = initial(path.icon_state) + if(dt == PIPE_UNARY_FLIPPABLE) + icon_state = "[icon_state]_preview" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 45c85d0bdc5c..cf5b7f32edfd 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -48,7 +48,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CHASM_STOPPER" = TRAIT_CHASM_STOPPER, "TRAIT_COMBAT_MODE_SKIP_INTERACTION" = TRAIT_COMBAT_MODE_SKIP_INTERACTION, "TRAIT_DEL_ON_SPACE_DUMP" = TRAIT_DEL_ON_SPACE_DUMP, - "TRAIT_VALID_DNA_INFUSION" = TRAIT_VALID_DNA_INFUSION, "TRAIT_FROZEN" = TRAIT_FROZEN, "TRAIT_HAS_LABEL" = TRAIT_HAS_LABEL, "TRAIT_HEARING_SENSITIVE" = TRAIT_HEARING_SENSITIVE, @@ -57,34 +56,37 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_IRRADIATED" = TRAIT_IRRADIATED, "TRAIT_IS_AQUARIUM" = TRAIT_IS_AQUARIUM, "TRAIT_LAVA_IMMUNE" = TRAIT_LAVA_IMMUNE, + "TRAIT_MOPABLE" = TRAIT_MOPABLE, "TRAIT_MOVE_FLOATING" = TRAIT_MOVE_FLOATING, "TRAIT_MOVE_FLYING" = TRAIT_MOVE_FLYING, "TRAIT_MOVE_GROUND" = TRAIT_MOVE_GROUND, "TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, - "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, + "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, + "TRAIT_NOT_BARFABLE" = TRAIT_NOT_BARFABLE, + "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, "TRAIT_NO_FLOATING_ANIM" = TRAIT_NO_FLOATING_ANIM, "TRAIT_NO_MANIFEST_CONTENTS_ERROR" = TRAIT_NO_MANIFEST_CONTENTS_ERROR, "TRAIT_NO_MISSING_ITEM_ERROR" = TRAIT_NO_MISSING_ITEM_ERROR, "TRAIT_NO_THROW_HITPUSH" = TRAIT_NO_THROW_HITPUSH, - "TRAIT_NOT_BARFABLE" = TRAIT_NOT_BARFABLE, - "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, "TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT" = TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, "TRAIT_ON_HIT_EFFECT" = TRAIT_ON_HIT_EFFECT, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, "TRAIT_SCARY_FISHERMAN" = TRAIT_SCARY_FISHERMAN, "TRAIT_SECLUDED_LOCATION" = TRAIT_SECLUDED_LOCATION, + "TRAIT_SILENT_REACTIONS" = TRAIT_SILENT_REACTIONS, "TRAIT_SNOWSTORM_IMMUNE" = TRAIT_SNOWSTORM_IMMUNE, "TRAIT_SPELLS_TRANSFER_TO_LOC" = TRAIT_SPELLS_TRANSFER_TO_LOC, "TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH" = TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, + "TRAIT_STOP_FISH_FLOPPING" = TRAIT_STOP_FISH_FLOPPING, "TRAIT_TELEKINESIS_CONTROLLED" = TRAIT_TELEKINESIS_CONTROLLED, "TRAIT_UNDERFLOOR" = TRAIT_UNDERFLOOR, "TRAIT_UNIQUE_IMMERSE" = TRAIT_UNIQUE_IMMERSE, + "TRAIT_VALID_DNA_INFUSION" = TRAIT_VALID_DNA_INFUSION, "TRAIT_WADDLING" = TRAIT_WADDLING, "TRAIT_WAS_RENAMED" = TRAIT_WAS_RENAMED, "TRAIT_WEATHER_IMMUNE" = TRAIT_WEATHER_IMMUNE, - "TRAIT_SILENT_REACTIONS" = TRAIT_SILENT_REACTIONS, ), /datum/controller/subsystem/economy = list( "TRAIT_MARKET_CRASHING" = TRAIT_MARKET_CRASHING, @@ -152,7 +154,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE, "TRAIT_ALLOWED_HONORBOUND_ATTACK" = TRAIT_ALLOWED_HONORBOUND_ATTACK, "TRAIT_ALLOW_HERETIC_CASTING" = TRAIT_ALLOW_HERETIC_CASTING, - "TRAIT_ALWAYS_NO_ACCESS" = TRAIT_ALWAYS_NO_ACCESS, "TRAIT_ALWAYS_WANTED" = TRAIT_ALWAYS_WANTED, "TRAIT_ANALGESIA" = TRAIT_ANALGESIA, "TRAIT_ANGELIC" = TRAIT_ANGELIC, @@ -206,6 +207,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CLUMSY" = TRAIT_CLUMSY, "TRAIT_COAGULATING" = TRAIT_COAGULATING, "TRAIT_CORPSELOCKED" = TRAIT_CORPSELOCKED, + "TRAIT_COMBAT_MODE_LOCK" = TRAIT_COMBAT_MODE_LOCK, "TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION, "TRAIT_CULT_HALO" = TRAIT_CULT_HALO, "TRAIT_CURSED" = TRAIT_CURSED, @@ -496,6 +498,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SNOB" = TRAIT_SNOB, "TRAIT_SOFTSPOKEN" = TRAIT_SOFTSPOKEN, "TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT, + "TRAIT_SOUND_DEBUGGED" = TRAIT_SOUND_DEBUGGED, "TRAIT_SPACEWALK" = TRAIT_SPACEWALK, "TRAIT_SPARRING" = TRAIT_SPARRING, "TRAIT_SPEAKS_CLEARLY" = TRAIT_SPEAKS_CLEARLY, @@ -672,6 +675,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FISH_QUICK_GROWTH" = TRAIT_FISH_QUICK_GROWTH, "TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE, "TRAIT_RESIST_EMULSIFY" = TRAIT_RESIST_EMULSIFY, + "TRAIT_RESIST_PSYCHIC" = TRAIT_RESIST_PSYCHIC, "TRAIT_FISH_WELL_COOKED" = TRAIT_FISH_WELL_COOKED, "TRAIT_YUCKY_FISH" = TRAIT_YUCKY_FISH, ), @@ -680,6 +684,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROD_IGNORE_ENVIRONMENT" = TRAIT_ROD_IGNORE_ENVIRONMENT, "TRAIT_ROD_LAVA_USABLE" = TRAIT_ROD_LAVA_USABLE, "TRAIT_ROD_REMOVE_FISHING_DUD" = TRAIT_ROD_REMOVE_FISHING_DUD, + "TRAIT_ROD_MANSUS_INFUSED" = TRAIT_ROD_MANSUS_INFUSED, ), /obj/item/integrated_circuit = list( "TRAIT_CIRCUIT_UI_OPEN" = TRAIT_CIRCUIT_UI_OPEN, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index af56b3a10eda..cf1e09597db8 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -38,7 +38,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, "TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE, "TRAIT_ALLOW_HERETIC_CASTING" = TRAIT_ALLOW_HERETIC_CASTING, - "TRAIT_ALWAYS_NO_ACCESS" = TRAIT_ALWAYS_NO_ACCESS, "TRAIT_ALWAYS_WANTED" = TRAIT_ALWAYS_WANTED, "TRAIT_ANOSMIA" = TRAIT_ANOSMIA, "TRAIT_ANTENNAE" = TRAIT_ANTENNAE, @@ -381,6 +380,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_ROD_IGNORE_ENVIRONMENT" = TRAIT_ROD_IGNORE_ENVIRONMENT, "TRAIT_ROD_LAVA_USABLE" = TRAIT_ROD_LAVA_USABLE, "TRAIT_ROD_REMOVE_FISHING_DUD" = TRAIT_ROD_REMOVE_FISHING_DUD, + "TRAIT_ROD_MANSUS_INFUSED" = TRAIT_ROD_MANSUS_INFUSED, ), /obj/item/organ/liver = list( "TRAIT_BALLMER_SCIENTIST" = TRAIT_BALLMER_SCIENTIST, diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 71d8a81b397c..5d092cbc1f6b 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -3,6 +3,7 @@ var/datum/hud/our_hud var/actiontooltipstyle = "" screen_loc = null + mouse_over_pointer = MOUSE_HAND_POINTER /// The icon state of our active overlay, used to prevent re-applying identical overlays var/active_overlay_icon_state @@ -109,32 +110,37 @@ last_hovored_ref = null if(!can_use(usr)) return + var/datum/hud/our_hud = usr.hud_used if(over_object == src) our_hud.hide_landings() return + if(istype(over_object, /atom/movable/screen/action_landing)) var/atom/movable/screen/action_landing/reserve = over_object reserve.hit_by(src) - our_hud.hide_landings() save_position() + our_hud.hide_landings() return - our_hud.hide_landings() if(istype(over_object, /atom/movable/screen/button_palette) || istype(over_object, /atom/movable/screen/palette_scroll)) our_hud.position_action(src, SCRN_OBJ_IN_PALETTE) save_position() + our_hud.hide_landings() return + if(istype(over_object, /atom/movable/screen/movable/action_button)) var/atom/movable/screen/movable/action_button/button = over_object our_hud.position_action_relative(src, button) save_position() + our_hud.hide_landings() return . = ..() our_hud.position_action(src, screen_loc) save_position() + our_hud.hide_landings() /atom/movable/screen/movable/action_button/proc/save_position() var/mob/user = our_hud.mymob @@ -269,6 +275,7 @@ icon = 'icons/hud/64x16_actions.dmi' icon_state = "screen_gen_palette" screen_loc = ui_action_palette + mouse_over_pointer = MOUSE_HAND_POINTER var/datum/hud/our_hud var/expanded = FALSE /// Id of any currently running timers that set our color matrix @@ -288,6 +295,7 @@ /atom/movable/screen/button_palette/proc/set_hud(datum/hud/our_hud) src.our_hud = our_hud refresh_owner() + disable_landing() // If our hud already has elements, don't force hide us /atom/movable/screen/button_palette/update_name(updates) . = ..() @@ -309,6 +317,15 @@ icon_state = "[ui_name]_palette" +/atom/movable/screen/button_palette/proc/activate_landing() + // Reveal ourselves to the user + invisibility = INVISIBILITY_NONE + +/atom/movable/screen/button_palette/proc/disable_landing() + // If we have no elements in the palette, hide your ugly self please + if (!length(our_hud.palette_actions?.actions)) + invisibility = INVISIBILITY_ABSTRACT + /atom/movable/screen/button_palette/MouseEntered(location, control, params) . = ..() if(QDELETED(src)) @@ -394,6 +411,7 @@ GLOBAL_LIST_INIT(palette_removed_matrix, list(1.4,0,0,0, 0.7,0.4,0,0, 0.4,0,0.6, /atom/movable/screen/palette_scroll icon = 'icons/hud/screen_gen.dmi' screen_loc = ui_palette_scroll + mouse_over_pointer = MOUSE_HAND_POINTER /// How should we move the palette's actions? /// Positive scrolls down the list, negative scrolls back var/scroll_direction = 0 diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index aaad7457f6d3..0a4cf277712b 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ai icon = 'icons/hud/screen_ai.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ai/Click() if(isobserver(usr) || usr.incapacitated) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 73916264a8b3..373e9534ec52 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -122,6 +122,7 @@ . = ..() if(clickable_glow) add_filter("clickglow", 2, outline_filter(color = COLOR_GOLD, size = 1)) + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/alert/MouseEntered(location,control,params) . = ..() @@ -318,7 +319,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /// The offer we're linked to, yes this is suspiciously like a status effect alert var/datum/status_effect/offering/offer /// Additional text displayed in the description of the alert. - var/additional_desc_text = "Click this alert to take it, or shift click it to examiante it." + var/additional_desc_text = "Click this alert to take it, or shift click it to examine it." /// Text to override what appears in screentips for the alert var/screentip_override_text /// Whether the offered item can be examined by shift-clicking the alert @@ -1135,7 +1136,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." return FALSE var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat - to_chat(usr, examine_block(jointext(examine(usr), "\n"))) + to_chat(usr, boxed_message(jointext(examine(usr), "\n"))) return FALSE var/datum/our_master = master_ref?.resolve() if(our_master && click_master) diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index b9a0e3bf655f..20e1e72f950f 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -39,13 +39,13 @@ using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_1" - using.screen_loc = ui_swaphand_position(owner,1) + using.screen_loc = ui_swaphand_position(owner, 1) static_inventory += using using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner,2) + using.screen_loc = ui_swaphand_position(owner, 2) static_inventory += using action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) @@ -61,7 +61,6 @@ floor_change = new /atom/movable/screen/floor_changer(null, src) floor_change.icon = ui_style - floor_change.screen_loc = ui_above_intent static_inventory += floor_change using = new/atom/movable/screen/language_menu(null, src) @@ -77,11 +76,11 @@ using.screen_loc = ui_drop_throw static_inventory += using - using = new /atom/movable/screen/resist(null, src) - using.icon = ui_style - using.screen_loc = ui_above_movement - using.update_appearance() - hotkeybuttons += using + resist_icon = new /atom/movable/screen/resist(null, src) + resist_icon.icon = ui_style + resist_icon.screen_loc = ui_above_movement + resist_icon.update_appearance() + hotkeybuttons += resist_icon throw_icon = new /atom/movable/screen/throw_catch(null, src) throw_icon.icon = ui_style diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index bb2b9fcb14ae..922953b01a36 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -12,7 +12,6 @@ floor_change = new /atom/movable/screen/floor_changer(null, src) floor_change.icon = ui_style - floor_change.screen_loc = ui_above_intent static_inventory += floor_change healths = new /atom/movable/screen/healths/alien(null, src) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 8f8193a50451..7a876cf7911c 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -1,6 +1,7 @@ /atom/movable/screen/blob icon = 'icons/hud/blob.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/blob/MouseEntered(location,control,params) . = ..() @@ -182,11 +183,11 @@ static_inventory += using using = new /atom/movable/screen/blob/node_blob(null, src) - using.screen_loc = ui_hand_position(2) + using.screen_loc = ui_hand_position(RIGHT_HANDS) static_inventory += using using = new /atom/movable/screen/blob/factory_blob(null, src) - using.screen_loc = ui_hand_position(1) + using.screen_loc = ui_hand_position(LEFT_HANDS) static_inventory += using using = new /atom/movable/screen/blob/readapt_strain(null, src) diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index 4048fd91b16f..134f91a2b8d4 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -3,11 +3,6 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/drop(null, src) - using.icon = ui_style - using.screen_loc = ui_drone_drop - static_inventory += using - pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style pull_icon.update_appearance() @@ -16,21 +11,20 @@ build_hand_slots() - using = new /atom/movable/screen/swap_hand(null, src) + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style - using.icon_state = "swap_1_m" - using.screen_loc = ui_swaphand_position(owner,1) + using.screen_loc = ui_swaphand_position(owner, 1) static_inventory += using using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style - using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner,2) + using.icon_state = "act_swap" + using.screen_loc = ui_swaphand_position(owner, 2) static_inventory += using action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) action_intent.icon = ui_style - action_intent.screen_loc = ui_combat_toggle + action_intent.screen_loc = ui_movi static_inventory += action_intent floor_change = new /atom/movable/screen/floor_changer(null, src) diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index 9f90076a3ac7..3ee08df77cb8 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,5 +1,6 @@ /atom/movable/screen/ghost icon = 'icons/hud/screen_ghost.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ghost/MouseEntered(location, control, params) . = ..() @@ -118,4 +119,3 @@ if (istype(O) && O.observetarget) return . = ..() - diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index ba1d8f4565e6..68a480d47f8f 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -15,11 +15,11 @@ infodisplay += healths using = new /atom/movable/screen/guardian/manifest(null, src) - using.screen_loc = ui_hand_position(2) + using.screen_loc = ui_hand_position(RIGHT_HANDS) static_inventory += using using = new /atom/movable/screen/guardian/recall(null, src) - using.screen_loc = ui_hand_position(1) + using.screen_loc = ui_hand_position(LEFT_HANDS) static_inventory += using using = new owner.toggle_button_type(null, src) @@ -101,6 +101,7 @@ /atom/movable/screen/guardian icon = 'icons/hud/guardian.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/guardian/manifest icon_state = "manifest" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 8f43f90d83f5..637237801b3c 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -42,6 +42,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/pull_icon var/atom/movable/screen/rest_icon var/atom/movable/screen/throw_icon + var/atom/movable/screen/resist_icon var/atom/movable/screen/module_store_icon var/atom/movable/screen/floor_change @@ -107,6 +108,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( // and avoid needing to make changes to all idk 300 consumers if we want to change the appearance var/list/asset_refs_for_reuse = list() + /// The BYOND version of the client that was last logged into this mob. + /// Currently used to rebuild all plane master groups when going between 515<->516. + var/last_byond_version + /datum/hud/New(mob/owner) mymob = owner @@ -154,13 +159,17 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/client_refresh(datum/source) SIGNAL_HANDLER var/client/client = mymob.canon_client - if(client.rebuild_plane_masters) - var/new_relay_loc = (client.byond_version > 515) ? "1,1" : "CENTER" + var/new_byond_version = client.byond_version +#if MIN_COMPILER_VERSION > 515 + #warn Fully change default relay_loc to "1,1", rather than changing it based on client version +#endif + if(!isnull(last_byond_version) && new_byond_version != last_byond_version) + var/new_relay_loc = (new_byond_version > 515) ? "1,1" : "CENTER" for(var/group_key as anything in master_groups) var/datum/plane_master_group/group = master_groups[group_key] group.relay_loc = new_relay_loc - group.rebuild_plane_masters() - client.rebuild_plane_masters = FALSE + group.rebuild_hud() + last_byond_version = new_byond_version RegisterSignal(client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) on_eye_change(null, null, client.eye) @@ -511,12 +520,17 @@ GLOBAL_LIST_INIT(available_ui_styles, list( static_inventory += hand_box hand_box.update_appearance() - var/i = 1 - for(var/atom/movable/screen/swap_hand/SH in static_inventory) - SH.screen_loc = ui_swaphand_position(mymob,!(i % 2) ? 2: 1) - i++ - for(var/atom/movable/screen/human/equip/E in static_inventory) - E.screen_loc = ui_equip_position(mymob) + var/num_of_swaps = 0 + for(var/atom/movable/screen/swap_hand/swap_hands in static_inventory) + num_of_swaps += 1 + + var/hand_num = 1 + for(var/atom/movable/screen/swap_hand/swap_hands in static_inventory) + var/hand_ind = RIGHT_HANDS + if (num_of_swaps > 1) + hand_ind = IS_RIGHT_INDEX(hand_num) ? LEFT_HANDS : RIGHT_HANDS + swap_hands.screen_loc = ui_swaphand_position(mymob, hand_ind) + hand_num += 1 if(ismob(mymob) && mymob.hud_used == src) show_hud(hud_version) @@ -587,11 +601,13 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/generate_landings(atom/movable/screen/movable/action_button/button) listed_actions.generate_landing() palette_actions.generate_landing() + toggle_palette.activate_landing() /// Clears all currently visible landings /datum/hud/proc/hide_landings() listed_actions.clear_landing() palette_actions.clear_landing() + toggle_palette.disable_landing() // Updates any existing "owned" visuals, ensures they continue to be visible /datum/hud/proc/update_our_owner() diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index bf460c97fea7..2d25bef65642 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -4,6 +4,8 @@ /atom/movable/screen/human/toggle name = "toggle" icon_state = "toggle" + base_icon_state = "toggle" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/human/toggle/Click() @@ -22,16 +24,11 @@ usr.client.screen += targetmob.hud_used.toggleable_inventory targetmob.hud_used.hidden_inventory_update(usr) + update_appearance() -/atom/movable/screen/human/equip - name = "equip" - icon_state = "act_equip" - -/atom/movable/screen/human/equip/Click() - if(ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE - var/mob/living/carbon/human/H = usr - H.quick_equip() +/atom/movable/screen/human/toggle/update_icon_state() + icon_state = "[base_icon_state][hud?.inventory_shown ? "_active" : ""]" + return ..() /atom/movable/screen/ling icon = 'icons/hud/screen_changeling.dmi' @@ -45,6 +42,7 @@ name = "current sting" screen_loc = ui_lingstingdisplay invisibility = INVISIBILITY_ABSTRACT + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/ling/sting/Click() if(isobserver(usr)) @@ -60,14 +58,17 @@ using = new /atom/movable/screen/language_menu(null, src) using.icon = ui_style + using.screen_loc = ui_human_language static_inventory += using using = new /atom/movable/screen/navigate(null, src) using.icon = ui_style + using.screen_loc = ui_human_navigate static_inventory += using using = new /atom/movable/screen/area_creator(null, src) using.icon = ui_style + using.screen_loc = ui_human_area static_inventory += using action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) @@ -75,23 +76,17 @@ action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent - floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change = new /atom/movable/screen/floor_changer/vertical(null, src) floor_change.icon = ui_style floor_change.screen_loc = ui_human_floor_changer static_inventory += floor_change - using = new /atom/movable/screen/mov_intent(null, src) using.icon = ui_style using.icon_state = (owner.move_intent == MOVE_INTENT_RUN ? "running" : "walking") using.screen_loc = ui_movi static_inventory += using - using = new /atom/movable/screen/drop(null, src) - using.icon = ui_style - using.screen_loc = ui_drop_throw - static_inventory += using - inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "uniform" inv_box.icon = ui_style @@ -112,16 +107,15 @@ build_hand_slots() - using = new /atom/movable/screen/swap_hand(null, src) + using = new /atom/movable/screen/drop(null, src) using.icon = ui_style - using.icon_state = "swap_1" - using.screen_loc = ui_swaphand_position(owner,1) + using.screen_loc = ui_swaphand_position(owner, 1) static_inventory += using using = new /atom/movable/screen/swap_hand(null, src) using.icon = ui_style - using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner,2) + using.icon_state = "act_swap" + using.screen_loc = ui_swaphand_position(owner, 2) static_inventory += using inv_box = new /atom/movable/screen/inventory(null, src) @@ -187,21 +181,16 @@ inv_box.slot_id = ITEM_SLOT_SUITSTORE static_inventory += inv_box - using = new /atom/movable/screen/resist(null, src) - using.icon = ui_style - using.screen_loc = ui_above_intent - hotkeybuttons += using + resist_icon = new /atom/movable/screen/resist(null, src) + resist_icon.icon = ui_style + resist_icon.screen_loc = ui_above_movement + hotkeybuttons += resist_icon using = new /atom/movable/screen/human/toggle(null, src) using.icon = ui_style using.screen_loc = ui_inventory static_inventory += using - using = new /atom/movable/screen/human/equip() - using.icon = ui_style - using.screen_loc = ui_equip_position(mymob) - static_inventory += using - inv_box = new /atom/movable/screen/inventory(null, src) inv_box.name = "gloves" inv_box.icon = ui_style @@ -263,7 +252,7 @@ rest_icon = new /atom/movable/screen/rest(null, src) rest_icon.icon = ui_style - rest_icon.screen_loc = ui_above_movement + rest_icon.screen_loc = ui_rest rest_icon.update_appearance() static_inventory += rest_icon @@ -284,7 +273,7 @@ pull_icon = new /atom/movable/screen/pull(null, src) pull_icon.icon = ui_style - pull_icon.screen_loc = ui_above_intent + pull_icon.screen_loc = ui_above_movement_top pull_icon.update_appearance() static_inventory += pull_icon @@ -336,8 +325,6 @@ var/obj/item/organ/eyes/eyes = human_mob.get_organ_slot(ORGAN_SLOT_EYES) if(eyes?.no_glasses) blocked_slots |= ITEM_SLOT_EYES - if(human_mob.bodyshape & BODYSHAPE_DIGITIGRADE) - blocked_slots |= ITEM_SLOT_FEET for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(!inv.slot_id) diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index fea3ed049bca..327397837d5b 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -118,8 +118,9 @@ screen_loc = "TOP,CENTER:-61" /atom/movable/screen/lobby/button + mouse_over_pointer = MOUSE_HAND_POINTER ///Is the button currently enabled? - var/enabled = TRUE + VAR_PROTECTED/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE ///Should this button play the select sound? @@ -183,6 +184,7 @@ return FALSE enabled = status update_appearance(UPDATE_ICON) + mouse_over_pointer = enabled ? MOUSE_HAND_POINTER : MOUSE_INACTIVE_POINTER return TRUE ///Prefs menu @@ -258,12 +260,13 @@ icon = 'icons/hud/lobby/join.dmi' icon_state = "" //Default to not visible base_icon_state = "join_game" - enabled = FALSE + enabled = null // set in init /atom/movable/screen/lobby/button/join/Initialize(mapload, datum/hud/hud_owner) . = ..() switch(SSticker.current_state) if(GAME_STATE_PREGAME, GAME_STATE_STARTUP) + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_SETTING_UP, PROC_REF(show_join_button)) if(GAME_STATE_SETTING_UP) set_button_status(TRUE) @@ -329,13 +332,14 @@ icon = 'icons/hud/lobby/observe.dmi' icon_state = "observe_disabled" base_icon_state = "observe" - enabled = FALSE + enabled = null // set in init /atom/movable/screen/lobby/button/observe/Initialize(mapload, datum/hud/hud_owner) . = ..() if(SSticker.current_state > GAME_STATE_STARTUP) set_button_status(TRUE) else + set_button_status(FALSE) RegisterSignal(SSticker, COMSIG_TICKER_ENTER_PREGAME, PROC_REF(enable_observing)) /atom/movable/screen/lobby/button/observe/Click(location, control, params) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 09b224f58851..8126141a0dfd 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -1,6 +1,3 @@ -#define NEXT_PAGE_ID "__next__" -#define DEFAULT_CHECK_DELAY 20 - GLOBAL_LIST_EMPTY(radial_menus) /atom/movable/screen/radial @@ -113,7 +110,7 @@ GLOBAL_LIST_EMPTY(radial_menus) var/hudfix_method = TRUE //TRUE to change anchor to user, FALSE to shift by py_shift var/py_shift = 0 - var/entry_animation = TRUE + var/button_animation_flags = BUTTON_SLIDE_IN ///A replacement icon state for the generic radial slice bg icon. Doesn't affect the next page nor the center buttons var/radial_slice_icon @@ -164,6 +161,8 @@ GLOBAL_LIST_EMPTY(radial_menus) new_element.icon = icon_path // NOVA EDIT ADDITION - GUNPOINT new_element.tooltips = use_tooltips new_element.set_parent(src) + if(button_animation_flags & BUTTON_FADE_IN) + new_element.alpha = 0 elements += new_element var/page = 1 @@ -187,9 +186,9 @@ GLOBAL_LIST_EMPTY(radial_menus) page_data[page] = current pages = page current_page = clamp(set_page, 1, pages) - update_screen_objects(entry_animation, click_on_hover) + update_screen_objects(button_animation_flags, click_on_hover) -/datum/radial_menu/proc/update_screen_objects(anim = FALSE, click_on_hover = FALSE) +/datum/radial_menu/proc/update_screen_objects(anim_flag = NONE, click_on_hover = FALSE) var/list/page_choices = page_data[current_page] var/angle_per_element = round(zone / page_choices.len) for(var/i in 1 to elements.len) @@ -199,11 +198,11 @@ GLOBAL_LIST_EMPTY(radial_menus) HideElement(element) element.click_on_hover = FALSE else - SetElement(element,page_choices[i],angle,anim = anim,anim_order = i) + SetElement(element,page_choices[i],angle,anim_flag = anim_flag,anim_order = i) // Only activate click on hover after the animation plays if (!click_on_hover) continue - if (anim) + if (anim_flag) addtimer(VARSET_CALLBACK(element, click_on_hover, TRUE), i * 0.5) else element.click_on_hover = TRUE @@ -218,11 +217,11 @@ GLOBAL_LIST_EMPTY(radial_menus) E.choice = null E.next_page = FALSE -/datum/radial_menu/proc/SetElement(atom/movable/screen/radial/slice/E,choice_id,angle,anim,anim_order) +/datum/radial_menu/proc/SetElement(atom/movable/screen/radial/slice/E, choice_id, angle, anim_flag, anim_order) //Position var/py = round(cos(angle) * radius) + py_shift var/px = round(sin(angle) * radius) - if(anim) + if(anim_flag & BUTTON_SLIDE_IN) var/timing = anim_order * 0.5 var/matrix/starting = matrix() starting.Scale(0.1,0.1) @@ -233,8 +232,11 @@ GLOBAL_LIST_EMPTY(radial_menus) E.pixel_y = py E.pixel_x = px - //Visuals - E.alpha = 255 + if(anim_flag & BUTTON_FADE_IN) + animate(E, alpha = 255, time = 0.15 SECONDS, easing = EASE_OUT) + else + E.alpha = 255 + E.mouse_opacity = MOUSE_OPACITY_ICON E.cut_overlays() E.vis_contents.Cut() @@ -267,7 +269,9 @@ GLOBAL_LIST_EMPTY(radial_menus) info_button.layer = RADIAL_CONTENT_LAYER E.vis_contents += info_button -/datum/radial_menu/New() +/datum/radial_menu/New(display_close_button) + if(!display_close_button) + return close_button = new close_button.set_parent(src) @@ -328,7 +332,9 @@ GLOBAL_LIST_EMPTY(radial_menus) menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER, pixel_x = offset_x, pixel_y = offset_y) SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM - menu_holder.vis_contents += elements + close_button + menu_holder.vis_contents += elements + if(!isnull(close_button)) + menu_holder.vis_contents += close_button current_user.images += menu_holder /datum/radial_menu/proc/hide() @@ -346,6 +352,14 @@ GLOBAL_LIST_EMPTY(radial_menus) next_check = world.time + check_delay stoplag(1) +/datum/radial_menu/proc/remove_menu() + if(!(button_animation_flags & BUTTON_FADE_OUT)) + qdel(src) + return + for(var/atom/movable/element as anything in elements) + animate(element, alpha = 0, time = 0.15 SECONDS) + QDEL_IN(src, 0.5 SECONDS) + /datum/radial_menu/Destroy() Reset() hide() @@ -357,11 +371,11 @@ GLOBAL_LIST_EMPTY(radial_menus) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE, user_space = FALSE) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, button_animation_flags = BUTTON_SLIDE_IN, click_on_hover = FALSE, user_space = FALSE, check_delay = DEFAULT_CHECK_DELAY, display_close_button = TRUE, radial_menu_offset = list(0, 0)) if(!user || !anchor || !length(choices)) return - if(length(choices)==1 && autopick_single_option) + if(length(choices) == 1 && autopick_single_option) return choices[1] if(!uniqueid) @@ -373,8 +387,9 @@ GLOBAL_LIST_EMPTY(radial_menus) menu.finished = TRUE return - var/datum/radial_menu/menu = new - menu.entry_animation = entry_animation + var/datum/radial_menu/menu = new(display_close_button) + menu.button_animation_flags = button_animation_flags + menu.check_delay = check_delay GLOB.radial_menus[uniqueid] = menu if(radius) menu.radius = radius @@ -391,10 +406,12 @@ GLOBAL_LIST_EMPTY(radial_menus) var/turf/anchor_turf = get_turf(anchor) offset_x = (anchor_turf.x - user_turf.x) * ICON_SIZE_X + anchor.pixel_x - user.pixel_x offset_y = (anchor_turf.y - user_turf.y) * ICON_SIZE_Y + anchor.pixel_y - user.pixel_y + offset_x += radial_menu_offset[1] + offset_y += radial_menu_offset[2] menu.show_to(user, offset_x, offset_y) menu.wait(user, anchor, require_near) var/answer = menu.selected_choice - qdel(menu) + menu.remove_menu() GLOB.radial_menus -= uniqueid if(require_near && !in_range(anchor, user)) return diff --git a/code/_onclick/hud/radial_persistent.dm b/code/_onclick/hud/radial_persistent.dm index 5fe81d005bd4..d48c8d9eb456 100644 --- a/code/_onclick/hud/radial_persistent.dm +++ b/code/_onclick/hud/radial_persistent.dm @@ -43,7 +43,7 @@ /datum/radial_menu/persistent/proc/change_choices(list/newchoices, tooltips = FALSE, animate = FALSE, keep_same_page = FALSE) if(!newchoices.len) return - entry_animation = FALSE + button_animation_flags = NONE var/target_page = keep_same_page ? current_page : 1 //Stores the current_page value before it's set back to 1 on Reset() Reset() set_choices(newchoices,tooltips, set_page = target_page) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index a304a84b43a3..35319bc89eda 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,5 +1,6 @@ /atom/movable/screen/robot icon = 'icons/hud/screen_cyborg.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/robot/module name = "cyborg module" diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 3fb31890c638..a83aae088eab 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -103,6 +103,7 @@ /atom/movable/screen/swap_hand plane = HUD_PLANE name = "swap hand" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/swap_hand/Click() // At this point in client Click() code we have passed the 1/10 sec check and little else @@ -123,6 +124,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "navigate" screen_loc = ui_navigate_menu + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/navigate/Click() if(!isliving(usr)) @@ -141,6 +143,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "area_edit" screen_loc = ui_building + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/area_creator/Click() if(usr.incapacitated || (isobserver(usr) && !isAdminGhostAI(usr))) @@ -156,6 +159,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "talk_wheel" screen_loc = ui_language_menu + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/language_menu/Click() usr.get_language_holder().open_language_menu(usr) @@ -241,7 +245,7 @@ . = ..() if(!handcuff_overlay) - var/state = (!(held_index % 2)) ? "markus" : "gabrielle" + var/state = IS_RIGHT_INDEX(held_index) ? "markus" : "gabrielle" handcuff_overlay = mutable_appearance('icons/hud/screen_gen.dmi', state) if(!hud?.mymob) @@ -257,7 +261,7 @@ . += blocked_overlay if(held_index == hud.mymob.active_hand_index) - . += (held_index % 2) ? "lhandactive" : "rhandactive" + . += IS_LEFT_INDEX(held_index) ? "lhandactive" : "rhandactive" /atom/movable/screen/inventory/hand/Click(location, control, params) // At this point in client Click() code we have passed the 1/10 sec check and little else @@ -285,6 +289,7 @@ plane = ABOVE_HUD_PLANE icon = 'icons/hud/screen_midnight.dmi' icon_state = "storage_close" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/close/Initialize(mapload, datum/hud/hud_owner, new_master) . = ..() @@ -302,6 +307,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_drop" plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/drop/Click() if(usr.stat == CONSCIOUS) @@ -312,6 +318,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "combat_off" screen_loc = ui_combat_toggle + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/combattoggle/Initialize(mapload, datum/hud/hud_owner) . = ..() @@ -357,7 +364,8 @@ name = "change floor" icon = 'icons/hud/screen_midnight.dmi' icon_state = "floor_change" - screen_loc = ui_floor_changer + screen_loc = ui_above_intent + mouse_over_pointer = MOUSE_HAND_POINTER var/vertical = FALSE /atom/movable/screen/floor_changer/Click(location,control,params) @@ -390,6 +398,7 @@ name = "run/walk toggle" icon = 'icons/hud/screen_midnight.dmi' icon_state = "running" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/mov_intent/Click() toggle(usr) @@ -415,6 +424,7 @@ icon = 'icons/hud/screen_midnight.dmi' icon_state = "pull" base_icon_state = "pull" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/pull/Click() if(isobserver(usr)) @@ -429,9 +439,12 @@ name = "resist" icon = 'icons/hud/screen_midnight.dmi' icon_state = "act_resist" + base_icon_state = "act_resist" plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/resist/Click() + flick("[base_icon_state]_on", src) if(isliving(usr)) var/mob/living/L = usr L.resist() @@ -442,6 +455,7 @@ icon_state = "act_rest" base_icon_state = "act_rest" plane = HUD_PLANE + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/rest/Click() if(isliving(usr)) @@ -452,7 +466,7 @@ var/mob/living/user = hud?.mymob if(!istype(user)) return ..() - icon_state = "[base_icon_state][user.resting ? 0 : null]" + icon_state = "[base_icon_state][user.resting ? "_on" : null]" return ..() /atom/movable/screen/storage @@ -525,7 +539,8 @@ /atom/movable/screen/throw_catch name = "throw/catch" icon = 'icons/hud/screen_midnight.dmi' - icon_state = "act_throw_off" + icon_state = "act_throw" + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/throw_catch/Click() if(iscarbon(usr)) @@ -536,6 +551,7 @@ name = "damage zone" icon_state = "zone_sel" screen_loc = ui_zonesel + mouse_over_pointer = MOUSE_HAND_POINTER var/overlay_icon = 'icons/hud/screen_gen.dmi' var/static/list/hover_overlays_cache = list() var/hovering @@ -713,6 +729,7 @@ /atom/movable/screen/healthdoll name = "health doll" screen_loc = ui_healthdoll + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/healthdoll/Click() if (iscarbon(usr)) @@ -810,6 +827,7 @@ name = "mood" icon_state = "mood5" screen_loc = ui_mood + mouse_over_pointer = MOUSE_HAND_POINTER /atom/movable/screen/splash icon = 'icons/blanks/blank_title.png' @@ -859,6 +877,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) /atom/movable/screen/component_button + mouse_over_pointer = MOUSE_HAND_POINTER var/atom/movable/screen/parent /atom/movable/screen/component_button/Initialize(mapload, atom/movable/screen/parent) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 7653da7f7755..e96017f6b4f8 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -444,21 +444,30 @@ else return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 -/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area, def_zone) - if(!I.force && !length(I.attack_verb_simple) && !length(I.attack_verb_continuous)) +/mob/living/proc/send_item_attack_message(obj/item/weapon, mob/living/user, hit_area, def_zone) + if(!weapon.force && !length(weapon.attack_verb_simple) && !length(weapon.attack_verb_continuous)) return - var/message_verb_continuous = length(I.attack_verb_continuous) ? "[pick(I.attack_verb_continuous)]" : "attacks" - var/message_verb_simple = length(I.attack_verb_simple) ? "[pick(I.attack_verb_simple)]" : "attack" - var/message_hit_area = get_hit_area_message(hit_area) - var/attack_message_spectator = "[src] [message_verb_continuous][message_hit_area] with [I]!" - var/attack_message_victim = "Something [message_verb_continuous] you[message_hit_area] with [I]!" - var/attack_message_attacker = "You [message_verb_simple] [src][message_hit_area] with [I]!" + // Sanity in case one is null for some reason + var/picked_index = rand(max(length(weapon.attack_verb_simple), length(weapon.attack_verb_continuous))) + + var/message_verb_continuous = "attacks" + var/message_verb_simple = "attack" + var/message_hit_area = get_hit_area_message(hit_area) + // Sanity in case one is... longer than the other? + if (picked_index && length(weapon.attack_verb_continuous) >= picked_index) + message_verb_continuous = weapon.attack_verb_continuous[picked_index] + if (picked_index && length(weapon.attack_verb_simple) >= picked_index) + message_verb_simple = weapon.attack_verb_simple[picked_index] + + var/attack_message_spectator = "[src] [message_verb_continuous][message_hit_area] with [weapon]!" + var/attack_message_victim = "Something [message_verb_continuous] you[message_hit_area] with [weapon]!" + var/attack_message_attacker = "You [message_verb_simple] [src][message_hit_area] with [weapon]!" if(user in viewers(src, null)) - attack_message_spectator = "[user] [message_verb_continuous] [src][message_hit_area] with [I]!" - attack_message_victim = "[user] [message_verb_continuous] you[message_hit_area] with [I]!" + attack_message_spectator = "[user] [message_verb_continuous] [src][message_hit_area] with [weapon]!" + attack_message_victim = "[user] [message_verb_continuous] you[message_hit_area] with [weapon]!" if(user == src) - attack_message_victim = "You [message_verb_simple] yourself[message_hit_area] with [I]." + attack_message_victim = "You [message_verb_simple] yourself[message_hit_area] with [weapon]." visible_message(span_danger("[attack_message_spectator]"),\ span_userdanger("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user) if(is_blind()) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 402a20cddc8d..f68ed1dacb67 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -327,7 +327,8 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie init_stage_completed = 0 var/mc_started = FALSE - add_startup_message("Initializing subsystems...") //NOVA EDIT CHANGE - Custom HTML Lobby Screen + // to_chat(world, span_boldannounce("Initializing subsystems..."), MESSAGE_TYPE_DEBUG) // NOVA EDIT REMOVAL + add_startup_message("Initializing subsystems...") // NOVA EDIT CHANGE - Custom HTML Lobby Screen var/list/stage_sorted_subsystems = new(INITSTAGE_MAX) for (var/i in 1 to INITSTAGE_MAX) @@ -369,7 +370,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!" - to_chat(world, span_boldannounce("[msg]")) + to_chat(world, span_boldannounce("[msg]"), MESSAGE_TYPE_DEBUG) log_world(msg) @@ -465,7 +466,8 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie // NOVA EDIT REMOVAL END if(result != SS_INIT_NO_MESSAGE) - add_startup_message(message, chat_warning) //NOVA EDIT CHANGE - ORIGINAL: to_chat(world, chat_message) + // to_chat(world, chat_message, MESSAGE_TYPE_DEBUG) // NOVA EDIT REMOVAL + add_startup_message(message, chat_warning) // NOVA EDIT ADDITION log_world(message) /datum/controller/master/proc/SetRunLevel(new_runlevel) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 21195550b435..15aabc66ff48 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -678,7 +678,7 @@ Ignore_errors instructes mysql to continue inserting rows if some of them have e /datum/db_query/proc/slow_query_check() - message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") + message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") /datum/db_query/proc/NextRow(async = TRUE) Activity("NextRow") diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm index 4958ddd434a8..904792b03e72 100644 --- a/code/controllers/subsystem/dynamic/dynamic.dm +++ b/code/controllers/subsystem/dynamic/dynamic.dm @@ -202,24 +202,24 @@ SUBSYSTEM_DEF(dynamic) VAR_PRIVATE/next_midround_injection /datum/controller/subsystem/dynamic/proc/admin_panel() - var/list/dat = list("Game Mode Panel

Game Mode Panel

") - dat += "Dynamic Mode \[VV\] \[Refresh\]
" + var/list/dat = list() + dat += "Dynamic Mode VVRefresh
" dat += "Threat Level: [threat_level]
" dat += "Budgets (Roundstart/Midrounds): [initial_round_start_budget]/[threat_level - initial_round_start_budget]
" - dat += "Midround budget to spend: [mid_round_budget] \[Adjust\] \[View Log\]
" + dat += "Midround budget to spend: [mid_round_budget] AdjustView Log
" dat += "
" dat += "Parameters: centre = [threat_curve_centre] ; width = [threat_curve_width].
" dat += "Split parameters: centre = [roundstart_split_curve_centre] ; width = [roundstart_split_curve_width].
" dat += "On average, [clamp(peaceful_percentage, 1, 99)]% of the rounds are more peaceful.
" - dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
" - dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
" - dat += "Stacking limit: [GLOB.dynamic_stacking_limit] \[Adjust\]" + dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
" + dat += "No stacking (only one round-ender): [GLOB.dynamic_no_stacking ? "On" : "Off"]
" + dat += "Stacking limit: [GLOB.dynamic_stacking_limit] Adjust" dat += "
" - dat += "\[Force Next Latejoin Ruleset\]
" + dat += "Force Next Latejoin Ruleset
" if (forced_latejoin_rule) - dat += {"-> [forced_latejoin_rule.name] <-
"} - dat += "\[Execute Midround Ruleset\]
" + dat += {"-> [forced_latejoin_rule.name] <-
"} + dat += "Execute Midround Ruleset
" dat += "
" dat += "Executed rulesets: " if (executed_rules.len > 0) @@ -229,15 +229,17 @@ SUBSYSTEM_DEF(dynamic) else dat += "none.
" dat += "
Injection Timers: ([get_heavy_midround_injection_chance(dry_run = TRUE)]% heavy midround chance)
" - dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] \[Now!\]
" + dat += "Latejoin: [DisplayTimeText(latejoin_injection_cooldown-world.time)] Now!
" var/next_injection = next_midround_injection() if (next_injection == INFINITY) dat += "All midrounds have been exhausted." else - dat += "Midround: [DisplayTimeText(next_injection - world.time)] \[Now!\]
" + dat += "Midround: [DisplayTimeText(next_injection - world.time)] Now!
" - usr << browse(dat.Join(), "window=gamemode_panel;size=500x500") + var/datum/browser/browser = new(usr, "gamemode_panel", "Game Mode Panel", 500, 500) + browser.set_content(dat.Join()) + browser.open() /datum/controller/subsystem/dynamic/Topic(href, href_list) if (..()) // Sanity, maybe ? diff --git a/code/controllers/subsystem/dynamic/ruleset_picking.dm b/code/controllers/subsystem/dynamic/ruleset_picking.dm index 1a77a0288daf..80a149beb31b 100644 --- a/code/controllers/subsystem/dynamic/ruleset_picking.dm +++ b/code/controllers/subsystem/dynamic/ruleset_picking.dm @@ -70,8 +70,8 @@ /** log_dynamic("[rule] ruleset executing...") message_admins("DYNAMIC: Executing midround ruleset [rule] in [DisplayTimeText(ADMIN_CANCEL_MIDROUND_TIME)]. \ - CANCEL | \ - SOMETHING ELSE") + CANCEL | \ + SOMETHING ELSE") return rule */ @@ -79,8 +79,8 @@ // NOVA EDIT ADDITION BEGIN - Event notification message_admins("Dynamic Event triggering in [DisplayTimeText(ADMIN_CANCEL_MIDROUND_TIME)]: [rule]. (\ - CANCEL | \ - SOMETHING ELSE)") + CANCEL | \ + SOMETHING ELSE)") for(var/client/staff as anything in GLOB.admins) if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) @@ -88,8 +88,8 @@ if(!midround_injection_timer_id == null) message_admins("Dynamic Event triggering in [DisplayTimeText(ADMIN_CANCEL_MIDROUND_TIME * 0.5)]: [rule]. (\ - CANCEL | \ - SOMETHING ELSE)") + CANCEL | \ + SOMETHING ELSE)") return rule // NOVA EDIT ADDITION END - Event notification diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index de731e32c656..e94e90f082a1 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -540,6 +540,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec /datum/controller/subsystem/explosions/proc/shake_the_room(turf/epicenter, near_distance, far_distance, quake_factor, echo_factor, creaking, sound/near_sound = sound(get_sfx(SFX_EXPLOSION)), sound/far_sound = sound('sound/effects/explosion/explosionfar.ogg'), sound/echo_sound = sound('sound/effects/explosion/explosion_distant.ogg'), sound/creaking_sound = sound(get_sfx(SFX_EXPLOSION_CREAKING)), hull_creaking_sound = sound(get_sfx(SFX_HULL_CREAKING))) var/frequency = get_rand_frequency() var/blast_z = epicenter.z + var/area/epicenter_area = get_area(epicenter) if(isnull(creaking)) // Autoset creaking. var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION) if(on_station && prob((quake_factor * QUAKE_CREAK_PROB) + (echo_factor * ECHO_CREAK_PROB))) // Huge explosions are near guaranteed to make the station creak and whine, smaller ones might. @@ -575,7 +576,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec base_shake_amount = max(base_shake_amount, quake_factor * 3, 0) // Devastating explosions rock the station and ground shake_camera(listener, FAR_SHAKE_DURATION, min(base_shake_amount, FAR_SHAKE_CAP)) - else if(!isspaceturf(listener_turf) && echo_factor) // Big enough explosions echo through the hull. + else if(!isspaceturf(listener_turf) && !(!(epicenter_area.type in GLOB.the_station_areas) && SSmapping.is_planetary()) && echo_factor) // Big enough explosions echo through the hull. Except on planetary maps if the epicenter is not on the station's area. var/echo_volume if(quake_factor) echo_volume = 60 diff --git a/code/controllers/subsystem/fluids.dm b/code/controllers/subsystem/fluids.dm index 6b68ae717222..2b4ce4729565 100644 --- a/code/controllers/subsystem/fluids.dm +++ b/code/controllers/subsystem/fluids.dm @@ -22,6 +22,7 @@ SUBSYSTEM_DEF(fluids) wait = 0 // Will be autoset to whatever makes the most sense given the spread and effect waits. flags = SS_KEEP_TIMING runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME + init_order = INIT_ORDER_FLUIDS priority = FIRE_PRIORITY_FLUIDS // Fluid spread processing: diff --git a/code/controllers/subsystem/lag_switch.dm b/code/controllers/subsystem/lag_switch.dm index f59ead3a99b0..05ce95bde4dc 100644 --- a/code/controllers/subsystem/lag_switch.dm +++ b/code/controllers/subsystem/lag_switch.dm @@ -34,7 +34,7 @@ SUBSYSTEM_DEF(lag_switch) auto_switch = FALSE UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT) veto_timer_id = addtimer(CALLBACK(src, PROC_REF(set_all_measures), TRUE, TRUE), 20 SECONDS, TIMER_STOPPABLE) - message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (CANCEL)") + message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (CANCEL)") log_admin("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds.") /// (En/Dis)able automatic triggering of switches based on client count diff --git a/code/controllers/subsystem/map_vote.dm b/code/controllers/subsystem/map_vote.dm index d5708cd9d087..fe88a638f6be 100644 --- a/code/controllers/subsystem/map_vote.dm +++ b/code/controllers/subsystem/map_vote.dm @@ -53,7 +53,7 @@ SUBSYSTEM_DEF(map_vote) last_message_at = world.time var/list/messages = args.Copy() - to_chat(world, span_purple(examine_block("Map Vote\n
\n[messages.Join("\n")]"))) + to_chat(world, span_purple(boxed_message("Map Vote\n
[messages.Join("\n")]"))) /datum/controller/subsystem/map_vote/proc/finalize_map_vote(datum/vote/map_vote/map_vote) if(already_voted) @@ -74,14 +74,9 @@ SUBSYSTEM_DEF(map_vote) send_map_vote_notice("Admin Override is in effect. Map will not be changed.", "Tallies are recorded and saved.") return - var/list/valid_maps = filter_cache_to_valid_maps() - if(!length(valid_maps)) - send_map_vote_notice("No valid maps.") - return - var/winner var/winner_amount = 0 - for(var/map in valid_maps) + for(var/map in map_vote.choices) if(!winner_amount) winner = map winner_amount = map_vote_cache[map] @@ -98,7 +93,7 @@ SUBSYSTEM_DEF(map_vote) messages += tally_printout // do not reset tallies if only one map is even possible - if(length(valid_maps) > 1) + if(length(map_vote.choices) > 1) map_vote_cache[winner] = CONFIG_GET(number/map_vote_minimum_tallies) write_cache() update_tally_printout() @@ -175,4 +170,4 @@ SUBSYSTEM_DEF(map_vote) for(var/map_id in map_vote_cache) var/datum/map_config/map = config.maplist[map_id] data += "[map.map_name] - [map_vote_cache[map_id]]" - tally_printout = examine_block("Current Tallies\n
\n[data.Join("\n")]") + tally_printout = boxed_message("Current Tallies\n
[data.Join("\n")]") diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index b9488b7346b1..e6b83aa4d1a0 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -243,23 +243,23 @@ SUBSYSTEM_DEF(mapping) // Generate mining ruins var/list/lava_ruins = levels_by_trait(ZTRAIT_LAVA_RUINS) if (lava_ruins.len) - seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), list(/area/lavaland/surface/outdoors/unexplored), themed_ruins[ZTRAIT_LAVA_RUINS], clear_below = TRUE, mineral_budget = 15, mineral_budget_update = OREGEN_PRESET_LAVALAND) + seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), list(/area/lavaland/surface/outdoors/unexplored), themed_ruins[ZTRAIT_LAVA_RUINS], clear_below = TRUE, mineral_budget = 15, mineral_budget_update = OREGEN_PRESET_LAVALAND, ruins_type = ZTRAIT_LAVA_RUINS) var/list/ice_ruins = levels_by_trait(ZTRAIT_ICE_RUINS) if (ice_ruins.len) // needs to be whitelisted for underground too so place_below ruins work - seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), themed_ruins[ZTRAIT_ICE_RUINS], clear_below = TRUE, mineral_budget = 4, mineral_budget_update = OREGEN_PRESET_TRIPLE_Z) + seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), themed_ruins[ZTRAIT_ICE_RUINS], clear_below = TRUE, mineral_budget = 4, mineral_budget_update = OREGEN_PRESET_TRIPLE_Z, ruins_type = ZTRAIT_ICE_RUINS) var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND) if (ice_ruins_underground.len) - seedRuins(ice_ruins_underground, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/underground/unexplored), themed_ruins[ZTRAIT_ICE_RUINS_UNDERGROUND], clear_below = TRUE, mineral_budget = 21) + seedRuins(ice_ruins_underground, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/underground/unexplored), themed_ruins[ZTRAIT_ICE_RUINS_UNDERGROUND], clear_below = TRUE, mineral_budget = 21, ruins_type = ZTRAIT_ICE_RUINS_UNDERGROUND) // Generate deep space ruins var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS) if (space_ruins.len) // Create a proportional budget by multiplying the amount of space ruin levels in the current map over the default amount var/proportional_budget = round(CONFIG_GET(number/space_budget) * (space_ruins.len / DEFAULT_SPACE_RUIN_LEVELS)) - seedRuins(space_ruins, proportional_budget, list(/area/space), themed_ruins[ZTRAIT_SPACE_RUINS], mineral_budget = 0) + seedRuins(space_ruins, proportional_budget, list(/area/space), themed_ruins[ZTRAIT_SPACE_RUINS], mineral_budget = 0, ruins_type = ZTRAIT_SPACE_RUINS) /// Sets up rivers, and things that behave like rivers. So lava/plasma rivers, and chasms /// It is important that this happens AFTER generating mineral walls and such, since we rely on them for river logic @@ -363,7 +363,7 @@ Used by the AI doomsday and the self-destruct nuke. multiz_levels = SSmapping.multiz_levels loaded_lazy_templates = SSmapping.loaded_lazy_templates -#define INIT_ANNOUNCE(X) to_chat(world, span_boldannounce("[X]")); log_world(X) +#define INIT_ANNOUNCE(X) to_chat(world, span_boldannounce("[X]"), MESSAGE_TYPE_DEBUG); log_world(X) /datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE, height_autosetup = TRUE) . = list() var/start_time = REALTIMEOFDAY @@ -589,13 +589,13 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away if(!mapfile) return away_name = "[mapfile] custom" - to_chat(user,span_notice("Loading [away_name]...")) + to_chat(user, span_notice("Loading [away_name]..."), MESSAGE_TYPE_DEBUG) var/datum/map_template/template = new(mapfile, "Away Mission") away_level = template.load_new_z(secret) else if(answer in GLOB.potentialRandomZlevels) away_name = answer - to_chat(user,span_notice("Loading [away_name]...")) + to_chat(user, span_notice("Loading [away_name]..."), MESSAGE_TYPE_DEBUG) var/datum/map_template/template = new(away_name, "Away Mission") away_level = template.load_new_z(secret) else @@ -905,7 +905,7 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away else start_time = REALTIMEOFDAY var/beginning_message = "Loading all away missions..." - to_chat(world, span_boldannounce(beginning_message)) + to_chat(world, span_boldannounce(beginning_message), MESSAGE_TYPE_DEBUG) log_world(beginning_message) log_mapping(beginning_message) @@ -923,7 +923,7 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away if(!isnull(start_time)) var/tracked_time = (REALTIMEOFDAY - start_time) / 10 var/finished_message = "Loaded [number_of_away_missions] away missions in [tracked_time] second[tracked_time == 1 ? "" : "s"]!" - to_chat(world, span_boldannounce(finished_message)) + to_chat(world, span_boldannounce(finished_message), MESSAGE_TYPE_DEBUG) log_world(finished_message) log_mapping(finished_message) diff --git a/code/controllers/subsystem/movement/newtonian_movement.dm b/code/controllers/subsystem/movement/newtonian_movement.dm index aeb03a576dae..e4143669678b 100644 --- a/code/controllers/subsystem/movement/newtonian_movement.dm +++ b/code/controllers/subsystem/movement/newtonian_movement.dm @@ -13,9 +13,10 @@ MOVEMENT_SUBSYSTEM_DEF(newtonian_movement) return ..() /datum/controller/subsystem/movement/newtonian_movement/fire(resumed = FALSE) - . = ..() - if (!resumed) + if(!resumed) + canonical_time = world.time currentrun = processing.Copy() + //cache for sanic speed (lists are references anyways) var/list/current_run = currentrun @@ -29,3 +30,21 @@ MOVEMENT_SUBSYSTEM_DEF(newtonian_movement) STOP_PROCESSING(src, thing) if (MC_TICK_CHECK) return + + for(var/list/bucket_info as anything in sorted_buckets) + var/time = bucket_info[MOVEMENT_BUCKET_TIME] + if(time > canonical_time || MC_TICK_CHECK) + return + pour_bucket(bucket_info) + +/datum/controller/subsystem/movement/newtonian_movement/proc/fire_moveloop(datum/move_loop/loop) + // Loop isn't even running right now + if(!(loop.status & MOVELOOP_STATUS_QUEUED)) + return + // Drop the loop, process it, and if its still valid - queue it again + dequeue_loop(loop) + loop.process() + if(QDELETED(loop)) + return + loop.timer = world.time + loop.delay + queue_loop(loop) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index e3d47a5c0cd6..c5754115a6e0 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -52,18 +52,18 @@ SUBSYSTEM_DEF(pai) return FALSE switch(action) if("submit") - candidate.comments = trim(params["comments"], MAX_BROADCAST_LEN) - candidate.description = trim(params["description"], MAX_BROADCAST_LEN) - candidate.name = trim(params["name"], MAX_NAME_LEN) + candidate.comments = reject_bad_name(params["comments"], allow_numbers = TRUE, max_length = MAX_BROADCAST_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" + candidate.description = reject_bad_name(params["description"], allow_numbers = TRUE, max_length = MAX_BROADCAST_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" + candidate.name = reject_bad_name(params["name"], allow_numbers = TRUE, max_length = MAX_NAME_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" candidate.ckey = user.ckey candidate.ready = TRUE ui.close() submit_alert(user) return TRUE if("save") - candidate.comments = params["comments"] - candidate.description = params["description"] - candidate.name = params["name"] + candidate.comments = reject_bad_name(params["comments"], allow_numbers = TRUE, max_length = MAX_BROADCAST_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" + candidate.description = reject_bad_name(params["description"], allow_numbers = TRUE, max_length = MAX_BROADCAST_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" + candidate.name = reject_bad_name(params["name"], allow_numbers = TRUE, max_length = MAX_NAME_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" candidate.savefile_save(user) return TRUE if("load") diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index 5de99066e28e..370246542be4 100644 --- a/code/controllers/subsystem/persistence/_persistence.dm +++ b/code/controllers/subsystem/persistence/_persistence.dm @@ -43,6 +43,9 @@ SUBSYSTEM_DEF(persistence) /// List of persistene ids which piggy banks. var/list/queued_broken_piggy_ids + /// json database linking to data/trophy_fishes.json, for persistent trophy fish mount. + var/datum/json_database/trophy_fishes_database + var/rounds_since_engine_exploded = 0 var/delam_highscore = 0 var/tram_hits_this_round = 0 diff --git a/code/controllers/subsystem/persistence/trophy_fishes.dm b/code/controllers/subsystem/persistence/trophy_fishes.dm new file mode 100644 index 000000000000..62fe8dfdfa09 --- /dev/null +++ b/code/controllers/subsystem/persistence/trophy_fishes.dm @@ -0,0 +1,71 @@ +#define PERSISTENCE_FISH_ID "fish_id" +#define PERSISTENCE_FISH_NAME "fish_name" +#define PERSISTENCE_FISH_SIZE "fish_size" +#define PERSISTENCE_FISH_WEIGHT "fish_weight" +#define PERSISTENCE_FISH_MATERIAL "fish_material" +#define PERSISTENCE_FISH_CATCHER "fish_catcher" +#define PERSISTENCE_FISH_CATCH_DATE "fish_catch_date" + +///Instantiate a fish, then set its size, weight, eventually materials and finally add it to the mount. +/datum/controller/subsystem/persistence/proc/load_trophy_fish(obj/structure/fish_mount/mount) + if(!mount.persistence_id) + return + if(isnull(trophy_fishes_database)) + trophy_fishes_database = new("data/trophy_fishes.json") + + var/list/data = trophy_fishes_database.get_key(mount.persistence_id) + if(!length(data)) + return + var/fish_id = data[PERSISTENCE_FISH_ID] + if(!fish_id) //For a reason or another, the id isn't there + return + var/fish_path = SSfishing.catchable_fish[fish_id] + if(!fish_path) //the fish was removed, uh uh. + return + var/obj/item/fish/fish = new fish_path(mount, /* apply_qualities = */ FALSE) + fish.fish_traits.Cut() + fish.update_size_and_weight(data[PERSISTENCE_FISH_SIZE], data[PERSISTENCE_FISH_WEIGHT]) + var/material_path = text2path(data[PERSISTENCE_FISH_MATERIAL]) + if(material_path) + //setting the list inside the proccall doesn't seem to work + var/list/mat_list = list(material_path = fish.weight) + fish.set_custom_materials(mat_list) + fish.persistence_load(data) + fish.name = data[PERSISTENCE_FISH_NAME] + mount.catcher_name = data[PERSISTENCE_FISH_CATCHER] + mount.catch_date = data[PERSISTENCE_FISH_CATCH_DATE] + fish.set_status(FISH_DEAD, silent = TRUE) + mount.add_fish(fish, from_persistence = TRUE, catcher = data[PERSISTENCE_FISH_CATCHER]) + +/datum/controller/subsystem/persistence/proc/save_trophy_fish(obj/structure/fish_mount/mount) + var/obj/item/fish/fish = mount.mounted_fish + if(!fish || !mount.persistence_id) + return + if(isnull(trophy_fishes_database)) + trophy_fishes_database = new("data/trophy_fishes.json") + + var/list/data = list() + var/fish_id = fish.fish_id + if(fish.fish_id_redirect_path) + var/obj/item/fish/other_path = fish.fish_id_redirect_path + fish_id = initial(other_path.fish_id) + + data[PERSISTENCE_FISH_ID] = fish_id + data[PERSISTENCE_FISH_NAME] = fish.name + data[PERSISTENCE_FISH_SIZE] = fish.size + data[PERSISTENCE_FISH_WEIGHT] = fish.weight / fish.material_weight_mult + var/datum/material/material = fish.get_master_material() + data[PERSISTENCE_FISH_MATERIAL] = "[material?.type]" + data[PERSISTENCE_FISH_CATCHER] = mount.catcher_name + data[PERSISTENCE_FISH_CATCH_DATE] = mount.catch_date + + fish.persistence_save(data) + trophy_fishes_database.set_key(mount.persistence_id, data) + +#undef PERSISTENCE_FISH_ID +#undef PERSISTENCE_FISH_NAME +#undef PERSISTENCE_FISH_SIZE +#undef PERSISTENCE_FISH_WEIGHT +#undef PERSISTENCE_FISH_MATERIAL +#undef PERSISTENCE_FISH_CATCHER +#undef PERSISTENCE_FISH_CATCH_DATE diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm index 52cd282bc44f..c9c7293f7bdb 100644 --- a/code/controllers/subsystem/polling.dm +++ b/code/controllers/subsystem/polling.dm @@ -148,14 +148,14 @@ SUBSYSTEM_DEF(polling) var/custom_link_style_start = "" var/custom_link_style_end = "style='color:DodgerBlue;font-weight:bold;-dm-text-outline: 1px black'" if(isatom(alert_pic) && isobserver(candidate_mob)) - act_jump = "[custom_link_style_start]\[Teleport\]" - var/act_signup = "[custom_link_style_start]\[[start_signed_up ? "Opt out" : "Sign Up"]\]" + act_jump = "[custom_link_style_start]\[Teleport\]" + var/act_signup = "[custom_link_style_start]\[[start_signed_up ? "Opt out" : "Sign Up"]\]" var/act_never = "" if(ignore_category) - act_never = "[custom_link_style_start]\[Never For This Round\]" + act_never = "[custom_link_style_start]\[Never For This Round\]" if(!duplicate_message_check(alert_poll)) //Only notify people once. They'll notice if there are multiple and we don't want to spam people. - SEND_SOUND(candidate_mob, 'sound/announcer/notice/notice2.ogg') + SEND_SOUND(candidate_mob, sound('sound/misc/prompt.ogg', volume = 70)) var/surrounding_icon if(chat_text_border_icon) var/image/surrounding_image @@ -165,7 +165,7 @@ SUBSYSTEM_DEF(polling) else surrounding_image = image(chat_text_border_icon) surrounding_icon = icon2html(surrounding_image, candidate_mob, extra_classes = "bigicon") - var/final_message = examine_block("[surrounding_icon] [span_ooc(question)] [surrounding_icon]\n[act_jump] [act_signup] [act_never]") + var/final_message = boxed_message("[surrounding_icon] [span_ooc(question)] [surrounding_icon]\n[act_jump] [act_signup] [act_never]") to_chat(candidate_mob, final_message) // Start processing it so it updates visually the timer diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 0d0deae2cc4a..c4cf2b8f2f41 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -389,7 +389,7 @@ SUBSYSTEM_DEF(shuttle) SSblackbox.record_feedback("text", "shuttle_reason", 1, "[call_reason]") log_shuttle("Shuttle call reason: [call_reason]") SSticker.emergency_reason = call_reason - message_admins("[ADMIN_LOOKUPFLW(user)] has called the shuttle. (TRIGGER CENTCOM RECALL)") + message_admins("[ADMIN_LOOKUPFLW(user)] has called the shuttle. (TRIGGER CENTCOM RECALL)") /// Call the emergency shuttle. /// If you are doing this on behalf of a player, use requestEvac instead. diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index cf924b55a86d..a8f1faf920eb 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -62,6 +62,15 @@ SUBSYSTEM_DEF(statpanels) var/ETA = SSshuttle.emergency.getModeStr() if(ETA) global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]" + + if(SSticker.reboot_timer) + var/reboot_time = timeleft(SSticker.reboot_timer) + if(reboot_time) + global_data += "Reboot: [DisplayTimeText(reboot_time, 1)]" + // admin must have delayed round end + else if(SSticker.ready_for_reboot) + global_data += "Reboot: DELAYED" + src.currentrun = GLOB.clients.Copy() mc_data = null @@ -117,11 +126,14 @@ SUBSYSTEM_DEF(statpanels) return /datum/controller/subsystem/statpanels/proc/set_status_tab(client/target) +#if MIN_COMPILER_VERSION > 515 + #warn 516 is most certainly out of beta, remove this beta notice if you haven't already +#endif + var/static/list/beta_notice = list("", "You are on the BYOND 516 beta, various UIs and such may be broken!", "Please report issues, and switch back to BYOND 515 if things are causing too many issues for you.") if(!global_data)//statbrowser hasnt fired yet and we were called from immediate_send_stat_data() return - target.stat_panel.send_message("update_stat", list( - "global_data" = global_data, + "global_data" = (target.byond_version < 516) ? global_data : (global_data + beta_notice), "ping_str" = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)", "other_str" = target.mob?.get_status_tab_items(), )) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index e06d080df298..1872c7f01843 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -67,8 +67,9 @@ SUBSYSTEM_DEF(ticker) /// Why an emergency shuttle was called var/emergency_reason + /// ID of round reboot timer, if it exists + var/reboot_timer = null var/real_round_start_time = 0 //NOVA EDIT ADDITION - var/discord_alerted = FALSE //NOVA EDIT - DISCORD PING SPAM PREVENTION /datum/controller/subsystem/ticker/Initialize() @@ -517,7 +518,7 @@ SUBSYSTEM_DEF(ticker) if(!hard_popcap) list_clear_nulls(queued_players) for (var/mob/dead/new_player/new_player in queued_players) - to_chat(new_player, span_userdanger("The alive players limit has been released!
[html_encode(">>Join Game<<")]")) + to_chat(new_player, span_userdanger("The alive players limit has been released!
[html_encode(">>Join Game<<")]")) SEND_SOUND(new_player, sound('sound/announcer/notice/notice1.ogg')) GLOB.latejoin_menu.ui_interact(new_player) queued_players.len = 0 @@ -532,7 +533,7 @@ SUBSYSTEM_DEF(ticker) list_clear_nulls(queued_players) if(living_player_count() < hard_popcap) if(next_in_line?.client) - to_chat(next_in_line, span_userdanger("A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<")) + to_chat(next_in_line, span_userdanger("A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<")) SEND_SOUND(next_in_line, sound('sound/announcer/notice/notice1.ogg')) next_in_line.ui_interact(next_in_line) return @@ -744,11 +745,10 @@ SUBSYSTEM_DEF(ticker) var/start_wait = world.time UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever - sleep(delay - (world.time - start_wait)) + reboot_timer = addtimer(CALLBACK(src, PROC_REF(reboot_callback), reason, end_string), delay - (world.time - start_wait), TIMER_STOPPABLE) - if(delay_end && !skip_delay) - to_chat(world, span_boldannounce("Reboot was cancelled by an admin.")) - return + +/datum/controller/subsystem/ticker/proc/reboot_callback(reason, end_string) if(end_string) end_state = end_string @@ -756,6 +756,21 @@ SUBSYSTEM_DEF(ticker) world.Reboot() +/** + * Deletes the current reboot timer and nulls the var + * + * Arguments: + * * user - the user that cancelled the reboot, may be null + */ +/datum/controller/subsystem/ticker/proc/cancel_reboot(mob/user) + if(!reboot_timer) + to_chat(user, span_warning("There is no pending reboot!")) + return FALSE + to_chat(world, span_boldannounce("An admin has delayed the round end.")) + deltimer(reboot_timer) + reboot_timer = null + return TRUE + /datum/controller/subsystem/ticker/Shutdown() gather_newscaster() //called here so we ensure the log is created even upon admin reboot if(!round_end_sound) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d0e642bd3aa2..d9d796782c2b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -119,7 +119,7 @@ SUBSYSTEM_DEF(vote) ) log_vote("vote finalized", vote_log_data) if(to_display) - to_chat(world, span_infoplain(vote_font("\n[to_display]"))) + to_chat(world, span_infoplain(vote_font("[to_display]"))) // Finally, doing any effects on vote completion current_vote.finalize_vote(final_winner) @@ -230,9 +230,9 @@ SUBSYSTEM_DEF(vote) var/to_display = current_vote.initiate_vote(vote_initiator_name, duration) log_vote(to_display) - to_chat(world, span_infoplain(vote_font("\n[span_bold(to_display)]\n\ + to_chat(world, custom_boxed_message("purple_box center", span_infoplain(vote_font("[span_bold(to_display)]
\ Type vote or click here to place your votes.\n\ - You have [DisplayTimeText(duration)] to vote."))) + You have [DisplayTimeText(duration)] to vote.")))) // And now that it's going, give everyone a voter action for(var/client/new_voter as anything in GLOB.clients) diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index 2f297f480ae6..18525a8c04e9 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -435,5 +435,5 @@ if(source.next_click > world.time) return else - source.next_click = world.time + CLICK_CD_RANGE + source.next_click = world.time + CLICK_CD_ACTIVATE_ABILITY INVOKE_ASYNC(src, PROC_REF(Trigger)) diff --git a/code/datums/actions/cooldown_action.dm b/code/datums/actions/cooldown_action.dm index 974009727870..c45fbda9fed5 100644 --- a/code/datums/actions/cooldown_action.dm +++ b/code/datums/actions/cooldown_action.dm @@ -250,7 +250,7 @@ return PreActivate(user) /// Intercepts client owner clicks to activate the ability -/datum/action/cooldown/proc/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/proc/InterceptClickOn(mob/living/clicker, params, atom/target) if(!IsAvailable(feedback = TRUE)) return FALSE if(!target) @@ -261,8 +261,8 @@ // And if we reach here, the action was complete successfully if(unset_after_click) - unset_click_ability(caller, refund_cooldown = FALSE) - caller.next_click = world.time + click_cd_override + unset_click_ability(clicker, refund_cooldown = FALSE) + clicker.next_click = world.time + click_cd_override return TRUE diff --git a/code/datums/actions/innate_action.dm b/code/datums/actions/innate_action.dm index c5271033bc6b..b907ba619579 100644 --- a/code/datums/actions/innate_action.dm +++ b/code/datums/actions/innate_action.dm @@ -76,17 +76,17 @@ on_who.click_intercept = null /// Handles whenever a mob clicks on something -/datum/action/innate/proc/InterceptClickOn(mob/living/caller, params, atom/clicked_on) +/datum/action/innate/proc/InterceptClickOn(mob/living/clicker, params, atom/clicked_on) if(!IsAvailable(feedback = TRUE)) - unset_ranged_ability(caller) + unset_ranged_ability(clicker) return FALSE if(!clicked_on) return FALSE - return do_ability(caller, clicked_on) + return do_ability(clicker, clicked_on) /// Actually goes through and does the click ability -/datum/action/innate/proc/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/proc/do_ability(mob/living/clicker, atom/clicked_on) return FALSE /datum/action/innate/Remove(mob/removed_from) diff --git a/code/datums/actions/mobs/projectileattack.dm b/code/datums/actions/mobs/projectileattack.dm index f833e05dde2e..8ac67bdecc49 100644 --- a/code/datums/actions/mobs/projectileattack.dm +++ b/code/datums/actions/mobs/projectileattack.dm @@ -399,7 +399,7 @@ /datum/action/cooldown/mob_cooldown/projectile_attack/wave/attack_sequence(mob/living/firer, atom/target) wendigo_scream(firer) - var/shots_per = 7 + var/shots_per = 6 var/difference = 360 / shots_per var/wave_direction = pick(-1, 1) switch(wave_direction) @@ -407,9 +407,9 @@ projectile_type = /obj/projectile/colossus/wendigo_shockwave/wave/alternate if(1) projectile_type = /obj/projectile/colossus/wendigo_shockwave/wave - for(var/shoot_times in 1 to 32) + for(var/shoot_times in 1 to 12) for(var/shot in 1 to shots_per) var/angle = shot * difference + shoot_times * 5 * wave_direction * -1 shoot_projectile(firer, target, angle, firer, null, null) - SLEEP_CHECK_DEATH(2, firer) + SLEEP_CHECK_DEATH(0.6 SECONDS, firer) SLEEP_CHECK_DEATH(3 SECONDS, firer) diff --git a/code/datums/ai/babies/babies_behaviors.dm b/code/datums/ai/babies/babies_behaviors.dm index aa8a15a03e40..c12f4acc6fac 100644 --- a/code/datums/ai/babies/babies_behaviors.dm +++ b/code/datums/ai/babies/babies_behaviors.dm @@ -1,45 +1,48 @@ +#define FIND_PARTNER_COOLDOWN 1 MINUTES + /** * Find a compatible, living partner, if we're also alone. */ /datum/ai_behavior/find_partner + action_cooldown = 5 SECONDS /// Range to look. var/range = 7 - /// Maximum number of children - var/max_children = 3 + /// Maximum number of nearby pop + var/max_nearby_pop = 3 /datum/ai_behavior/find_partner/perform(seconds_per_tick, datum/ai_controller/controller, target_key, partner_types_key, child_types_key) - max_children = controller.blackboard[BB_MAX_CHILDREN] || max_children + var/maximum_pop = controller.blackboard[BB_MAX_CHILDREN] || max_nearby_pop var/mob/pawn_mob = controller.pawn - var/list/partner_types = controller.blackboard[partner_types_key] - var/list/child_types = controller.blackboard[child_types_key] + var/list/similar_species_types = controller.blackboard[partner_types_key] + controller.blackboard[child_types_key] var/mob/living/living_pawn = controller.pawn + var/list/possible_partners = list() - var/children = 0 + var/nearby_pop = 0 for(var/mob/living/other in oview(range, pawn_mob)) if(!pawn_mob.faction_check_atom(other)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - if(children >= max_children) - return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - - if(other.stat != CONSCIOUS) //Check if it's conscious FIRST. + if(!is_type_in_list(other, similar_species_types)) continue - if(is_type_in_list(other, child_types)) //Check for children SECOND. - children++ - continue + if(++nearby_pop >= maximum_pop) + controller.set_blackboard_key(BB_PARTNER_SEARCH_TIMEOUT, world.time + FIND_PARTNER_COOLDOWN) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - if(!is_type_in_list(other, partner_types) || !HAS_TRAIT(other, TRAIT_MOB_BREEDER)) + if(!HAS_TRAIT(other, TRAIT_MOB_BREEDER) || other.ckey) continue - if(other.ckey) + if(other.stat != CONSCIOUS) //Check if it's conscious FIRST. continue if(other.gender != living_pawn.gender && !(other.flags_1 & HOLOGRAM_1)) //Better safe than sorry ;_; - controller.set_blackboard_key(target_key, other) - return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED + possible_partners += other - return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + if(!length(possible_partners)) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + + controller.set_blackboard_key(target_key, pick(possible_partners)) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED /** * Reproduce. @@ -64,3 +67,5 @@ /datum/ai_behavior/make_babies/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() controller.clear_blackboard_key(target_key) + +#undef FIND_PARTNER_COOLDOWN diff --git a/code/datums/ai/babies/babies_subtrees.dm b/code/datums/ai/babies/babies_subtrees.dm index 1b7fe5b88cb5..60ca7dc8193a 100644 --- a/code/datums/ai/babies/babies_subtrees.dm +++ b/code/datums/ai/babies/babies_subtrees.dm @@ -11,7 +11,7 @@ /datum/ai_planning_subtree/make_babies/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() - if(!SPT_PROB(chance, seconds_per_tick)) + if(!SPT_PROB(chance, seconds_per_tick) || controller.blackboard[BB_PARTNER_SEARCH_TIMEOUT] >= world.time) return if(controller.blackboard_key_exists(BB_BABIES_TARGET)) @@ -21,14 +21,7 @@ if(controller.pawn.gender == FEMALE || !controller.blackboard[BB_BREED_READY]) return - var/partner_types = controller.blackboard[BB_BABIES_PARTNER_TYPES] - var/baby_types = controller.blackboard[BB_BABIES_CHILD_TYPES] - - if(!partner_types || !baby_types) - return - - // Baby can't reproduce - if(is_type_in_list(controller.pawn, baby_types)) + if(!controller.blackboard[BB_BABIES_PARTNER_TYPES] || !controller.blackboard[BB_BABIES_CHILD_TYPES]) return // Find target diff --git a/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm b/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm index 6cae6132d368..4d7a3e7ad306 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/express_happiness.dm @@ -31,11 +31,11 @@ var/list/final_list switch(happiness_value) if(HIGH_HAPPINESS_THRESHOLD to INFINITY) - final_list = happy_emotions + final_list = controller.blackboard[BB_HAPPY_EMOTIONS] || happy_emotions if(MODERATE_HAPPINESS_THRESHOLD to HIGH_HAPPINESS_THRESHOLD) - final_list = moderate_emotions + final_list = controller.blackboard[BB_MODERATE_EMOTIONS] || moderate_emotions else - final_list = depressed_emotions + final_list = controller.blackboard[BB_SAD_EMOTIONS] || depressed_emotions if(!length(final_list)) return controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(final_list)) diff --git a/code/datums/ai/dog/dog_controller.dm b/code/datums/ai/dog/dog_controller.dm index a5794ff9b5f4..0aaaede44cb8 100644 --- a/code/datums/ai/dog/dog_controller.dm +++ b/code/datums/ai/dog/dog_controller.dm @@ -25,7 +25,7 @@ // With tongs in hand! BB_TARGET_HELD_ITEM = /obj/item/kitchen/tongs, BB_BABIES_PARTNER_TYPES = list(/mob/living/basic/pet/dog), - BB_BABIES_CHILD_TYPES = list(/mob/living/basic/pet/dog/corgi/puppy = 95, /mob/living/basic/pet/dog/corgi/puppy/void = 5), + BB_BABIES_CHILD_TYPES = list(/mob/living/basic/pet/dog/corgi), ) planning_subtrees = list( diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm index 4d0fb5140504..d71508251b94 100644 --- a/code/datums/ai/generic/generic_behaviors.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -49,14 +49,8 @@ batman.visible_message(span_warning("[batman] gets a slightly too tight hug from [big_guy]!"), span_userdanger("You feel your body break as [big_guy] embraces you!")) - if(iscarbon(batman)) - var/mob/living/carbon/carbon_batman = batman - for(var/obj/item/bodypart/bodypart_to_break in carbon_batman.bodyparts) - if(bodypart_to_break.body_zone == BODY_ZONE_HEAD) - continue - bodypart_to_break.receive_damage(brute = 15, wound_bonus = 35) - else - batman.adjustBruteLoss(150) + for(var/zone in GLOB.all_body_zones - BODY_ZONE_HEAD) + batman.apply_damage(15, BRUTE, zone, wound_bonus = 35) return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/monkey/monkey_behaviors.dm b/code/datums/ai/monkey/monkey_behaviors.dm index 3fb94191cc3c..48ec37058304 100644 --- a/code/datums/ai/monkey/monkey_behaviors.dm +++ b/code/datums/ai/monkey/monkey_behaviors.dm @@ -4,11 +4,18 @@ /datum/ai_behavior/monkey_equip behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH -/datum/ai_behavior/monkey_equip/finish_action(datum/ai_controller/controller, success) +/datum/ai_behavior/monkey_equip/setup(datum/ai_controller/controller, target_key) + . = ..() + var/obj/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +/datum/ai_behavior/monkey_equip/finish_action(datum/ai_controller/controller, success, target_key) . = ..() if(!success) //Don't try again on this item if we failed - controller.set_blackboard_key_assoc(BB_MONKEY_BLACKLISTITEMS, controller.blackboard[BB_MONKEY_PICKUPTARGET], TRUE) + controller.set_blackboard_key_assoc(BB_MONKEY_BLACKLISTITEMS, controller.blackboard[target_key], TRUE) controller.clear_blackboard_key(BB_MONKEY_PICKUPTARGET) @@ -50,9 +57,8 @@ return FALSE /datum/ai_behavior/monkey_equip/ground - required_distance = 0 -/datum/ai_behavior/monkey_equip/ground/perform(seconds_per_tick, datum/ai_controller/controller) +/datum/ai_behavior/monkey_equip/ground/perform(seconds_per_tick, datum/ai_controller/controller, target_key) . = ..() if(equip_item(controller)) return . | AI_BEHAVIOR_SUCCEEDED @@ -60,7 +66,7 @@ /datum/ai_behavior/monkey_equip/pickpocket -/datum/ai_behavior/monkey_equip/pickpocket/perform(seconds_per_tick, datum/ai_controller/controller) +/datum/ai_behavior/monkey_equip/pickpocket/perform(seconds_per_tick, datum/ai_controller/controller, target_key) . = ..() if(controller.blackboard[BB_MONKEY_PICKPOCKETING]) //We are pickpocketing, don't do ANYTHING!!!! return @@ -75,8 +81,6 @@ finish_action(controller, FALSE) return - - victim.visible_message(span_warning("[living_pawn] starts trying to take [target] from [victim]!"), span_danger("[living_pawn] tries to take [target]!")) controller.set_blackboard_key(BB_MONKEY_PICKPOCKETING, TRUE) @@ -196,7 +200,7 @@ if(isnull(potential_weapon)) controller.ai_interact(target = target, modifiers = disarm ? list(RIGHT_CLICK = TRUE) : null, combat_mode = TRUE) - if(!isnull(holding_weapon)) + if(disarm && !isnull(holding_weapon) && controller.blackboard[BB_MONKEY_BLACKLISTITEMS][holding_weapon]) controller.remove_thing_from_blackboard_key(BB_MONKEY_BLACKLISTITEMS, holding_weapon) //lets try to pickpocket it again! return TRUE diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index 8b753b9c1ccc..4c778f661220 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -171,11 +171,10 @@ have ways of interacting with a specific mob and control it. return FALSE set_blackboard_key(BB_MONKEY_PICKUPTARGET, weapon) - set_movement_target(type, weapon) if(pickpocket) - queue_behavior(/datum/ai_behavior/monkey_equip/pickpocket) + queue_behavior(/datum/ai_behavior/monkey_equip/pickpocket, BB_MONKEY_PICKUPTARGET) else - queue_behavior(/datum/ai_behavior/monkey_equip/ground) + queue_behavior(/datum/ai_behavior/monkey_equip/ground, BB_MONKEY_PICKUPTARGET) return TRUE ///Reactive events to being hit diff --git a/code/datums/ai_laws/ai_laws.dm b/code/datums/ai_laws/ai_laws.dm index a0d1d629fc8d..b992cb56cd2c 100644 --- a/code/datums/ai_laws/ai_laws.dm +++ b/code/datums/ai_laws/ai_laws.dm @@ -79,8 +79,15 @@ GLOBAL_VAR(round_default_lawset) /proc/pick_weighted_lawset() var/datum/ai_laws/lawtype var/list/law_weights = CONFIG_GET(keyed_list/law_weight) + var/list/specified_law_ids = CONFIG_GET(keyed_list/specified_laws) + if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI)) - law_weights -= AI_LAWS_ASIMOV + switch(CONFIG_GET(number/default_laws)) + if(CONFIG_ASIMOV) + law_weights -= AI_LAWS_ASIMOV + if(CONFIG_CUSTOM) + law_weights -= specified_law_ids + while(!lawtype && law_weights.len) var/possible_id = pick_weight(law_weights) lawtype = lawid_to_type(possible_id) @@ -442,7 +449,7 @@ GLOBAL_VAR(round_default_lawset) /datum/ai_laws/proc/show_laws(mob/to_who) var/list/printable_laws = get_law_list(include_zeroth = TRUE) - to_chat(to_who, examine_block(jointext(printable_laws, "\n"))) + to_chat(to_who, boxed_message(jointext(printable_laws, "\n"))) /datum/ai_laws/proc/associate(mob/living/silicon/M) if(owner) diff --git a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm index 623a61b8912f..6a50f431c061 100644 --- a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm @@ -26,3 +26,7 @@ /datum/bodypart_overlay/texture/carpskin texture_icon_state = "carpskin" texture_icon = 'icons/mob/human/textures.dmi' + +/datum/bodypart_overlay/texture/checkered + texture_icon_state = "checkered" + texture_icon = 'icons/mob/human/textures.dmi' diff --git a/code/datums/brain_damage/hypnosis.dm b/code/datums/brain_damage/hypnosis.dm index 5630073c9555..a9400578025b 100644 --- a/code/datums/brain_damage/hypnosis.dm +++ b/code/datums/brain_damage/hypnosis.dm @@ -55,7 +55,10 @@ to_chat(owner, span_userdanger("You suddenly snap out of your hypnosis. The phrase '[hypnotic_phrase]' no longer feels important to you.")) owner.clear_alert(ALERT_HYPNOSIS) ..() + if (!isnull(antagonist)) + antagonist.trauma = null owner.mind.remove_antag_datum(/datum/antagonist/hypnotized) + antagonist = null /datum/brain_trauma/hypnosis/on_life(seconds_per_tick, times_fired) ..() diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index cd45ae1abf46..ec537adf5c73 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -399,19 +399,23 @@ var/scratch_damage = 0.5 /datum/brain_trauma/severe/eldritch_beauty/on_life(seconds_per_tick, times_fired) - // Jumpsuits ruin the "perfection" of the body - if(!owner.get_item_by_slot(ITEM_SLOT_ICLOTHING)) + if(owner.incapacitated) return // Scratching code var/obj/item/bodypart/bodypart = owner.get_bodypart(owner.get_random_valid_zone(even_weights = TRUE)) - if(!(bodypart && IS_ORGANIC_LIMB(bodypart)) && bodypart.bodypart_flags & BODYPART_PSEUDOPART) + if(!bodypart || !IS_ORGANIC_LIMB(bodypart) || (bodypart.bodypart_flags & BODYPART_PSEUDOPART)) return - if(owner.incapacitated) + if(!ishuman(owner)) return - bodypart.receive_damage(scratch_damage) + // Jumpsuits ruin the "perfection" of the body + var/mob/living/carbon/human/scratcher = owner + if(!length(scratcher.get_clothing_on_part(bodypart))) + return + + owner.apply_damage(scratch_damage, BRUTE, bodypart) if(SPT_PROB(33, seconds_per_tick)) - to_chat(owner, span_notice("You scratch furiously at the clothed [bodypart]!")) + to_chat(owner, span_notice("You scratch furiously at your clothed [bodypart.plaintext_zone]!")) // This one is for "Climb over the rusted mountain" or /obj/structure/sign/painting/eldritch/rust /datum/brain_trauma/severe/rusting diff --git a/code/datums/browser.dm b/code/datums/browser.dm index b9d859552389..cf0df8dac501 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -138,13 +138,13 @@ var/output = {"
[Message]

- [Button1]"} + [Button1]"} if (Button2) - output += {"[Button2]"} + output += {"[Button2]"} if (Button3) - output += {"[Button3]"} + output += {"[Button3]"} output += {"
"} @@ -356,11 +356,11 @@ var/setting = settings["mainsettings"][name] if (setting["type"] == "datum") if (setting["subtypesonly"]) - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" else - dat += "[setting["desc"]]: [setting["value"]]
" + dat += "[setting["desc"]]: [setting["value"]]
" if (preview_icon) dat += "" @@ -371,7 +371,7 @@ dat += "" - dat += "
Ok " + dat += "
Ok " dat += "
" diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index b3e21e886567..7bc82fe216e1 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -230,9 +230,12 @@ var/remaining_time = time_before_fade * (CHAT_MESSAGE_EXP_DECAY ** idx++) * (CHAT_MESSAGE_HEIGHT_DECAY ** combined_height) // Ensure we don't accidentially spike alpha up or something silly like that m.message.alpha = m.get_current_alpha(time_spent) - if (remaining_time > 0) + if(remaining_time > 0) + if(time_spent < CHAT_MESSAGE_SPAWN_TIME) + // We haven't even had the time to fade in yet! + animate(m.message, alpha = 255, CHAT_MESSAGE_SPAWN_TIME - time_spent) // Stay faded in for a while, then - animate(m.message, alpha = 255, remaining_time) + animate(m.message, alpha = 255, remaining_time, flags=ANIMATION_CONTINUE) // Fade out animate(alpha = 0, time = CHAT_MESSAGE_EOL_FADE) m.animate_lifespan = remaining_time + CHAT_MESSAGE_EOL_FADE diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm index 3bb06ab639da..dea0002663d6 100644 --- a/code/datums/components/acid.dm +++ b/code/datums/components/acid.dm @@ -243,16 +243,10 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(!iscarbon(user) || user.can_touch_acid(source, acid_power, acid_volume)) return NONE - var/obj/item/bodypart/affecting = user.get_active_hand() - //Should not happen! - if(!affecting) - return NONE - - affecting.receive_damage(burn = 5) + user.apply_damage(5, BURN, user.get_active_hand()) to_chat(user, span_userdanger("The acid on \the [source] burns your hand!")) INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream") playsound(source, SFX_SEAR, 50, TRUE) - user.update_damage_overlays() return COMPONENT_CANCEL_ATTACK_CHAIN /// Handles searing the feet of whoever walks over this without protection. Only active if the parent is a turf. diff --git a/code/datums/components/alternative_sharpness.dm b/code/datums/components/alternative_sharpness.dm new file mode 100644 index 000000000000..e32c3ccf45d6 --- /dev/null +++ b/code/datums/components/alternative_sharpness.dm @@ -0,0 +1,60 @@ +/// Allows items to have different sharpness for right click attacks +/datum/component/alternative_sharpness + /// Sharpness we change the attack to + var/alt_sharpness = NONE + /// Overrides for continuous attack verbs when performing an alt attack + var/verbs_continuous = null + /// Overrides for simple attack verbs when performing an alt attack + var/verbs_simple = null + /// Value by which we offset our force during the attack + var/force_mod = 0 + /// Are we currently performing an alt attack? + var/alt_attacking = FALSE + /// Trait required for us to trigger + var/required_trait = null + // Old values before we overrode them + var/base_continuous = null + var/base_simple = null + var/base_sharpness = NONE + +/datum/component/alternative_sharpness/Initialize(alt_sharpness, verbs_continuous = null, verbs_simple = null, force_mod = 0, required_trait = null) + if (!isitem(parent)) + return COMPONENT_INCOMPATIBLE + var/obj/item/weapon = parent + src.alt_sharpness = alt_sharpness + src.verbs_continuous = verbs_continuous + src.verbs_simple = verbs_simple + src.force_mod = force_mod + src.required_trait = required_trait + base_continuous = weapon.attack_verb_continuous + base_simple = weapon.attack_verb_simple + +/datum/component/alternative_sharpness/RegisterWithParent() + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK_SECONDARY, PROC_REF(on_secondary_attack)) + +/datum/component/alternative_sharpness/proc/on_secondary_attack(obj/item/source, atom/target, mob/user, params) + SIGNAL_HANDLER + + if (alt_attacking || (required_trait && !HAS_TRAIT(source, required_trait))) + return + + alt_attacking = TRUE + source.force += force_mod + base_sharpness = source.sharpness + source.sharpness = alt_sharpness + if (!isnull(verbs_continuous)) + source.attack_verb_continuous = verbs_continuous + + if (!isnull(verbs_simple)) + source.attack_verb_simple = verbs_simple + + // I absolutely despise this but this is geniunely the best way to do this without creating and hooking up to a dozen signals and still risking failure edge cases + addtimer(CALLBACK(src, PROC_REF(disable_alt_attack)), 1) + +/datum/component/alternative_sharpness/proc/disable_alt_attack() + var/obj/item/weapon = parent + alt_attacking = FALSE + weapon.force -= force_mod + weapon.attack_verb_continuous = base_continuous + weapon.attack_verb_simple = base_simple + weapon.sharpness = base_sharpness diff --git a/code/datums/components/aquarium.dm b/code/datums/components/aquarium.dm index cf86c6b56b47..36c3c2a1f53f 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -100,11 +100,12 @@ ADD_KEEP_TOGETHER(movable, AQUARIUM_TRAIT) //render the fish on the same layer of the aquarium. if(reagents_size > 0) - RegisterSignal(movable.reagents, COMSIG_REAGENTS_NEW_REAGENT, PROC_REF(start_autofeed)) if(!movable.reagents) movable.create_reagents(reagents_size, SEALED_CONTAINER) - else if(movable.reagents.total_volume) + if(movable.reagents.total_volume) start_autofeed(movable.reagents) + else + RegisterSignal(movable.reagents, COMSIG_REAGENTS_NEW_REAGENT, PROC_REF(start_autofeed)) RegisterSignal(movable, COMSIG_PLUNGER_ACT, PROC_REF(on_plunger_act)) RegisterSignal(movable, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(on_item_interaction)) @@ -128,7 +129,7 @@ if(content.flags_1 & INITIALIZED_1) on_entered(movable, content) - ADD_TRAIT(movable, TRAIT_IS_AQUARIUM, AQUARIUM_TRAIT) + movable.add_traits(list(TRAIT_IS_AQUARIUM, TRAIT_STOP_FISH_FLOPPING), AQUARIUM_TRAIT) /datum/component/aquarium/UnregisterFromParent() var/atom/movable/movable = parent @@ -155,7 +156,7 @@ STOP_PROCESSING(SSobj, src) beauty_by_content = null tracked_fish_by_type = null - movable.remove_traits(list(TRAIT_IS_AQUARIUM, TRAIT_AQUARIUM_PANEL_OPEN, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH), AQUARIUM_TRAIT) + movable.remove_traits(list(TRAIT_IS_AQUARIUM, TRAIT_AQUARIUM_PANEL_OPEN, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, TRAIT_STOP_FISH_FLOPPING), AQUARIUM_TRAIT) qdel(movable.GetComponent(/datum/component/fishing_spot)) REMOVE_KEEP_TOGETHER(movable, AQUARIUM_TRAIT) @@ -189,6 +190,8 @@ /datum/component/aquarium/proc/on_click_alt(atom/movable/source, mob/living/user) SIGNAL_HANDLER + if(!user.can_perform_action(source)) + return var/closing = HAS_TRAIT(parent, TRAIT_AQUARIUM_PANEL_OPEN) if(closing) REMOVE_TRAIT(parent, TRAIT_AQUARIUM_PANEL_OPEN, AQUARIUM_TRAIT) @@ -238,10 +241,10 @@ return ITEM_INTERACT_SUCCESS ///Called when the feed storage is no longer empty. -/datum/component/aquarium/proc/start_autofeed(atom/movable/source, new_reagent, amount, reagtemp, data, no_react) +/datum/component/aquarium/proc/start_autofeed(datum/reagents/source, new_reagent, amount, reagtemp, data, no_react) SIGNAL_HANDLER START_PROCESSING(SSobj, src) - UnregisterSignal(source.reagents, COMSIG_REAGENTS_NEW_REAGENT) + UnregisterSignal(source, COMSIG_REAGENTS_NEW_REAGENT) ///Feed the fish at defined intervals until the feed storage is empty. /datum/component/aquarium/process(seconds_per_tick) @@ -358,7 +361,7 @@ types_to_mate_with = types_to_mate_with & types_to_check for(var/obj/item/fish/fish_type as anything in types_to_mate_with) - var/list/type_fishes = types_to_mate_with[fish_type] + var/list/type_fishes = tracked_fish_by_type[fish_type] if(length(type_fishes) >= initial(fish_type.stable_population)) continue candidates += type_fishes @@ -473,7 +476,7 @@ var/atom/movable/aquarium = parent .["fluidType"] = fluid_type .["temperature"] = fluid_temp - .["safe_mode"] = !HAS_TRAIT_FROM(aquarium, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) + .["safe_mode"] = HAS_TRAIT_FROM(aquarium, TRAIT_STOP_FISH_REPRODUCTION_AND_GROWTH, AQUARIUM_TRAIT) .["fishData"] = list() .["feedingInterval"] = feeding_interval / (1 MINUTES) .["propData"] = list() diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index 9e495ada52fa..992b7bd97385 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -35,7 +35,7 @@ src.armor_mod = armor_mod if(upgrade_prefix) src.upgrade_prefix = upgrade_prefix - var/obj/item/typecast = upgrade_item + var/obj/item/typecast = src.upgrade_item src.upgrade_name = initial(typecast.name) /datum/component/armor_plate/proc/examine(datum/source, mob/user, list/examine_list) diff --git a/code/datums/components/basic_inhands.dm b/code/datums/components/basic_inhands.dm index ac50f618861f..4d286e4eed3e 100644 --- a/code/datums/components/basic_inhands.dm +++ b/code/datums/components/basic_inhands.dm @@ -39,7 +39,7 @@ SIGNAL_HANDLER var/list/held_overlays = list() for(var/obj/item/held in holding_mob.held_items) - var/is_right = holding_mob.get_held_index_of_item(held) % 2 == 0 + var/is_right = IS_RIGHT_INDEX(holding_mob.get_held_index_of_item(held)) var/icon_file = is_right ? held.righthand_file : held.lefthand_file var/mutable_appearance/held_overlay = held.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) held_overlay.pixel_y += y_offset diff --git a/code/datums/components/bloodysoles.dm b/code/datums/components/bloodysoles.dm index 32ec8177f467..342e27c4b29a 100644 --- a/code/datums/components/bloodysoles.dm +++ b/code/datums/components/bloodysoles.dm @@ -211,7 +211,6 @@ // Create new footprints if(theoretical_new_blood >= BLOOD_FOOTPRINTS_MIN) adjust_bloody_shoes(last_blood_state, blood_lost) - update_icon() var/obj/effect/decal/cleanable/blood/footprints/FP = new(get_turf(parent_atom), footprint_sprite) if(!QDELETED(FP)) ///prints merged diff --git a/code/datums/components/breeding.dm b/code/datums/components/breeding.dm index 3c2ffb61b5a5..cb57f035c2bc 100644 --- a/code/datums/components/breeding.dm +++ b/code/datums/components/breeding.dm @@ -4,8 +4,8 @@ /datum/component/breed /// additional mobs we can breed with var/list/can_breed_with - ///path of the baby - var/baby_path + ///weighted list of the possible baby types + var/list/baby_paths ///time to wait after breeding var/breed_timer ///AI key we set when we're ready to breed @@ -15,20 +15,20 @@ ///callback after we give birth to the child var/datum/callback/post_birth -/datum/component/breed/Initialize(list/can_breed_with = list(), breed_timer = 40 SECONDS, baby_path, post_birth) +/datum/component/breed/Initialize(list/can_breed_with = list(), breed_timer = 40 SECONDS, baby_paths = list(), post_birth) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE if(ishuman(parent)) //sin detected return COMPONENT_INCOMPATIBLE - if(!ispath(baby_path)) - stack_trace("attempted to add a breeding component with invalid baby path!") + if(!length(baby_paths)) + stack_trace("attempted to add a breeding component with invalid baby paths!") return src.can_breed_with = can_breed_with src.breed_timer = breed_timer - src.baby_path = baby_path + src.baby_paths = baby_paths src.post_birth = post_birth ADD_TRAIT(parent, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, type) @@ -62,7 +62,8 @@ return COMPONENT_HOSTILE_NO_ATTACK var/turf/delivery_destination = get_turf(source) - var/atom/baby = new baby_path(delivery_destination) + var/chosen_baby_path = pick_weight(baby_paths) + var/atom/baby = new chosen_baby_path(delivery_destination) new /obj/effect/temp_visual/heart(delivery_destination) toggle_status(source) diff --git a/code/datums/components/burning.dm b/code/datums/components/burning.dm index fa60b3ecbced..7264689d13cc 100644 --- a/code/datums/components/burning.dm +++ b/code/datums/components/burning.dm @@ -91,16 +91,10 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e source.extinguish() return COMPONENT_CANCEL_ATTACK_CHAIN - var/obj/item/bodypart/affecting = user.get_active_hand() - //Should not happen! - if(!affecting) - return NONE - - affecting.receive_damage(burn = 5) + user.apply_damage(5, BURN, user.get_active_hand()) to_chat(user, span_userdanger("You burn your hand on [source]!")) INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream") playsound(source, SFX_SEAR, 50, TRUE) - user.update_damage_overlays() return COMPONENT_CANCEL_ATTACK_CHAIN /// Maintains the burning overlay on the parent atom diff --git a/code/datums/components/callouts.dm b/code/datums/components/callouts.dm index 52a3e007905c..854f769f8a10 100644 --- a/code/datums/components/callouts.dm +++ b/code/datums/components/callouts.dm @@ -111,7 +111,7 @@ for(var/datum/callout_option/callout_option as anything in callout_options) callout_items[callout_option] = image(icon = 'icons/hud/radial.dmi', icon_state = callout_option::icon_state) - var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE, user_space = TRUE) + var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, button_animation_flags = NONE, click_on_hover = TRUE, user_space = TRUE) if (!selection) return diff --git a/code/datums/components/cleaner.dm b/code/datums/components/cleaner.dm index 7072f271c7a6..035f0c054dba 100644 --- a/code/datums/components/cleaner.dm +++ b/code/datums/components/cleaner.dm @@ -96,8 +96,8 @@ ADD_TRAIT(target, TRAIT_CURRENTLY_CLEANING, REF(src)) // We need to update our planes on overlay changes RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(cleaning_target_moved)) - var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, target, GAME_PLANE) - var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, target, ABOVE_GAME_PLANE) + var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, target, GAME_PLANE) + var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, target, ABOVE_GAME_PLANE) var/list/icon_offsets = target.get_oversized_icon_offsets() low_bubble.pixel_x = icon_offsets["x"] low_bubble.pixel_y = icon_offsets["y"] @@ -140,13 +140,13 @@ if(same_z_layer) return // First, get rid of the old overlay - var/mutable_appearance/old_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, old_turf, GAME_PLANE) - var/mutable_appearance/old_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, old_turf, ABOVE_GAME_PLANE) + var/mutable_appearance/old_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, old_turf, GAME_PLANE) + var/mutable_appearance/old_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, old_turf, ABOVE_GAME_PLANE) source.cut_overlay(old_low_bubble) source.cut_overlay(old_high_bubble) // Now, add the new one - var/mutable_appearance/new_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, new_turf, GAME_PLANE) - var/mutable_appearance/new_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", GAME_CLEAN_LAYER, new_turf, ABOVE_GAME_PLANE) + var/mutable_appearance/new_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, new_turf, GAME_PLANE) + var/mutable_appearance/new_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", CLEANABLE_OBJECT_LAYER, new_turf, ABOVE_GAME_PLANE) source.add_overlay(new_low_bubble) source.add_overlay(new_high_bubble) diff --git a/code/datums/components/combustible_flooder.dm b/code/datums/components/combustible_flooder.dm index 07df03671c16..c24fae55b843 100644 --- a/code/datums/components/combustible_flooder.dm +++ b/code/datums/components/combustible_flooder.dm @@ -57,7 +57,11 @@ message_admins(admin_message) if(delete_parent && !QDELETED(parent)) - qdel(parent) // For things with the explodable component like plasma mats this isn't necessary, but there's no harm. + if(isobj(parent)) + var/obj/obj_parent = parent + obj_parent.deconstruct(disassembled = FALSE) + else + qdel(parent) // For things with the explodable component like plasma mats this isn't necessary, but there's no harm. qdel(src) /// fire_act reaction. diff --git a/code/datums/components/crafting/chemistry.dm b/code/datums/components/crafting/chemistry.dm index 70d6c76dea24..66847281ec46 100644 --- a/code/datums/components/crafting/chemistry.dm +++ b/code/datums/components/crafting/chemistry.dm @@ -150,6 +150,8 @@ category = CAT_CHEMISTRY /datum/crafting_recipe/improvised_chem_heater/on_craft_completion(mob/user, atom/result) + if(!istype(user)) + return var/obj/item/stock_parts/power_store/cell/cell = locate(/obj/item/stock_parts/power_store/cell) in range(1) if(!cell) return diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index ca8c8fdc62f3..04a53ce3a3aa 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -1,16 +1,23 @@ -/datum/component/personal_crafting/Initialize() +/datum/component/personal_crafting + /// Custom screen_loc for our element + var/screen_loc_override + +/datum/component/personal_crafting/Initialize(screen_loc_override) + src.screen_loc_override = screen_loc_override if(ismob(parent)) RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, PROC_REF(create_mob_button)) -/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL) +/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/user_client) SIGNAL_HANDLER - var/datum/hud/H = user.hud_used - var/atom/movable/screen/craft/C = new() - C.icon = H.ui_style - H.static_inventory += C - CL.screen += C - RegisterSignal(C, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) + var/datum/hud/hud = user.hud_used + var/atom/movable/screen/craft/craft_ui = new() + craft_ui.icon = hud.ui_style + if (screen_loc_override) + craft_ui.screen_loc = screen_loc_override + hud.static_inventory += craft_ui + user_client.screen += craft_ui + RegisterSignal(craft_ui, COMSIG_SCREEN_ELEMENT_CLICK, PROC_REF(component_ui_interact)) #define COOKING TRUE #define CRAFTING FALSE diff --git a/code/datums/components/crafting/robot.dm b/code/datums/components/crafting/robot.dm index d290c39aa0fb..8a6a014d5a4e 100644 --- a/code/datums/components/crafting/robot.dm +++ b/code/datums/components/crafting/robot.dm @@ -47,7 +47,7 @@ result = /mob/living/basic/bot/repairbot reqs = list( /obj/item/storage/toolbox = 1, - /obj/item/stack/tile/iron = 10, + /obj/item/stack/conveyor = 1, /obj/item/assembly/prox_sensor = 1, /obj/item/bodypart/arm/right/robot = 1, ) diff --git a/code/datums/components/electrified_buckle.dm b/code/datums/components/electrified_buckle.dm index d641cf320e19..f0a5ab857912 100644 --- a/code/datums/components/electrified_buckle.dm +++ b/code/datums/components/electrified_buckle.dm @@ -153,9 +153,10 @@ /datum/component/electrified_buckle/proc/on_update_overlays(atom/movable/source, list/overlays) SIGNAL_HANDLER var/overlay_layer = length(source.buckled_mobs) ? ABOVE_MOB_LAYER : OBJ_LAYER - for (var/image/overlay_image in requested_overlays) - overlay_image.layer = overlay_layer - overlays += overlay_image + for (var/mutable_appearance/electrified_overlay as anything in requested_overlays) + electrified_overlay.layer = overlay_layer + electrified_overlay = source.color_atom_overlay(electrified_overlay) + overlays += electrified_overlay ///where the guinea pig is actually shocked if possible /datum/component/electrified_buckle/process(seconds_per_tick) diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index 09e583a0fcf7..f6ee85c23729 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -65,8 +65,20 @@ if(damage > 0) var/armor = victim.run_armor_check(limb.body_zone, MELEE, "Your armor has protected your [limb.plaintext_zone].", "Your armor has softened a hit to your [limb.plaintext_zone].", weapon.armour_penetration, weak_against_armour = weapon.weak_against_armour) - limb.receive_damage(brute = (1 - embed_data.pain_stam_pct) * damage, blocked = armor, wound_bonus = weapon.wound_bonus, bare_wound_bonus = weapon.bare_wound_bonus, sharpness = weapon.get_sharpness()) - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage, + damagetype = BRUTE, + def_zone = limb, + blocked = armor, + wound_bonus = weapon.wound_bonus, + bare_wound_bonus = weapon.bare_wound_bonus, + sharpness = weapon.get_sharpness(), + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) /datum/component/embedded/Destroy() var/mob/living/carbon/victim = parent @@ -111,8 +123,18 @@ pain_chance_current *= 0.2 if(harmful && prob(pain_chance_current)) - limb.receive_damage(brute = (1 - embed_data.pain_stam_pct) * damage, wound_bonus = CANT_WOUND) - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage, + damagetype = BRUTE, + def_zone = limb, + wound_bonus = CANT_WOUND, + sharpness = weapon.get_sharpness(), + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) to_chat(victim, span_userdanger("[weapon] embedded in your [limb.plaintext_zone] hurts!")) var/fall_chance_current = SPT_PROB_RATE(embed_data.fall_chance / 100, seconds_per_tick) * 100 @@ -152,9 +174,20 @@ if(harmful && prob(chance)) var/damage = weapon.w_class * embed_data.jostle_pain_mult - limb.receive_damage(brute = (1 - embed_data.pain_stam_pct) * damage, wound_bonus = CANT_WOUND) - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage, + damagetype = BRUTE, + def_zone = limb, + wound_bonus = CANT_WOUND, + sharpness = weapon.get_sharpness(), + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) to_chat(victim, span_userdanger("[weapon] embedded in your [limb.plaintext_zone] jostles and stings!")) + embed_data.jostle_callback?.Invoke(victim, weapon, embed_data) /// Called when then item randomly falls out of a carbon. This handles the damage and descriptors, then calls safe_remove() @@ -164,8 +197,18 @@ if(harmful) var/damage = weapon.w_class * embed_data.remove_pain_mult - limb.receive_damage(brute= (1 - embed_data.pain_stam_pct) * damage, wound_bonus = CANT_WOUND) - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage, + damagetype = BRUTE, + def_zone = limb, + wound_bonus = CANT_WOUND, + sharpness = weapon.get_sharpness(), + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) victim.visible_message(span_danger("[weapon] falls [harmful ? "out" : "off"] of [victim.name]'s [limb.plaintext_zone]!"), span_userdanger("[weapon] falls [harmful ? "out" : "off"] of your [limb.plaintext_zone]!")) safeRemove() @@ -199,8 +242,18 @@ /datum/component/embedded/proc/damaging_removal(mob/living/carbon/victim, obj/item/removed, obj/item/bodypart/limb, ouch_multiplier = 1) var/datum/embed_data/embed_data = weapon.get_embed() var/damage = weapon.w_class * embed_data.remove_pain_mult * ouch_multiplier - limb.receive_damage(brute= (1 - embed_data.pain_stam_pct) * damage, sharpness = SHARP_EDGED) //It hurts to rip it out, get surgery you dingus. unlike the others, this CAN wound + increase slash bloodflow - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage, + damagetype = BRUTE, + def_zone = limb, + wound_bonus = max(0, weapon.wound_bonus), // It hurts to rip it out, get surgery you dingus. unlike the others, this CAN wound + increase slash bloodflow + sharpness = weapon.get_sharpness() || SHARP_EDGED, // always sharp, even if the object isn't + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) victim.emote("scream") /// This proc handles the final step and actual removal of an embedded/stuck item from a carbon, whether or not it was actually removed safely. @@ -301,10 +354,20 @@ var/datum/embed_data/embed_data = weapon.get_embed() var/damage = weapon.w_class * embed_data.remove_pain_mult - limb.receive_damage(brute = (1 - embed_data.pain_stam_pct) * damage * 1.5, sharpness = SHARP_EDGED) // Performs exit wounds and flings the user to the caster if nearby + victim.apply_damage( + damage = (1 - embed_data.pain_stam_pct) * damage * 1.5, + damagetype = BRUTE, + def_zone = limb, + wound_bonus = max(0, weapon.wound_bonus), // Performs exit wounds and flings the user to the caster if nearby + sharpness = weapon.get_sharpness() || SHARP_EDGED, + attacking_item = weapon, + ) + victim.apply_damage( + damage = embed_data.pain_stam_pct * damage, + damagetype = STAMINA, + ) victim.cause_wound_of_type_and_severity(WOUND_PIERCE, limb, WOUND_SEVERITY_MODERATE) - victim.adjustStaminaLoss(embed_data.pain_stam_pct * damage) - playsound(get_turf(victim), 'sound/effects/wounds/blood2.ogg', 50, TRUE) + playsound(victim, 'sound/effects/wounds/blood2.ogg', 50, TRUE) var/dist = get_dist(caster, victim) //Check if the caster is close enough to yank them in if(dist < 7) diff --git a/code/datums/components/explodable.dm b/code/datums/components/explodable.dm index 9dc8db3bbc4f..db77f865fd7a 100644 --- a/code/datums/components/explodable.dm +++ b/code/datums/components/explodable.dm @@ -147,18 +147,20 @@ return // If we don't do this and this doesn't delete it can lock the MC into only processing Input, Timers, and Explosions. var/atom/bomb = parent - var/log = TRUE - if(light_impact_range < 1) - log = FALSE + var/do_log = light_impact_range >= 1 exploding = TRUE - explosion(bomb, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, log, uncapped) //epic explosion time + explosion(bomb, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, do_log, uncapped) //epic explosion time switch(delete_after) if(EXPLODABLE_DELETE_SELF) qdel(src) if(EXPLODABLE_DELETE_PARENT) - qdel(bomb) + if(isobj(bomb)) + var/obj/obj_bomb = bomb + obj_bomb.deconstruct(disassembled = FALSE) + else + qdel(bomb) else addtimer(CALLBACK(src, PROC_REF(reset_exploding)), 0.1 SECONDS) diff --git a/code/datums/components/food_storage.dm b/code/datums/components/food_storage.dm index 843f611e5ff3..32fb27c7b729 100644 --- a/code/datums/components/food_storage.dm +++ b/code/datums/components/food_storage.dm @@ -4,7 +4,7 @@ /datum/component/food_storage /// Reference to what we have in our food. - var/obj/item/stored_item + VAR_FINAL/obj/item/stored_item /// The amount of volume the food has on creation - Used for probabilities var/initial_volume = 10 /// Minimum size items that can be inserted @@ -13,16 +13,14 @@ var/bad_chance_of_discovery = 0 /// What are the odds we see the stored item before we bite it? var/good_chance_of_discovery = 100 - /// The stored item was found out somehow. - var/discovered = FALSE /datum/component/food_storage/Initialize(_minimum_weight_class = WEIGHT_CLASS_SMALL, _bad_chance = 0, _good_chance = 100) RegisterSignal(parent, COMSIG_ATOM_ITEM_INTERACTION_SECONDARY, PROC_REF(try_inserting_item)) + RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) RegisterSignal(parent, COMSIG_CLICK_CTRL, PROC_REF(try_removing_item)) RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(consume_food_storage)) - RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) - + RegisterSignals(parent, list(COMSIG_FOOD_CONSUMED, COMSIG_OBJ_DECONSTRUCT), PROC_REF(storage_consumed)) var/atom/food = parent initial_volume = food.reagents.total_volume @@ -33,12 +31,19 @@ food.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1 -/datum/component/food_storage/Destroy(force) - if(stored_item) - stored_item.forceMove(stored_item.drop_location()) - stored_item.dropped() - stored_item = null - . = ..() +/datum/component/food_storage/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_ITEM_INTERACTION_SECONDARY, + COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, + COMSIG_CLICK_CTRL, + COMSIG_FOOD_CONSUMED, + COMSIG_FOOD_EATEN, + COMSIG_OBJ_DECONSTRUCT, + )) + if(QDELING(parent) || QDELETED(stored_item)) + return + stored_item.forceMove(stored_item.drop_location()) + stored_item = null /** Begins the process of inserted an item. * @@ -60,19 +65,17 @@ return NONE if(inserted_item.w_class > minimum_weight_class) - to_chat(user, span_warning("\The [inserted_item.name] won't fit in \the [parent].")) + to_chat(user, span_warning("[inserted_item] won't fit in [parent].")) return ITEM_INTERACT_BLOCKING if(!QDELETED(stored_item)) - to_chat(user, span_warning("There's something in \the [parent].")) - return ITEM_INTERACT_BLOCKING - - if(HAS_TRAIT(inserted_item, TRAIT_NODROP)) - to_chat(user, span_warning("\the [inserted_item] is stuck to your hand, you can't put into \the [parent]!")) + to_chat(user, span_warning("There's something in [parent].")) return ITEM_INTERACT_BLOCKING - user.visible_message(span_notice("[user.name] begins inserting [inserted_item.name] into \the [parent]."), \ - span_notice("You start to insert the [inserted_item.name] into \the [parent].")) + user.visible_message( + span_notice("[user] begins inserting [inserted_item] into [parent]."), + span_notice("You start to insert the [inserted_item] into [parent]."), + ) INVOKE_ASYNC(src, PROC_REF(insert_item), inserted_item, user) return ITEM_INTERACT_SUCCESS @@ -89,14 +92,11 @@ var/atom/food = parent - if(QDELETED(stored_item)) - return CLICK_ACTION_BLOCKING - if(!food.can_interact(user)) return CLICK_ACTION_BLOCKING - user.visible_message(span_notice("[user.name] begins tearing at \the [parent]."), \ - span_notice("You start to rip into \the [parent].")) + user.visible_message(span_notice("[user] begins tearing at [parent]."), \ + span_notice("You start to rip into [parent].")) INVOKE_ASYNC(src, PROC_REF(begin_remove_item), user) return CLICK_ACTION_SUCCESS @@ -110,9 +110,12 @@ /datum/component/food_storage/proc/insert_item(obj/item/inserted_item, mob/user) if(!do_after(user, 1.5 SECONDS, target = parent)) return + if(!user.temporarilyRemoveItemFromInventory(inserted_item)) + to_chat(user, span_warning("You can't seem to insert [inserted_item] into [parent].")) + return var/atom/food = parent - to_chat(user, span_notice("You slip [inserted_item.name] inside \the [parent].")) + to_chat(user, span_notice("You slip [inserted_item] inside [parent].")) inserted_item.forceMove(food) user.log_message("inserted [inserted_item] into [parent].", LOG_ATTACK) food.add_fingerprint(user) @@ -126,19 +129,22 @@ * user - person removing the item. */ /datum/component/food_storage/proc/begin_remove_item(mob/user) - if(do_after(user, 10 SECONDS, target = parent)) - remove_item(user) + if(!do_after(user, 10 SECONDS, target = parent)) + return + if(QDELETED(stored_item)) + to_chat(user, span_warning("There's nothing in [parent].")) + return + remove_item(user) /** * Removes the stored item, putting it in user's hands or on the ground, then updates the reference. */ /datum/component/food_storage/proc/remove_item(mob/user) if(user.put_in_hands(stored_item)) - user.visible_message(span_warning("[user.name] slowly pulls [stored_item.name] out of \the [parent]."), \ - span_warning("You slowly pull [stored_item.name] out of \the [parent].")) + user.visible_message(span_warning("[user] slowly pulls [stored_item] out of [parent]."), \ + span_warning("You slowly pull [stored_item] out of [parent].")) else - stored_item.dropped() - stored_item.visible_message(span_warning("[stored_item.name] falls out of \the [parent].")) + stored_item.visible_message(span_warning("[stored_item] falls out of [parent].")) update_stored_item() @@ -167,9 +173,10 @@ /// Chance of finding the held item = bad chance - 50 good_chance_of_discovery = bad_chance_of_discovery - 50 + var/discovered = FALSE if(prob(good_chance_of_discovery)) //finding the item, without biting it discovered = TRUE - to_chat(target, span_warning("It feels like there's something in \the [parent]...!")) + to_chat(target, span_warning("It feels like there's something in [parent]...!")) else if(prob(bad_chance_of_discovery)) //finding the item, BY biting it user.log_message("just fed [key_name(target)] \a [stored_item] which was hidden in [parent].", LOG_ATTACK) @@ -179,6 +186,14 @@ if(!QDELETED(stored_item) && discovered) INVOKE_ASYNC(src, PROC_REF(remove_item), user) +/// When fully consumed, just drop the item out on the ground. +/datum/component/food_storage/proc/storage_consumed(datum/source, mob/living/target, mob/living/user) + SIGNAL_HANDLER + if(QDELETED(stored_item)) + return + stored_item.forceMove(stored_item.drop_location()) + stored_item = null + /** Updates the reference of the stored item. * * Checks the food's contents for if an alternate item was placed into the food. diff --git a/code/datums/components/ground_sinking.dm b/code/datums/components/ground_sinking.dm index d29e84908a43..4e846b4cf704 100644 --- a/code/datums/components/ground_sinking.dm +++ b/code/datums/components/ground_sinking.dm @@ -99,7 +99,7 @@ /datum/component/ground_sinking/proc/finish_sinking(mob/living/basic/living_target) sinked = TRUE is_sinking = FALSE - living_target.density = FALSE + living_target.set_density(FALSE) living_target.damage_coeff = damage_res_sinked if(heal_when_sinked) start_regenerating() @@ -113,7 +113,7 @@ stop_regenerating() living_target.icon_state = target_icon_state living_target.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) - living_target.density = TRUE + living_target.set_density(TRUE) sinked = FALSE /// The mop starts regaining health diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm index edde591c0c38..3699ee75b8c3 100644 --- a/code/datums/components/gunpoint.dm +++ b/code/datums/components/gunpoint.dm @@ -194,7 +194,7 @@ return var/flinch_chance = 50 - var/gun_hand = (source.get_held_index_of_item(weapon) % 2) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM + var/gun_hand = IS_LEFT_INDEX(source.get_held_index_of_item(weapon)) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM if(isbodypart(def_zone)) var/obj/item/bodypart/hitting = def_zone diff --git a/code/datums/components/happiness.dm b/code/datums/components/happiness.dm index a131e86960eb..beaad4b7ca93 100644 --- a/code/datums/components/happiness.dm +++ b/code/datums/components/happiness.dm @@ -105,8 +105,7 @@ /datum/component/happiness/proc/view_happiness(mob/living/source, mob/living/clicker) if(HAS_TRAIT(source, TRAIT_MOB_HIDE_HAPPINESS) || !istype(clicker) || !COOLDOWN_FINISHED(src, happiness_inspect) || !clicker.CanReach(source)) return - var/list/offset_to_add = get_icon_dimensions(source.icon) - var/y_position = offset_to_add["height"] + 1 + var/y_position = source.get_cached_height() + 1 var/obj/effect/overlay/happiness_overlay/hearts = new hearts.pixel_y = y_position hearts.set_hearts(happiness_level/maximum_happiness) diff --git a/code/datums/components/heart_eater.dm b/code/datums/components/heart_eater.dm index 122716b3be5b..3e6e07280311 100644 --- a/code/datums/components/heart_eater.dm +++ b/code/datums/components/heart_eater.dm @@ -50,7 +50,7 @@ eater_tongue.disliked_foodtypes &= ~GORE eater_tongue.liked_foodtypes |= GORE -/datum/component/heart_eater/proc/on_species_change(mob/living/carbon/human/eater, datum/species/new_species, datum/species/old_species) +/datum/component/heart_eater/proc/on_species_change(mob/living/carbon/human/eater, datum/species/new_species, datum/species/old_species, pref_load, regenerate_icons) SIGNAL_HANDLER eater.dna?.species?.damage_modifier += remember_modifier diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm index 7da90a2db083..f168a3eba35d 100644 --- a/code/datums/components/infective.dm +++ b/code/datums/components/infective.dm @@ -115,8 +115,8 @@ return if(!is_weak) - var/appendage_zone = feeder.held_items.Find(source) - appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : (appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM) + var/appendage_zone = feeder.get_held_index_of_item(source) + appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : (IS_RIGHT_INDEX(appendage_zone) ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM) try_infect(feeder, appendage_zone) for(var/datum/disease/disease as anything in diseases) diff --git a/code/datums/components/jetpack.dm b/code/datums/components/jetpack.dm index 0a52d2250be9..5498a8a81ef8 100644 --- a/code/datums/components/jetpack.dm +++ b/code/datums/components/jetpack.dm @@ -3,8 +3,10 @@ // So propulsion through space on move, that sort of thing /datum/component/jetpack dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - /// Checks to ensure if we can move & if we can activate + /// Checks to ensure if we can move var/datum/callback/check_on_move + /// Checks to ensure we can activate + var/datum/callback/check_on_activation /// If we should stabilize ourselves when not drifting var/stabilize = FALSE /// The signal we listen for as an activation @@ -23,6 +25,10 @@ var/stabilization_force /// Our current user var/mob/user + /// Last tick on which we triggered, to prevent double-dipping + var/last_force_tick + /// Last tick on which we stabilized + var/last_stabilization_tick /** * Arguments: @@ -35,7 +41,7 @@ * * check_on_move - Callback we call each time we attempt a move, we expect it to retun true if the move is ok, false otherwise. It expects an arg, TRUE if fuel should be consumed, FALSE othewise * * effect_type - Type of trail_follow to spawn */ -/datum/component/jetpack/Initialize(stabilize, drift_force = 1 NEWTONS, stabilization_force = 1 NEWTONS, activation_signal, deactivation_signal, return_flag, datum/callback/check_on_move, datum/effect_system/trail_follow/effect_type) +/datum/component/jetpack/Initialize(stabilize, drift_force = 1 NEWTONS, stabilization_force = 1 NEWTONS, activation_signal, deactivation_signal, return_flag, datum/callback/check_on_move, datum/callback/check_on_activation, datum/effect_system/trail_follow/effect_type) . = ..() if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -48,6 +54,7 @@ src.stabilize = stabilize src.check_on_move = check_on_move + src.check_on_activation = check_on_activation src.activation_signal = activation_signal src.deactivation_signal = deactivation_signal src.return_flag = return_flag @@ -55,7 +62,7 @@ src.drift_force = drift_force src.stabilization_force = stabilization_force -/datum/component/jetpack/InheritComponent(datum/component/component, original, stabilize, drift_force = 1 NEWTONS, stabilization_force = 1 NEWTONS, activation_signal, deactivation_signal, return_flag, datum/callback/check_on_move, datum/effect_system/trail_follow/effect_type) +/datum/component/jetpack/InheritComponent(datum/component/component, original, stabilize, drift_force = 1 NEWTONS, stabilization_force = 1 NEWTONS, activation_signal, deactivation_signal, return_flag, datum/callback/check_on_move, datum/callback/check_on_activation, datum/effect_system/trail_follow/effect_type) UnregisterSignal(parent, src.activation_signal) if(src.deactivation_signal) UnregisterSignal(parent, src.deactivation_signal) @@ -65,6 +72,7 @@ src.stabilize = stabilize src.check_on_move = check_on_move + src.check_on_activation = check_on_activation src.activation_signal = activation_signal src.deactivation_signal = deactivation_signal src.return_flag = return_flag @@ -80,6 +88,7 @@ QDEL_NULL(trail) user = null check_on_move = null + check_on_activation = null return ..() /datum/component/jetpack/proc/setup_trail(mob/user) @@ -93,7 +102,7 @@ /datum/component/jetpack/proc/activate(datum/source, mob/new_user) SIGNAL_HANDLER - if(!check_on_move.Invoke(TRUE)) + if(!isnull(check_on_activation) && !check_on_activation.Invoke()) return return_flag user = new_user @@ -101,13 +110,16 @@ RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_move_react)) RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE_NOGRAV, PROC_REF(on_client_move)) RegisterSignal(user, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(on_pushoff)) + RegisterSignal(user, COMSIG_MOVABLE_DRIFT_BLOCK_INPUT, PROC_REF(on_input_block)) + last_stabilization_tick = world.time START_PROCESSING(SSnewtonian_movement, src) - setup_trail(user) + if (effect_type) + setup_trail(user) /datum/component/jetpack/proc/deactivate(datum/source, mob/old_user) SIGNAL_HANDLER - UnregisterSignal(old_user, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE)) + UnregisterSignal(old_user, list(COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE_NOGRAV, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, COMSIG_MOVABLE_DRIFT_BLOCK_INPUT)) STOP_PROCESSING(SSnewtonian_movement, src) user = null @@ -119,7 +131,7 @@ if (!should_trigger(source)) return - if(source.client.intended_direction && check_on_move.Invoke(FALSE))//You use jet when press keys. yes. + if(source.client.intended_direction && check_on_move.Invoke(FALSE) && trail) //You use jet when press keys. yes. trail.generate_effect() /datum/component/jetpack/proc/should_trigger(mob/source) @@ -142,24 +154,62 @@ trail.oldposition = get_turf(source) /datum/component/jetpack/process(seconds_per_tick) - if (!should_trigger(user) || !stabilize || isnull(user.drift_handler)) + if (last_stabilization_tick == world.time) return - var/max_drift_force = (DEFAULT_INERTIA_SPEED / user.cached_multiplicative_slowdown - 1) / INERTIA_SPEED_COEF + 1 + last_stabilization_tick = world.time + + if (!should_trigger(user) || !stabilize || !check_on_move.Invoke(FALSE) || isnull(user.drift_handler)) + return + + var/max_drift_force = MOVE_DELAY_TO_DRIFT(user.cached_multiplicative_slowdown) user.drift_handler.stabilize_drift(user.client.intended_direction ? dir2angle(user.client.intended_direction) : null, user.client.intended_direction ? max_drift_force : 0, stabilization_force * (seconds_per_tick * 1 SECONDS)) +/datum/component/jetpack/proc/on_input_block(mob/source) + SIGNAL_HANDLER + + if (!should_trigger(source)) + return + + if (!check_on_move.Invoke(TRUE)) + return + + return DRIFT_ALLOW_INPUT + /datum/component/jetpack/proc/on_client_move(mob/source, list/move_args) SIGNAL_HANDLER if (!should_trigger(source)) return + if (last_force_tick == world.time) + return + if (!check_on_move.Invoke(TRUE)) return - var/max_drift_force = (DEFAULT_INERTIA_SPEED / source.cached_multiplicative_slowdown - 1) / INERTIA_SPEED_COEF + 1 - source.newtonian_move(dir2angle(source.client.intended_direction), instant = TRUE, drift_force = drift_force, controlled_cap = max_drift_force) - source.setDir(source.client.intended_direction) + var/max_drift_force = MOVE_DELAY_TO_DRIFT(source.cached_multiplicative_slowdown) + var/applied_force = drift_force + var/move_dir = source.client.intended_direction + // Try to see if we can simulate pushing off a wall + var/atom/movable/backup = source.get_spacemove_backup(move_dir, FALSE, include_floors = TRUE) + if (backup && !(backup.dir & move_dir)) + applied_force = max_drift_force + + // We don't want to force the loop to fire before stabilizing if we're going to, otherwise its effects will be delayed until the next tick which is jank + var/force_stabilize = FALSE + if (last_stabilization_tick < world.time) + force_stabilize = TRUE + + source.newtonian_move(dir2angle(move_dir), instant = TRUE, drift_force = applied_force, controlled_cap = max_drift_force, force_loop = !force_stabilize) + source.setDir(move_dir) + last_force_tick = world.time + + if (force_stabilize) + // Newphys is an SS_TICKER subsystem and under ideal circumstances should be firing every tick, thus a period of world.tick_lag + // However, since our servers are jank, even SSinput can end up overtiming - which is also an SS_TICKER subsystem that just so + // happens to be what is calling this proc - so we can be assured that this is not above world.tick_lag, or at least should not be + process(world.tick_lag) /datum/component/jetpack/proc/on_pushoff(mob/source, movement_dir, continuous_move, atom/backup) SIGNAL_HANDLER @@ -167,7 +217,10 @@ if (get_dir(source, backup) == movement_dir || source.loc == backup.loc) return - if (!source.client?.intended_direction || (source.client.intended_direction & get_dir(source, backup))) + if (!source.client?.intended_direction || source.client.intended_direction == get_dir(source, backup)) + return + + if (isnull(source.drift_handler)) return if (!should_trigger(source) || !check_on_move.Invoke(FALSE)) diff --git a/code/datums/components/leanable.dm b/code/datums/components/leanable.dm index b95fd734ad04..bc0994dcdcd9 100644 --- a/code/datums/components/leanable.dm +++ b/code/datums/components/leanable.dm @@ -2,45 +2,55 @@ /datum/component/leanable /// How much will mobs that lean onto this object be offset var/leaning_offset = 11 - /// List of click modifiers that are required to be present for leaning to trigger - var/list/click_mods = null - /// Callback called for additional checks if a lean is valid - var/datum/callback/lean_check = null - /// Whenever this object can be leaned on from the same turf as its' own. Do not use without a custom lean_check! - var/same_turf = FALSE /// List of mobs currently leaning on our parent var/list/leaning_mobs = list() + /// Is this object currently leanable? + var/is_currently_leanable = TRUE -/datum/component/leanable/Initialize(leaning_offset = 11, list/click_mods = null, datum/callback/lean_check = null, same_turf = FALSE) +/datum/component/leanable/Initialize(mob/living/leaner, leaning_offset = 11) . = ..() src.leaning_offset = leaning_offset - src.click_mods = click_mods - src.lean_check = lean_check - src.same_turf = same_turf + mousedrop_receive(parent, leaner, leaner) /datum/component/leanable/RegisterWithParent() RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + RegisterSignal(parent, COMSIG_ATOM_DENSITY_CHANGED, PROC_REF(on_density_change)) + var/atom/leanable_atom = parent + is_currently_leanable = leanable_atom.density + +/datum/component/leanable/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list( + COMSIG_MOVABLE_MOVED, + COMSIG_MOUSEDROPPED_ONTO, + COMSIG_ATOM_DENSITY_CHANGED, + )) + +/datum/component/leanable/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_MOUSEDROPPED_ONTO, COMSIG_MOVABLE_MOVED)) /datum/component/leanable/Destroy(force) + stop_leaning_leaners() + return ..() + +/datum/component/leanable/proc/stop_leaning_leaners(fall) for (var/mob/living/leaner as anything in leaning_mobs) leaner.stop_leaning() + if(fall) + to_chat(leaner, span_danger("You lose balance!")) + leaner.Paralyze(0.5 SECONDS) leaning_mobs = null - return ..() /datum/component/leanable/proc/on_moved(datum/source) SIGNAL_HANDLER + for (var/mob/living/leaner as anything in leaning_mobs) leaner.stop_leaning() /datum/component/leanable/proc/mousedrop_receive(atom/source, atom/movable/dropped, mob/user, params) if (dropped != user) return - if (islist(click_mods)) - var/list/modifiers = params2list(params) - for (var/modifier in click_mods) - if (!LAZYACCESS(modifiers, modifier)) - return if (!iscarbon(dropped) && !iscyborg(dropped)) return var/mob/living/leaner = dropped @@ -49,10 +59,10 @@ if (HAS_TRAIT_FROM(leaner, TRAIT_UNDENSE, LEANING_TRAIT)) return var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir)) - if (checked_turf != get_turf(source) && (!same_turf || get_turf(source) != get_turf(leaner))) - return - if (!isnull(lean_check) && !lean_check.Invoke(dropped, params)) + if (checked_turf != get_turf(source)) return + if(!is_currently_leanable) + return COMPONENT_CANCEL_MOUSEDROPPED_ONTO leaner.start_leaning(source, leaning_offset) leaning_mobs += leaner RegisterSignals(leaner, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING), PROC_REF(stopped_leaning)) @@ -63,6 +73,13 @@ leaning_mobs -= source UnregisterSignal(source, list(COMSIG_LIVING_STOPPED_LEANING, COMSIG_QDELETING)) +/** + * Makes the mob lean on an atom + * Arguments + * + * * atom/lean_target - the target the mob is trying to lean on + * * leaning_offset - pixel offset to apply on the mob when leaning + */ /mob/living/proc/start_leaning(atom/lean_target, leaning_offset) var/new_x = lean_target.pixel_x + base_pixel_x + body_position_pixel_x_offset var/new_y = lean_target.pixel_y + base_pixel_y + body_position_pixel_y_offset @@ -95,6 +112,7 @@ /// You fall on your face if you get teleported while leaning /mob/living/proc/teleport_away_while_leaning() SIGNAL_HANDLER + // Make sure we unregister signal handlers and reset animation stop_leaning() // -1000 aura @@ -103,6 +121,7 @@ /mob/living/proc/stop_leaning() SIGNAL_HANDLER + UnregisterSignal(src, list( COMSIG_MOB_CLIENT_PRE_MOVE, COMSIG_LIVING_DISARM_HIT, @@ -117,5 +136,14 @@ /mob/living/proc/lean_dir_changed(atom/source, old_dir, new_dir) SIGNAL_HANDLER + if (old_dir != new_dir) INVOKE_ASYNC(src, PROC_REF(stop_leaning)) + +/datum/component/leanable/proc/on_density_change() + SIGNAL_HANDLER + is_currently_leanable = !is_currently_leanable + if(!is_currently_leanable) + stop_leaning_leaners(fall = TRUE) + return + stop_leaning_leaners() diff --git a/code/datums/components/life_link.dm b/code/datums/components/life_link.dm index 314a3d7931bd..98858f61c3cb 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -123,24 +123,14 @@ /// Update our health on the medical hud /datum/component/life_link/proc/update_med_hud_health(mob/living/mob_parent) - var/image/holder = mob_parent.hud_list?[HEALTH_HUD] - if(isnull(holder)) - return - holder.icon_state = "hud[RoundHealth(host)]" - var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - ICON_SIZE_Y + mob_parent.set_hud_image_state(HEALTH_HUD, "hud[RoundHealth(host)]") /// Update our vital status on the medical hud /datum/component/life_link/proc/update_med_hud_status(mob/living/mob_parent) - var/image/holder = mob_parent.hud_list?[STATUS_HUD] - if(isnull(holder)) - return - var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - ICON_SIZE_Y if(host.stat == DEAD || HAS_TRAIT(host, TRAIT_FAKEDEATH)) - holder.icon_state = "huddead" + mob_parent.set_hud_image_state(STATUS_HUD, "huddead") else - holder.icon_state = "hudhealthy" + mob_parent.set_hud_image_state(STATUS_HUD, "hudhealthy") /// When our status tab updates, draw how much HP our host has in there /datum/component/life_link/proc/on_status_tab_updated(mob/living/source, list/items) diff --git a/code/datums/components/mutant_hands.dm b/code/datums/components/mutant_hands.dm index f7e19e59fb5a..b3478d41f311 100644 --- a/code/datums/components/mutant_hands.dm +++ b/code/datums/components/mutant_hands.dm @@ -147,6 +147,7 @@ icon = 'icons/effects/blood.dmi' icon_state = "bloodhand_left" base_icon_state = "bloodhand" + icon_angle = 90 item_flags = ABSTRACT | DROPDEL | HAND_ITEM resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF @@ -160,11 +161,9 @@ if(!base_icon_state) return - // Even hand indexes are right hands, - // Odd hand indexes are left hand - // ...But also, we swap it intentionally here, + // We swap it intentionally here, // so right icon is shown on the left (Because hands) - if(user.get_held_index_of_item(src) % 2 == 1) + if(IS_LEFT_INDEX(user.get_held_index_of_item(src))) icon_state = "[base_icon_state]_right" else icon_state = "[base_icon_state]_left" diff --git a/code/datums/components/omen.dm b/code/datums/components/omen.dm index 080ee58a0f81..e250bb7124f3 100644 --- a/code/datums/components/omen.dm +++ b/code/datums/components/omen.dm @@ -208,14 +208,11 @@ INVOKE_ASYNC(our_guy, TYPE_PROC_REF(/mob, emote), "scream") to_chat(our_guy, span_warning("What a horrible night... To have a curse!")) - if(prob(30 * luck_mod)) /// Bonk! - var/obj/item/bodypart/the_head = our_guy.get_bodypart(BODY_ZONE_HEAD) - if(!the_head) - return - playsound(get_turf(our_guy), 'sound/effects/tableheadsmash.ogg', 90, TRUE) + if(prob(30 * luck_mod) && our_guy.get_bodypart(BODY_ZONE_HEAD)) /// Bonk! + playsound(our_guy, 'sound/effects/tableheadsmash.ogg', 90, TRUE) our_guy.visible_message(span_danger("[our_guy] hits [our_guy.p_their()] head really badly falling down!"), span_userdanger("You hit your head really badly falling down!")) - the_head.receive_damage(75 * damage_mod, damage_source = "slipping") - our_guy.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100 * damage_mod) + our_guy.apply_damage(75 * damage_mod, BRUTE, BODY_ZONE_HEAD, attacking_item = "slipping") + our_guy.apply_damage(100 * damage_mod, BRAIN) consume_omen() return diff --git a/code/datums/components/parry.dm b/code/datums/components/parry.dm index a478fcbd2780..4b49096a6e26 100644 --- a/code/datums/components/parry.dm +++ b/code/datums/components/parry.dm @@ -104,10 +104,10 @@ parried = TRUE if (source.firer != user) - if (abs(source.angle - dir2angle(user)) < 15) + if (abs(source.angle - dir2angle(user.dir)) < 15) source.set_angle((source.angle + 180) % 360 + rand(-3, 3)) else - source.set_angle(dir2angle(user) + rand(-3, 3)) + source.set_angle(dir2angle(user.dir) + rand(-3, 3)) user.visible_message(span_warning("[user] expertly parries [source] with [user.p_their()] bare hand!"), span_warning("You parry [source] with your hand!")) else user.visible_message(span_warning("[user] boosts [source] with [user.p_their()] bare hand!"), span_warning("You boost [source] with your hand!")) diff --git a/code/datums/components/pet_commands/fetch.dm b/code/datums/components/pet_commands/fetch.dm index 9a42c485d5c0..143ac9ca1014 100644 --- a/code/datums/components/pet_commands/fetch.dm +++ b/code/datums/components/pet_commands/fetch.dm @@ -3,11 +3,11 @@ * Watch for someone throwing or pointing at something and then go get it and bring it back. * If it's food we might eat it instead. */ -/datum/pet_command/point_targeting/fetch +/datum/pet_command/fetch command_name = "Fetch" command_desc = "Command your pet to retrieve something you throw or point at." - radial_icon = 'icons/mob/actions/actions_spells.dmi' - radial_icon_state = "summons" + radial_icon_state = "fetch" + requires_pointing = TRUE speech_commands = list("fetch") command_feedback = "bounces" pointed_reaction = "with great interest" @@ -16,22 +16,25 @@ /// If true, this is a poorly trained pet who will eat food you throw instead of bringing it back var/will_eat_targets = TRUE -/datum/pet_command/point_targeting/fetch/New(mob/living/parent) +/datum/pet_command/fetch/New(mob/living/parent) . = ..() if(isnull(parent)) return parent.AddElement(/datum/element/ai_held_item) // We don't remove this on destroy because they might still be holding something -/datum/pet_command/point_targeting/fetch/add_new_friend(mob/living/tamer) +/datum/pet_command/fetch/add_new_friend(mob/living/tamer) . = ..() RegisterSignal(tamer, COMSIG_MOB_THROW, PROC_REF(listened_throw)) -/datum/pet_command/point_targeting/fetch/remove_friend(mob/living/unfriended) +/datum/pet_command/fetch/remove_friend(mob/living/unfriended) . = ..() UnregisterSignal(unfriended, COMSIG_MOB_THROW) +/datum/pet_command/fetch/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to fetch [target]!" + /// A friend has thrown something, if we're listening or at least not busy then go get it -/datum/pet_command/point_targeting/fetch/proc/listened_throw(mob/living/carbon/thrower) +/datum/pet_command/fetch/proc/listened_throw(mob/living/carbon/thrower) SIGNAL_HANDLER var/mob/living/parent = weak_parent.resolve() @@ -57,7 +60,7 @@ RegisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED, PROC_REF(listen_throw_land)) /// A throw we were listening to has finished, see if it's in range for us to try grabbing it -/datum/pet_command/point_targeting/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwingdatum) +/datum/pet_command/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwingdatum) SIGNAL_HANDLER UnregisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED) @@ -76,7 +79,7 @@ parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, thrower) // Don't try and fetch turfs or anchored objects if someone points at them -/datum/pet_command/point_targeting/fetch/look_for_target(mob/living/pointing_friend, obj/item/pointed_atom) +/datum/pet_command/fetch/look_for_target(mob/living/pointing_friend, obj/item/pointed_atom) if (!istype(pointed_atom)) return FALSE if (pointed_atom.anchored) @@ -89,7 +92,7 @@ parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, pointing_friend) // Finally, plan our actions -/datum/pet_command/point_targeting/fetch/execute_action(datum/ai_controller/controller) +/datum/pet_command/fetch/execute_action(datum/ai_controller/controller) controller.queue_behavior(/datum/ai_behavior/forget_failed_fetches) var/atom/target = controller.blackboard[BB_CURRENT_PET_TARGET] diff --git a/code/datums/components/pet_commands/obeys_commands.dm b/code/datums/components/pet_commands/obeys_commands.dm index 8aaa7e717929..4a68574d6e08 100644 --- a/code/datums/components/pet_commands/obeys_commands.dm +++ b/code/datums/components/pet_commands/obeys_commands.dm @@ -3,12 +3,23 @@ * Manages a list of pet command datums, allowing you to boss it around * Creates a radial menu of pet commands when this creature is alt-clicked, if it has any */ +#define DEFAULT_RADIAL_VIEWING_DISTANCE 9 /datum/component/obeys_commands /// List of commands you can give to the owner of this component var/list/available_commands = list() + ///Users currently viewing our radial options + var/list/radial_viewers = list() + ///radius of our radial menu + var/radial_menu_radius = 48 + ///after how long we shutdown radial menus + var/radial_menu_lifetime = 7 SECONDS + ///offset to display the radial menu + var/list/radial_menu_offset + ///should the commands move with the pet owner's screen? + var/radial_relative_to_user /// The available_commands parameter should be passed as a list of typepaths -/datum/component/obeys_commands/Initialize(list/command_typepaths = list()) +/datum/component/obeys_commands/Initialize(list/command_typepaths = list(), list/radial_menu_offset = list(0, 0), radial_relative_to_user = FALSE) . = ..() if (!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -17,7 +28,8 @@ return COMPONENT_INCOMPATIBLE if (!length(command_typepaths)) CRASH("Initialised obedience component with no commands.") - + src.radial_menu_offset = radial_menu_offset + src.radial_relative_to_user = radial_relative_to_user for (var/command_path in command_typepaths) var/datum/pet_command/new_command = new command_path(parent) available_commands[new_command.command_name] = new_command @@ -30,7 +42,6 @@ RegisterSignal(parent, COMSIG_LIVING_BEFRIENDED, PROC_REF(add_friend)) RegisterSignal(parent, COMSIG_LIVING_UNFRIENDED, PROC_REF(remove_friend)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(display_menu)) /datum/component/obeys_commands/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_LIVING_BEFRIENDED, COMSIG_LIVING_UNFRIENDED, COMSIG_ATOM_EXAMINE, COMSIG_CLICK_ALT)) @@ -38,15 +49,26 @@ /// Add someone to our friends list /datum/component/obeys_commands/proc/add_friend(datum/source, mob/living/new_friend) SIGNAL_HANDLER - + RegisterSignal(new_friend, COMSIG_KB_LIVING_VIEW_PET_COMMANDS, PROC_REF(on_key_pressed)) + RegisterSignal(new_friend, DEACTIVATE_KEYBIND(COMSIG_KB_LIVING_VIEW_PET_COMMANDS), PROC_REF(on_key_unpressed)) for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] INVOKE_ASYNC(command, TYPE_PROC_REF(/datum/pet_command, add_new_friend), new_friend) +/datum/component/obeys_commands/proc/on_key_unpressed(mob/living/source) + SIGNAL_HANDLER + UnregisterSignal(source, COMSIG_ATOM_MOUSE_ENTERED) + +/datum/component/obeys_commands/proc/remove_from_viewers(mob/living/source) + radial_viewers -= REF(source) + /// Remove someone from our friends list /datum/component/obeys_commands/proc/remove_friend(datum/source, mob/living/old_friend) SIGNAL_HANDLER - + UnregisterSignal(old_friend, list( + COMSIG_KB_LIVING_VIEW_PET_COMMANDS, + DEACTIVATE_KEYBIND(COMSIG_KB_LIVING_VIEW_PET_COMMANDS), + )) for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] INVOKE_ASYNC(command, TYPE_PROC_REF(/datum/pet_command, remove_friend), old_friend) @@ -61,21 +83,34 @@ return examine_list += span_notice("[source.p_They()] seem[source.p_s()] happy to see you!") -/// Displays a radial menu of commands -/datum/component/obeys_commands/proc/display_menu(datum/source, mob/living/clicker) +/datum/component/obeys_commands/proc/on_key_pressed(mob/living/friend) + SIGNAL_HANDLER + RegisterSignal(friend, COMSIG_ATOM_MOUSE_ENTERED, PROC_REF(on_mouse_hover)) + +/datum/component/obeys_commands/proc/on_mouse_hover(mob/living/friend, atom/mouse_hovered) SIGNAL_HANDLER + if(mouse_hovered == parent) + display_menu(friend) + return + if(isliving(mouse_hovered)) + remove_from_viewers(friend) + +/// Displays a radial menu of commands +/datum/component/obeys_commands/proc/display_menu(mob/living/friend) var/mob/living/living_parent = parent - if (IS_DEAD_OR_INCAP(living_parent) || !clicker.can_perform_action(living_parent)) + if (IS_DEAD_OR_INCAP(living_parent) || friend.stat != CONSCIOUS) return - if (!(clicker in living_parent.ai_controller?.blackboard[BB_FRIENDS_LIST])) + if (!(friend in living_parent.ai_controller?.blackboard[BB_FRIENDS_LIST])) return // Not our friend, can't boss us around - - INVOKE_ASYNC(src, PROC_REF(display_radial_menu), clicker) - return CLICK_ACTION_SUCCESS + if(radial_viewers[REF(friend)]) + return + if(!can_see(friend, parent, DEFAULT_RADIAL_VIEWING_DISTANCE)) + return + INVOKE_ASYNC(src, PROC_REF(display_radial_menu), friend) /// Actually display the radial menu and then do something with the result -/datum/component/obeys_commands/proc/display_radial_menu(mob/living/clicker) +/datum/component/obeys_commands/proc/display_radial_menu(mob/living/friend) var/list/radial_options = list() for (var/command_name as anything in available_commands) var/datum/pet_command/command = available_commands[command_name] @@ -83,9 +118,22 @@ if (!choice) continue radial_options += choice - - var/pick = show_radial_menu(clicker, clicker, radial_options, tooltips = TRUE) - if (!pick) + radial_viewers[REF(friend)] = world.time + radial_menu_lifetime + var/pick = show_radial_menu(friend, parent, radial_options, radius = radial_menu_radius, button_animation_flags = BUTTON_FADE_IN | BUTTON_FADE_OUT, custom_check = CALLBACK(src, PROC_REF(check_menu_viewer), friend), check_delay = 0.15 SECONDS, display_close_button = FALSE, radial_menu_offset = radial_menu_offset, user_space = radial_relative_to_user) + remove_from_viewers(friend) + if(!pick) return var/datum/pet_command/picked_command = available_commands[pick] - picked_command.try_activate_command(clicker) + picked_command.try_activate_command(friend, radial_command = TRUE) + +/datum/component/obeys_commands/proc/check_menu_viewer(mob/living/user) + if(QDELETED(user) || !radial_viewers[REF(user)]) + return FALSE + if(world.time > radial_viewers[REF(user)]) + return FALSE + var/viewing_distance = DEFAULT_RADIAL_VIEWING_DISTANCE + if(!can_see(user, parent, viewing_distance)) + return FALSE + return TRUE + +#undef DEFAULT_RADIAL_VIEWING_DISTANCE diff --git a/code/datums/components/pet_commands/pet_command.dm b/code/datums/components/pet_commands/pet_command.dm index 52b4cc883492..84b288a5cd80 100644 --- a/code/datums/components/pet_commands/pet_command.dm +++ b/code/datums/components/pet_commands/pet_command.dm @@ -13,7 +13,7 @@ /// If true, command will not appear in radial menu and can only be accessed through speech var/hidden = FALSE /// Icon to display in radial menu - var/icon/radial_icon + var/icon/radial_icon = 'icons/hud/radial_pets.dmi' /// Icon state to display in radial menu var/radial_icon_state /// Speech strings to listen out for @@ -24,6 +24,12 @@ var/command_feedback /// How close a mob needs to be to a target to respond to a command var/sense_radius = 7 + /// does this pet command need a point to activate? + var/requires_pointing = FALSE + /// Blackboard key for targeting strategy, this is likely going to need it + var/targeting_strategy_key = BB_PET_TARGETING_STRATEGY + ///our pointed reaction we play + var/pointed_reaction /datum/pet_command/New(mob/living/parent) . = ..() @@ -34,10 +40,17 @@ RegisterSignal(tamer, COMSIG_MOB_SAY, PROC_REF(respond_to_command)) RegisterSignal(tamer, COMSIG_MOB_AUTOMUTE_CHECK, PROC_REF(waive_automute)) RegisterSignal(tamer, COMSIG_MOB_CREATED_CALLOUT, PROC_REF(respond_to_callout)) + if(requires_pointing) + RegisterSignal(tamer, COMSIG_MOVABLE_POINTED, PROC_REF(point_on_target)) /// Stop listening to a guy /datum/pet_command/proc/remove_friend(mob/living/unfriended) - UnregisterSignal(unfriended, list(COMSIG_MOB_SAY, COMSIG_MOB_AUTOMUTE_CHECK, COMSIG_MOB_CREATED_CALLOUT)) + UnregisterSignal(unfriended, list( + COMSIG_MOB_SAY, + COMSIG_MOB_AUTOMUTE_CHECK, + COMSIG_MOB_CREATED_CALLOUT, + COMSIG_MOVABLE_POINTED, + )) /// Stop the automute from triggering for commands (unless the spoken text is suspiciously longer than the command) /datum/pet_command/proc/waive_automute(mob/living/speaker, client/client, last_message, mute_type) @@ -49,7 +62,6 @@ /// Respond to something that one of our friends has asked us to do /datum/pet_command/proc/respond_to_command(mob/living/speaker, speech_args) SIGNAL_HANDLER - var/mob/living/parent = weak_parent.resolve() if (!parent) return @@ -60,10 +72,10 @@ if (!find_command_in_text(spoken_text)) return - try_activate_command(speaker) + try_activate_command(commander = speaker, radial_command = FALSE) /// Respond to a callout -/datum/pet_command/proc/respond_to_callout(mob/living/caller, datum/callout_option/callout, atom/target) +/datum/pet_command/proc/respond_to_callout(mob/living/speaker, datum/callout_option/callout, atom/target) SIGNAL_HANDLER if (isnull(callout_type) || !ispath(callout, callout_type)) @@ -73,21 +85,21 @@ if (!parent) return - if (!valid_callout_target(caller, callout, target)) + if (!valid_callout_target(speaker, callout, target)) var/found_new_target = FALSE for (var/atom/new_target in range(2, target)) - if (valid_callout_target(caller, callout, new_target)) + if (valid_callout_target(speaker, callout, new_target)) target = new_target found_new_target = TRUE if (!found_new_target) return - if (try_activate_command(caller)) + if (try_activate_command(commander = speaker, radial_command = FALSE)) look_for_target(parent, target) /// Does this callout with this target trigger this command? -/datum/pet_command/proc/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target) +/datum/pet_command/proc/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target) return TRUE /** @@ -103,48 +115,76 @@ return TRUE return FALSE -/// Apply a command state if conditions are right, return command if successful -/datum/pet_command/proc/try_activate_command(mob/living/commander) +/datum/pet_command/proc/pet_able_to_respond() var/mob/living/parent = weak_parent.resolve() - if (!parent) + if(isnull(parent) || isnull(parent.ai_controller)) return FALSE - if (!parent.ai_controller) // We stopped having a brain at some point + if(IS_DEAD_OR_INCAP(parent)) // Probably can't hear them if we're dead return FALSE - if (IS_DEAD_OR_INCAP(parent)) // Probably can't hear them if we're dead - return FALSE - if (parent.ai_controller.blackboard[BB_ACTIVE_PET_COMMAND] == src) // We're already doing it + return TRUE + +/// Apply a command state if conditions are right, return command if successful +/datum/pet_command/proc/try_activate_command(mob/living/commander, radial_command) + if(!pet_able_to_respond()) return FALSE - set_command_active(parent, commander) + var/mob/living/parent = weak_parent.resolve() + set_command_active(parent, commander, radial_command) return TRUE +/datum/pet_command/proc/generate_emote_command(atom/target) + var/mob/living/living_pet = weak_parent?.resolve() + return isnull(living_pet) ? null : retrieve_command_text(living_pet, target) + +/datum/pet_command/proc/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to spring into action!" + /// Target the pointed atom for actions -/datum/pet_command/proc/look_for_target(mob/living/friend, atom/pointed_atom) +/datum/pet_command/proc/look_for_target(mob/living/friend, atom/potential_target) var/mob/living/parent = weak_parent.resolve() - if (!parent) - return FALSE - if (!parent.ai_controller) - return FALSE - if (IS_DEAD_OR_INCAP(parent)) + if(!pet_able_to_respond()) return FALSE - if (parent.ai_controller.blackboard[BB_ACTIVE_PET_COMMAND] != src) // We're not listening right now + if (parent.ai_controller.blackboard[BB_CURRENT_PET_TARGET] == potential_target) // That's already our target return FALSE - if (parent.ai_controller.blackboard[BB_CURRENT_PET_TARGET] == pointed_atom) // That's already our target - return FALSE - if (!can_see(parent, pointed_atom, sense_radius)) + if (!can_see(parent, potential_target, sense_radius)) return FALSE parent.ai_controller.CancelActions() - set_command_target(parent, pointed_atom) + set_command_target(parent, potential_target) return TRUE /// Activate the command, extend to add visible messages and the like -/datum/pet_command/proc/set_command_active(mob/living/parent, mob/living/commander) - set_command_target(parent, null) +/datum/pet_command/proc/set_command_active(mob/living/parent, mob/living/commander, radial_command = FALSE) + parent.ai_controller.clear_blackboard_key(BB_CURRENT_PET_TARGET) parent.ai_controller.CancelActions() // Stop whatever you're doing and do this instead parent.ai_controller.set_blackboard_key(BB_ACTIVE_PET_COMMAND, src) if (command_feedback) parent.balloon_alert_to_viewers("[command_feedback]") // If we get a nicer runechat way to do this, refactor this + if(!radial_command) + return + if(!requires_pointing) + var/manual_emote_text = generate_emote_command() + commander.manual_emote(manual_emote_text) + return + RegisterSignal(commander, COMSIG_MOB_CLICKON, PROC_REF(click_on_target)) + commander.client?.mouse_override_icon = 'icons/effects/mouse_pointers/pet_paw.dmi' + commander.update_mouse_pointer() + +/datum/pet_command/proc/click_on_target(mob/living/source, atom/target, list/modifiers) + SIGNAL_HANDLER + if(!can_see(source, target, 9)) + return COMSIG_MOB_CANCEL_CLICKON + var/manual_emote_text = generate_emote_command(target) + if(on_target_set(source, target) && !isnull(manual_emote_text)) + INVOKE_ASYNC(source, TYPE_PROC_REF(/atom, manual_emote), manual_emote_text) + UnregisterSignal(source, COMSIG_MOB_CLICKON) + source.client?.mouse_override_icon = source.client::mouse_override_icon + source.update_mouse_pointer() + return COMSIG_MOB_CANCEL_CLICKON + +/datum/pet_command/proc/point_on_target(mob/living/friend, atom/potential_target) + SIGNAL_HANDLER + on_target_set(friend, potential_target) /// Store the target for the AI blackboard /datum/pet_command/proc/set_command_target(mob/living/parent, atom/target) @@ -158,11 +198,6 @@ var/datum/radial_menu_choice/choice = new() choice.name = command_name choice.image = icon(icon = radial_icon, icon_state = radial_icon_state) - var/tooltip = command_desc - if (length(speech_commands)) - tooltip += "
Speak this command with the words [speech_commands.Join(", ")]." - choice.info = tooltip - return list("[command_name]" = choice) /** @@ -174,34 +209,16 @@ SHOULD_CALL_PARENT(FALSE) CRASH("Pet command execute action not implemented.") -/** - * # Point Targeting Pet Command - * As above but also listens for you pointing at something and marks it as a target - */ -/datum/pet_command/point_targeting - /// Text describing an action we perform upon receiving a new target - var/pointed_reaction - /// Blackboard key for targeting strategy, this is likely going to need it - var/targeting_strategy_key = BB_PET_TARGETING_STRATEGY - -/datum/pet_command/point_targeting/add_new_friend(mob/living/tamer) - . = ..() - RegisterSignal(tamer, COMSIG_MOVABLE_POINTED, PROC_REF(on_point)) - -/datum/pet_command/point_targeting/remove_friend(mob/living/unfriended) - . = ..() - UnregisterSignal(unfriended, COMSIG_MOVABLE_POINTED) - /// Target the pointed atom for actions -/datum/pet_command/point_targeting/proc/on_point(mob/living/friend, atom/pointed_atom, obj/effect/temp_visual/point/point) - SIGNAL_HANDLER - +/datum/pet_command/proc/on_target_set(mob/living/friend, atom/potential_target) var/mob/living/parent = weak_parent.resolve() if (!parent) return FALSE parent.ai_controller.CancelActions() - if (look_for_target(friend, pointed_atom) && set_command_target(parent, pointed_atom)) - parent.visible_message(span_warning("[parent] follows [friend]'s gesture towards [pointed_atom] [pointed_reaction]!")) - return TRUE - return FALSE + if(!look_for_target(friend, potential_target) || !set_command_target(parent, potential_target)) + return FALSE + parent.visible_message(span_warning("[parent] follows [friend]'s gesture towards [potential_target] [pointed_reaction]!")) + return TRUE + + diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm index fd4e1f922c8b..cd535b33ecab 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -7,14 +7,16 @@ /datum/pet_command/idle command_name = "Stay" command_desc = "Command your pet to stay idle in this location." - radial_icon = 'icons/obj/bed.dmi' - radial_icon_state = "dogbed" + radial_icon_state = "halt" speech_commands = list("sit", "stay", "stop") command_feedback = "sits" /datum/pet_command/idle/execute_action(datum/ai_controller/controller) return SUBTREE_RETURN_FINISH_PLANNING // This cancels further AI planning +/datum/pet_command/idle/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to stay idle!" + /** * # Pet Command: Stop * Tells a pet to exit command mode and resume its normal behaviour, which includes regular target-seeking and what have you @@ -22,8 +24,7 @@ /datum/pet_command/free command_name = "Loose" command_desc = "Allow your pet to resume its natural behaviours." - radial_icon = 'icons/mob/actions/actions_spells.dmi' - radial_icon_state = "repulse" + radial_icon_state = "free" speech_commands = list("free", "loose") command_feedback = "relaxes" @@ -31,6 +32,9 @@ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return // Just move on to the next planning subtree. +/datum/pet_command/free/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to go free!" + /** * # Pet Command: Follow * Tells a pet to follow you until you tell it to do something else @@ -38,8 +42,7 @@ /datum/pet_command/follow command_name = "Follow" command_desc = "Command your pet to accompany you." - radial_icon = 'icons/testing/turf_analysis.dmi' - radial_icon_state = "red_arrow" + radial_icon_state = "follow" speech_commands = list("heel", "follow") callout_type = /datum/callout_option/move ///the behavior we use to follow @@ -49,6 +52,9 @@ . = ..() set_command_target(parent, commander) +/datum/pet_command/follow/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to follow!" + /datum/pet_command/follow/execute_action(datum/ai_controller/controller) controller.queue_behavior(follow_behavior, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING @@ -60,14 +66,16 @@ /datum/pet_command/play_dead command_name = "Play Dead" command_desc = "Play a macabre trick." - radial_icon = 'icons/mob/simple/pets.dmi' - radial_icon_state = "puppy_dead" + radial_icon_state = "play_dead" speech_commands = list("play dead") // Don't get too creative here, people talk about dying pretty often /datum/pet_command/play_dead/execute_action(datum/ai_controller/controller) controller.queue_behavior(/datum/ai_behavior/play_dead) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/play_dead/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to play dead!" + /** * # Pet Command: Good Boy * React if complimented @@ -115,16 +123,18 @@ controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/untargeted_ability/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to use an ability!" + /** * # Pet Command: Attack * Tells a pet to chase and bite the next thing you point at */ -/datum/pet_command/point_targeting/attack +/datum/pet_command/attack command_name = "Attack" command_desc = "Command your pet to attack things that you point out to it." - radial_icon = 'icons/effects/effects.dmi' - radial_icon_state = "bite" - + radial_icon_state = "attack" + requires_pointing = TRUE callout_type = /datum/callout_option/attack speech_commands = list("attack", "sic", "kill") command_feedback = "growl" @@ -135,70 +145,78 @@ var/attack_behaviour = /datum/ai_behavior/basic_melee_attack // Refuse to target things we can't target, chiefly other friends -/datum/pet_command/point_targeting/attack/set_command_target(mob/living/parent, atom/target) +/datum/pet_command/attack/set_command_target(mob/living/parent, atom/target) if (!target) - return + return FALSE var/mob/living/living_parent = parent if (!living_parent.ai_controller) - return + return FALSE var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(living_parent.ai_controller.blackboard[targeting_strategy_key]) if (!targeter) - return + return FALSE if (!targeter.can_attack(living_parent, target)) refuse_target(parent, target) - return + return FALSE return ..() +/datum/pet_command/attack/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to attack [target]!" + /// Display feedback about not targeting something -/datum/pet_command/point_targeting/attack/proc/refuse_target(mob/living/parent, atom/target) +/datum/pet_command/attack/proc/refuse_target(mob/living/parent, atom/target) var/mob/living/living_parent = parent living_parent.balloon_alert_to_viewers("[refuse_reaction]") living_parent.visible_message(span_notice("[living_parent] refuses to attack [target].")) -/datum/pet_command/point_targeting/attack/execute_action(datum/ai_controller/controller) +/datum/pet_command/attack/execute_action(datum/ai_controller/controller) controller.queue_behavior(attack_behaviour, BB_CURRENT_PET_TARGET, targeting_strategy_key) return SUBTREE_RETURN_FINISH_PLANNING /** * # Breed command. breed with a partner! */ -/datum/pet_command/point_targeting/breed +/datum/pet_command/breed command_name = "Breed" command_desc = "Command your pet to attempt to breed with a partner." - radial_icon = 'icons/mob/simple/animal.dmi' - radial_icon_state = "heart" + requires_pointing = TRUE + radial_icon_state = "breed" speech_commands = list("breed", "consummate") + ///the behavior we use to make babies var/datum/ai_behavior/reproduce_behavior = /datum/ai_behavior/make_babies -/datum/pet_command/point_targeting/breed/set_command_target(mob/living/parent, atom/target) +/datum/pet_command/breed/set_command_target(mob/living/parent, atom/target) if(isnull(target) || !isliving(target)) - return + return FALSE if(!HAS_TRAIT(parent, TRAIT_MOB_BREEDER) || !HAS_TRAIT(target, TRAIT_MOB_BREEDER)) - return + return FALSE if(isnull(parent.ai_controller)) - return + return FALSE if(!parent.ai_controller.blackboard[BB_BREED_READY] || isnull(parent.ai_controller.blackboard[BB_BABIES_PARTNER_TYPES])) - return + return FALSE var/mob/living/living_target = target if(!living_target.ai_controller?.blackboard[BB_BREED_READY]) - return + return FALSE return ..() -/datum/pet_command/point_targeting/breed/execute_action(datum/ai_controller/controller) +/datum/pet_command/breed/execute_action(datum/ai_controller/controller) if(is_type_in_list(controller.blackboard[BB_CURRENT_PET_TARGET], controller.blackboard[BB_BABIES_PARTNER_TYPES])) controller.queue_behavior(reproduce_behavior, BB_CURRENT_PET_TARGET) controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/breed/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to breed with [target]!" + /** * # Pet Command: Targetted Ability * Tells a pet to use some kind of ability on the next thing you point at */ -/datum/pet_command/point_targeting/use_ability +/datum/pet_command/use_ability command_name = "Use ability" command_desc = "Command your pet to use one of its special skills on something that you point out to it." radial_icon = 'icons/mob/actions/actions_spells.dmi' radial_icon_state = "projectile" + requires_pointing = TRUE speech_commands = list("shoot", "blast", "cast") command_feedback = "growl" pointed_reaction = "and growls" @@ -207,7 +225,7 @@ /// The AI behavior to use for the ability var/ability_behavior = /datum/ai_behavior/pet_use_ability -/datum/pet_command/point_targeting/use_ability/execute_action(datum/ai_controller/controller) +/datum/pet_command/use_ability/execute_action(datum/ai_controller/controller) if (!pet_ability_key) return var/datum/action/cooldown/using_action = controller.blackboard[pet_ability_key] @@ -218,6 +236,9 @@ controller.queue_behavior(ability_behavior, pet_ability_key, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING +/datum/pet_command/use_ability/retrieve_command_text(atom/living_pet, atom/target) + return isnull(target) ? null : "signals [living_pet] to use an ability on [target]!" + /datum/pet_command/protect_owner command_name = "Protect owner" command_desc = "Your pet will run to your aid." @@ -253,8 +274,8 @@ . = ..() set_command_target(parent, victim) -/datum/pet_command/protect_owner/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target) - return target == caller || get_dist(caller, target) <= 1 +/datum/pet_command/protect_owner/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target) + return target == speaker || get_dist(speaker, target) <= 1 /datum/pet_command/protect_owner/proc/set_attacking_target(atom/source, mob/living/attacker) SIGNAL_HANDLER @@ -278,25 +299,39 @@ /** * # Fish command: command the mob to fish at the next fishing spot you point at. Requires the profound fisher component */ -/datum/pet_command/point_targeting/fish +/datum/pet_command/fish command_name = "Fish" command_desc = "Command your pet to try fishing at a nearby fishing spot." - radial_icon = 'icons/obj/aquarium/fish.dmi' - radial_icon_state = "goldfish" + requires_pointing = TRUE + radial_icon_state = "fish" speech_commands = list("fish") -// Refuse to target things we can't target, chiefly other friends -/datum/pet_command/point_targeting/fish/set_command_target(mob/living/parent, atom/target) - if (!target) - return - if(!parent.ai_controller || !HAS_TRAIT(parent, TRAIT_PROFOUND_FISHER)) - return - var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(/datum/targeting_strategy/fishing) - if (!targeter?.can_attack(parent, target)) - parent.balloon_alert_to_viewers("shakes head!") - return +/datum/pet_command/fish/execute_action(datum/ai_controller/controller) + if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET)) + controller.queue_behavior(/datum/ai_behavior/interact_with_target/fishing, BB_CURRENT_PET_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/pet_command/fish/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to go fish!" + +/datum/pet_command/move + command_name = "Move" + command_desc = "Command your pet to move to a location!" + requires_pointing = TRUE + radial_icon_state = "move" + speech_commands = list("move", "walk") + ///the behavior we use to walk towards targets + var/datum/ai_behavior/walk_behavior = /datum/ai_behavior/travel_towards + +/datum/pet_command/move/set_command_target(mob/living/parent, atom/target) + if(isnull(target) || !can_see(parent, target, 9)) + return FALSE return ..() -/datum/pet_command/point_targeting/fish/execute_action(datum/ai_controller/controller) - controller.queue_behavior(/datum/ai_behavior/hunt_target/interact_with_target/reset_target_combat_mode_off, BB_CURRENT_PET_TARGET) +/datum/pet_command/move/execute_action(datum/ai_controller/controller) + if(controller.blackboard_key_exists(BB_CURRENT_PET_TARGET)) + controller.queue_behavior(walk_behavior, BB_CURRENT_PET_TARGET) return SUBTREE_RETURN_FINISH_PLANNING + +/datum/pet_command/move/retrieve_command_text(atom/living_pet, atom/target) + return "signals [living_pet] to move!" diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm index a1be66654a2c..5bf95b747e3c 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -121,6 +121,8 @@ ///returns TRUE when they can give the specified amount and reagent. called by process request /datum/component/plumbing/proc/can_give(amount, reagent, datum/ductnet/net) + SHOULD_BE_PURE(TRUE) + if(amount <= 0) return @@ -335,7 +337,7 @@ tile_covered = should_hide parent_obj.update_appearance() -/datum/component/plumbing/proc/change_ducting_layer(obj/caller, obj/changer, new_layer = DUCT_LAYER_DEFAULT) +/datum/component/plumbing/proc/change_ducting_layer(obj/source, obj/changer, new_layer = DUCT_LAYER_DEFAULT) SIGNAL_HANDLER ducting_layer = new_layer diff --git a/code/datums/components/plumbing/reaction_chamber.dm b/code/datums/components/plumbing/reaction_chamber.dm index d0aff2f50708..f095f07262b5 100644 --- a/code/datums/components/plumbing/reaction_chamber.dm +++ b/code/datums/components/plumbing/reaction_chamber.dm @@ -8,20 +8,41 @@ return COMPONENT_INCOMPATIBLE /datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net) - . = ..() + . = FALSE + var/obj/machinery/plumbing/reaction_chamber/reaction_chamber = parent - if(!. || !reaction_chamber.emptying || reagents.is_reacting) - return FALSE + + //cannot give when we outselves are requesting or reacting the reagents + if(amount <= 0 || !reagents.total_volume || !reaction_chamber.emptying || reagents.is_reacting) + return + + //check to see if we can give catalysts only if they are in excess + var/list/datum/reagent/catalysts = reaction_chamber.catalysts + for(var/datum/reagent/chemical as anything in reagents.reagent_list) + if(reagent && chemical.type != reagent) + continue + + //we have the exact amounts so no excess to spare + if(chemical.volume <= (catalysts[chemical.type] || 0)) + if(reagent) + break + else + continue + + //atleast 1 reagent to give so take whatever + return TRUE /datum/component/plumbing/reaction_chamber/send_request(dir) var/obj/machinery/plumbing/reaction_chamber/chamber = parent + if(chamber.emptying) return //take in reagents var/present_amount var/diff - for(var/required_reagent in chamber.required_reagents) + var/list/datum/reagent/required_reagents = chamber.catalysts | chamber.required_reagents + for(var/datum/reagent/required_reagent as anything in required_reagents) //find how much amount is already present if at all and get the reagent reference present_amount = 0 for(var/datum/reagent/present_reagent as anything in reagents.reagent_list) @@ -30,10 +51,11 @@ break //compute how much more is needed - diff = min(chamber.required_reagents[required_reagent] - present_amount, MACHINE_REAGENT_TRANSFER) + diff = min(required_reagents[required_reagent] - present_amount, MACHINE_REAGENT_TRANSFER) if(diff >= CHEMICAL_QUANTISATION_LEVEL) // the closest we can ask for so values like 0.9999 become 1 process_request(diff, required_reagent, dir) - return + if(!chamber.catalysts[required_reagent]) //only block if not a catalyst as they can come in whenever they are available + return reagents.flags &= ~NO_REACT reagents.handle_reactions() diff --git a/code/datums/components/plumbing/simple_components.dm b/code/datums/components/plumbing/simple_components.dm index d1f8a4c3ca63..1378780353a4 100644 --- a/code/datums/components/plumbing/simple_components.dm +++ b/code/datums/components/plumbing/simple_components.dm @@ -22,5 +22,5 @@ demand_connects = NORTH supply_connects = SOUTH -/datum/component/plumbing/manifold/change_ducting_layer(obj/caller, obj/changer, new_layer) +/datum/component/plumbing/manifold/change_ducting_layer(obj/source, obj/changer, new_layer) return diff --git a/code/datums/components/seethrough_mob.dm b/code/datums/components/seethrough_mob.dm index b6951c5489b6..23b860ac566e 100644 --- a/code/datums/components/seethrough_mob.dm +++ b/code/datums/components/seethrough_mob.dm @@ -17,7 +17,7 @@ ///This component's personal uid var/personal_uid -/datum/component/seethrough_mob/Initialize(target_alpha = 100, animation_time = 0.5 SECONDS, clickthrough = TRUE) +/datum/component/seethrough_mob/Initialize(target_alpha = 100, animation_time = 0.5 SECONDS, clickthrough = TRUE, keep_color = FALSE) . = ..() if(!ismob(parent)) @@ -33,9 +33,9 @@ uid++ src.personal_uid = uid - render_source_atom.appearance_flags |= ( RESET_COLOR | RESET_TRANSFORM) + render_source_atom.appearance_flags |= KEEP_APART - render_source_atom.vis_flags |= (VIS_INHERIT_ID | VIS_INHERIT_PLANE | VIS_INHERIT_LAYER) + render_source_atom.vis_flags |= (VIS_INHERIT_ID|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER) render_source_atom.render_source = "*transparent_bigmob[personal_uid]" @@ -55,9 +55,8 @@ for(var/atom/movable/screen/plane_master/seethrough as anything in our_hud.get_true_plane_masters(SEETHROUGH_PLANE)) seethrough.unhide_plane(fool) - var/icon/current_mob_icon = icon(fool.icon, fool.icon_state) render_source_atom.pixel_x = -fool.pixel_x - render_source_atom.pixel_y = ((current_mob_icon.Height() - 32) * 0.5) + render_source_atom.pixel_y = ((fool.get_cached_height() - ICON_SIZE_Y) * 0.5) initial_render_target_value = fool.render_target fool.render_target = "*transparent_bigmob[personal_uid]" diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm index 23977d6d8eb2..14183e4beb63 100644 --- a/code/datums/components/supermatter_crystal.dm +++ b/code/datums/components/supermatter_crystal.dm @@ -165,10 +165,7 @@ var/obj/item/cigarette/cig = item var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY) if(clumsy) - var/which_hand = BODY_ZONE_L_ARM - if(!(user.active_hand_index % 2)) - which_hand = BODY_ZONE_R_ARM - var/obj/item/bodypart/dust_arm = user.get_bodypart(which_hand) + var/obj/item/bodypart/dust_arm = user.get_active_hand() dust_arm.dismember() user.visible_message(span_danger("The [item] flashes out of existence on contact with \the [atom_source], resonating with a horrible sound..."),\ span_danger("Oops! The [item] flashes out of existence on contact with \the [atom_source], taking your arm with it! That was clumsy of you!")) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index a4652d354a55..f89e24ffcb6d 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -274,6 +274,7 @@ user.visible_message(span_warning("[user] lands a [tackle_word] on [target], briefly staggering them both!"), span_userdanger("You land a [tackle_word] on [target], briefly staggering [target.p_them()] and yourself!"), ignored_mobs = target) to_chat(target, span_userdanger("[user] lands a [tackle_word] on you, briefly staggering you both!")) + user.SetKnockdown(0, ignore_canstun = TRUE) user.get_up(TRUE) user.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS) target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH * 2, 10 SECONDS) //okay maybe slightly good for the sacker, it's a mild benefit okay? @@ -527,12 +528,8 @@ if(99 to INFINITY) // can you imagine standing around minding your own business when all of the sudden some guy fucking launches himself into a wall at full speed and irreparably paralyzes himself? user.visible_message(span_danger("[user] slams face-first into [hit] at an awkward angle, severing [user.p_their()] spinal column with a sickening crack! Fucking shit!"), span_userdanger("You slam face-first into [hit] at an awkward angle, severing your spinal column with a sickening crack! Fucking shit!")) - var/obj/item/bodypart/head/hed = user.get_bodypart(BODY_ZONE_HEAD) - if(hed) - hed.receive_damage(brute=40, updating_health=FALSE, wound_bonus = 40) - else - user.adjustBruteLoss(40, updating_health=FALSE) - user.adjustStaminaLoss(30) + user.apply_damage(40, BRUTE, BODY_ZONE_HEAD, wound_bonus = 40) + user.apply_damage(30, STAMINA) playsound(user, 'sound/effects/blob/blobattack.ogg', 60, TRUE) playsound(user, 'sound/effects/splat.ogg', 70, TRUE) playsound(user, 'sound/effects/wounds/crack2.ogg', 70, TRUE) @@ -543,12 +540,8 @@ if(97 to 98) user.visible_message(span_danger("[user] slams skull-first into [hit] with a sound like crumpled paper, revealing a horrifying breakage in [user.p_their()] cranium! Holy shit!"), span_userdanger("You slam skull-first into [hit] and your senses are filled with warm goo flooding across your face! Your skull is open!")) - var/obj/item/bodypart/head/hed = user.get_bodypart(BODY_ZONE_HEAD) - if(hed) - hed.receive_damage(brute = 30, updating_health = FALSE, wound_bonus = 25) - else - user.adjustBruteLoss(40, updating_health = FALSE) - user.adjustStaminaLoss(30) + user.apply_damage(30, BRUTE, BODY_ZONE_HEAD, wound_bonus = 25) + user.apply_damage(30, STAMINA) user.gain_trauma_type(BRAIN_TRAUMA_MILD) playsound(user, 'sound/effects/blob/blobattack.ogg', 60, TRUE) playsound(user, 'sound/effects/splat.ogg', 70, TRUE) @@ -558,8 +551,8 @@ if(93 to 96) user.visible_message(span_danger("[user] slams face-first into [hit] with a concerning squish, immediately going limp!"), span_userdanger("You slam face-first into [hit], and immediately lose consciousness!")) - user.adjustStaminaLoss(30) - user.adjustBruteLoss(30) + user.apply_damage(30, BRUTE, spread_damage = TRUE) + user.apply_damage(30, STAMINA) user.Unconscious(10 SECONDS) user.gain_trauma_type(BRAIN_TRAUMA_MILD) user.playsound_local(get_turf(user), 'sound/items/weapons/flashbang.ogg', 100, TRUE, 8) @@ -568,8 +561,8 @@ if(86 to 92) user.visible_message(span_danger("[user] slams head-first into [hit], suffering major cranial trauma!"), span_userdanger("You slam head-first into [hit], and the world explodes around you!")) - user.adjustStaminaLoss(30, updating_stamina = FALSE) - user.adjustBruteLoss(30) + user.apply_damage(30, BRUTE, spread_damage = TRUE) + user.apply_damage(30, STAMINA) user.adjust_confusion(15 SECONDS) if(prob(80)) user.gain_trauma(/datum/brain_trauma/mild/concussion) @@ -580,16 +573,16 @@ if(68 to 85) user.visible_message(span_danger("[user] slams hard into [hit], knocking [user.p_them()] senseless!"), span_userdanger("You slam hard into [hit], knocking yourself senseless!")) - user.adjustStaminaLoss(30, updating_stamina = FALSE) - user.adjustBruteLoss(10) + user.apply_damage(10, BRUTE, spread_damage = TRUE) + user.apply_damage(30, STAMINA) user.adjust_confusion(10 SECONDS) user.Knockdown(3 SECONDS) shake_camera(user, 3, 4) if(1 to 67) user.visible_message(span_danger("[user] slams into [hit]!"), span_userdanger("You slam into [hit]!")) - user.adjustStaminaLoss(20, updating_stamina = FALSE) - user.adjustBruteLoss(10) + user.apply_damage(10, BRUTE, spread_damage = TRUE) + user.apply_damage(20, STAMINA) user.Knockdown(2 SECONDS) shake_camera(user, 2, 2) @@ -602,32 +595,32 @@ UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) ///A special case for splatting for handling windows -/datum/component/tackler/proc/splatWindow(mob/living/carbon/user, obj/structure/window/W) +/datum/component/tackler/proc/splatWindow(mob/living/carbon/user, obj/structure/window/windscreen_casualty) playsound(user, 'sound/effects/glass/Glasshit.ogg', 140, TRUE) - if(W.type in list(/obj/structure/window, /obj/structure/window/fulltile, /obj/structure/window/unanchored, /obj/structure/window/fulltile/unanchored)) // boring unreinforced windows + if(windscreen_casualty.type in list(/obj/structure/window, /obj/structure/window/fulltile, /obj/structure/window/unanchored, /obj/structure/window/fulltile/unanchored)) // boring unreinforced windows for(var/i in 1 to speed) var/obj/item/shard/shard = new /obj/item/shard(get_turf(user)) shard.set_embed(/datum/embed_data/glass_candy) user.hitby(shard, skipcatch = TRUE, hitpush = FALSE) shard.set_embed(initial(shard.embed_type)) - W.atom_destruction() + windscreen_casualty.atom_destruction() user.adjustStaminaLoss(10 * speed) user.Paralyze(3 SECONDS) - user.visible_message(span_danger("[user] smacks into [W] and shatters it, shredding [user.p_them()]self with glass!"), span_userdanger("You smacks into [W] and shatter it, shredding yourself with glass!")) + user.visible_message(span_danger("[user] smacks into [windscreen_casualty] and shatters it, shredding [user.p_them()]self with glass!"), span_userdanger("You smacks into [windscreen_casualty] and shatter it, shredding yourself with glass!")) else - user.visible_message(span_danger("[user] smacks into [W] like a bug!"), span_userdanger("You smacks into [W] like a bug!")) + user.visible_message(span_danger("[user] smacks into [windscreen_casualty] like a bug!"), span_userdanger("You smacks into [windscreen_casualty] like a bug!")) user.Paralyze(1 SECONDS) user.Knockdown(3 SECONDS) - W.take_damage(30 * speed) + windscreen_casualty.take_damage(30 * speed) user.adjustStaminaLoss(10 * speed, updating_stamina=FALSE) user.adjustBruteLoss(5 * speed) -/datum/component/tackler/proc/delayedSmash(obj/structure/window/W) - if(W) - W.atom_destruction() - playsound(W, SFX_SHATTER, 70, TRUE) +/datum/component/tackler/proc/delayedSmash(obj/structure/window/windscreen_casualty) + if(windscreen_casualty) + windscreen_casualty.atom_destruction() + playsound(windscreen_casualty, SFX_SHATTER, 70, TRUE) ///Check to see if we hit a table, and if so, make a big mess! /datum/component/tackler/proc/checkObstacle(mob/living/carbon/owner) @@ -636,8 +629,8 @@ if(!tackling) return - var/turf/T = get_turf(owner) - var/obj/structure/table/kevved = locate(/obj/structure/table) in T.contents + var/turf/our_turf = get_turf(owner) + var/obj/structure/table/kevved = locate(/obj/structure/table) in our_turf.contents if(!kevved) return @@ -645,9 +638,9 @@ // we split the mess-making into two parts (check what we're gonna send flying, intermission for dealing with the tackler, then actually send stuff flying) for the benefit of making sure the face-slam text // comes before the list of stuff that goes flying, but can still adjust text + damage to how much of a mess it made - for(var/obj/item/I in T.contents) - if(!I.anchored) - messes += I + for(var/obj/item/item_in_turf in our_turf.contents) + if(!item_in_turf.anchored) + messes += item_in_turf if(messes.len >= MAX_TABLE_MESSES) break @@ -672,13 +665,15 @@ owner.Knockdown(2 SECONDS + 0.4 SECONDS * messes.len) // 2 seconds of knockdown after the paralyze owner.updatehealth() - for(var/obj/item/I in messes) - var/dist = rand(1, 3) - var/sp = 2 + for(var/obj/item/item_in_mess in messes) + // The amount of distance the object flies away when launched by our tackle + var/item_launch_distance = rand(1, 3) + // The transfered speed at which an item is launched by our tackle + var/item_launch_speed = 2 if(prob(25 * (src.speed - 1))) // if our tackle speed is higher than 1, with chance (speed - 1 * 25%), throw the thing at our tackle speed + 1 - sp = speed + 1 - I.throw_at(get_ranged_target_turf(I, pick(GLOB.alldirs), range = dist), range = dist, speed = sp) - I.visible_message(span_danger("[I] goes flying[sp > 3 ? " dangerously fast" : ""]!")) // standard embed speed + item_launch_speed = speed + 1 + item_in_mess.throw_at(get_ranged_target_turf(item_in_mess, pick(GLOB.alldirs), range = item_launch_distance), range = item_launch_distance, speed = item_launch_speed) + item_in_mess.visible_message(span_danger("[item_in_mess] goes flying[item_launch_speed < EMBED_THROWSPEED_THRESHOLD ? "" : " dangerously fast" ]!")) // standard embed speed var/datum/thrownthing/tackle = tackle_ref?.resolve() diff --git a/code/datums/components/tameable.dm b/code/datums/components/tameable.dm index 0d77688a22e7..747d729ee1dc 100644 --- a/code/datums/components/tameable.dm +++ b/code/datums/components/tameable.dm @@ -2,8 +2,6 @@ /datum/component/tameable ///If true, this atom can only be domesticated by one person var/unique - ///What the mob eats, typically used for taming or animal husbandry. - var/list/food_types ///Starting success chance for taming. var/tame_chance ///Added success chance after every failed tame attempt. @@ -15,8 +13,6 @@ if(!isatom(parent)) //yes, you could make a tameable toolbox. return COMPONENT_INCOMPATIBLE - if(food_types) - src.food_types = food_types if(tame_chance) src.tame_chance = tame_chance src.current_tame_chance = tame_chance @@ -24,35 +20,30 @@ src.bonus_tame_chance = bonus_tame_chance src.unique = unique - RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(try_tame)) + if(food_types && !HAS_TRAIT(parent, TRAIT_MOB_EATER)) + parent.AddElement(/datum/element/basic_eating, food_types = food_types) + + RegisterSignal(parent, COMSIG_MOB_ATE, PROC_REF(try_tame)) RegisterSignal(parent, COMSIG_SIMPLEMOB_SENTIENCEPOTION, PROC_REF(on_tame)) //Instantly succeeds RegisterSignal(parent, COMSIG_SIMPLEMOB_TRANSFERPOTION, PROC_REF(on_tame)) //Instantly succeeds -/datum/component/tameable/proc/try_tame(datum/source, obj/item/food, mob/living/attacker, params) +/datum/component/tameable/proc/try_tame(atom/source, obj/item/food, mob/living/attacker) SIGNAL_HANDLER - if(!is_type_in_list(food, food_types)) + + if(isnull(attacker) || already_friends(attacker)) return - if(isliving(source)) - var/mob/living/potentially_dead_horse = source - if(potentially_dead_horse.stat == DEAD) - to_chat(attacker, span_warning("[parent] is dead!")) - return COMPONENT_CANCEL_ATTACK_CHAIN - var/atom/atom_parent = source var/inform_tamer = FALSE - atom_parent.balloon_alert(attacker, "fed") var/modified_tame_chance = current_tame_chance if(HAS_TRAIT(attacker, TRAIT_BEAST_EMPATHY)) modified_tame_chance += 50 inform_tamer = TRUE - if(unique || !already_friends(attacker)) - if(prob(modified_tame_chance)) //note: lack of feedback message is deliberate, keep them guessing unless they're an expert! - on_tame(source, attacker, food, inform_tamer) - else - current_tame_chance += bonus_tame_chance - qdel(food) - return COMPONENT_CANCEL_ATTACK_CHAIN + source.balloon_alert(attacker, "eats from your hand") + if(prob(modified_tame_chance)) //note: lack of feedback message is deliberate, keep them guessing unless they're an expert! + on_tame(source, attacker, food, inform_tamer) + else + current_tame_chance += bonus_tame_chance /// Check if the passed mob is already considered one of our friends /datum/component/tameable/proc/already_friends(mob/living/potential_friend) diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm index 1fac66c07cd6..718ef86647b9 100644 --- a/code/datums/components/thermite.dm +++ b/code/datums/components/thermite.dm @@ -179,16 +179,10 @@ if(!iscarbon(user) || user.can_touch_burning(source)) return NONE - var/obj/item/bodypart/affecting = user.get_active_hand() - //Should not happen! - if(!affecting) - return NONE - - affecting.receive_damage(burn = 5) + user.apply_damage(5, BURN, user.get_active_hand()) to_chat(user, span_userdanger("The ignited thermite on \the [source] burns your hand!")) INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, emote), "scream") playsound(source, SFX_SEAR, 50, TRUE) - user.update_damage_overlays() return COMPONENT_CANCEL_ATTACK_CHAIN /** diff --git a/code/datums/components/throwbonus_on_windup.dm b/code/datums/components/throwbonus_on_windup.dm index ed505d69697d..56e3de5cd815 100644 --- a/code/datums/components/throwbonus_on_windup.dm +++ b/code/datums/components/throwbonus_on_windup.dm @@ -52,8 +52,7 @@ return if(throw_text) to_chat(our_holder, span_warning(throw_text)) - var/list/offset_to_add = get_icon_dimensions(our_holder.icon) - var/x_position = CEILING(offset_to_add["width"] * 0.5, 1) + var/x_position = CEILING(our_holder.get_visual_width() * 0.5, 1) our_bar = new() our_bar.maximum_count = maximum_bonus our_bar.pixel_x = x_position diff --git a/code/datums/components/trader/trader.dm b/code/datums/components/trader/trader.dm index d623a9943b89..3b2675785aec 100644 --- a/code/datums/components/trader/trader.dm +++ b/code/datums/components/trader/trader.dm @@ -394,7 +394,7 @@ Can accept both a type path, and an instance of a datum. Type path has priority. else buy_info += span_notice("• [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name][product_info[TRADER_PRODUCT_INFO_PRICE_MOD_DESCRIPTION]]; willing to buy [span_green("[tern_op_result]")]") - to_chat(customer, examine_block(buy_info.Join("\n"))) + to_chat(customer, boxed_message(buy_info.Join("\n"))) ///Displays to the customer what the trader is selling and how much is in stock /datum/component/trader/proc/trader_sells_what(mob/customer) @@ -413,7 +413,7 @@ Can accept both a type path, and an instance of a datum. Type path has priority. sell_info += span_notice("• [span_red("(OUT OF STOCK)")] [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name]; [span_red("[tern_op_result]")] left in stock") else sell_info += span_notice("• [initial(thing.name)] for [product_info[TRADER_PRODUCT_INFO_PRICE]] [trader_data.currency_name]; [span_green("[tern_op_result]")] left in stock") - to_chat(customer, examine_block(sell_info.Join("\n"))) + to_chat(customer, boxed_message(sell_info.Join("\n"))) ///Sets quantity of all products to initial(quanity); this proc is currently called during initialize /datum/component/trader/proc/restock_products() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 9145106d6e02..5fe2273a82ff 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -633,8 +633,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.update_body_size() // NOVA EDIT ADDITION END - - dna.species.on_species_gain(src, old_species, pref_load) + dna.species.on_species_gain(src, old_species, pref_load, regenerate_icons = icon_update) log_mob_tag("TAG: [tag] SPECIES: [key_name(src)] \[[mrace]\]") /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) diff --git a/code/datums/drift_handler.dm b/code/datums/drift_handler.dm index 215305843647..559ea9e13ca8 100644 --- a/code/datums/drift_handler.dm +++ b/code/datums/drift_handler.dm @@ -36,7 +36,6 @@ RegisterSignal(drifting_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(before_move)) RegisterSignal(drifting_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(after_move)) RegisterSignal(drifting_loop, COMSIG_QDELETING, PROC_REF(loop_death)) - RegisterSignal(parent, COMSIG_MOB_ATTEMPT_HALT_SPACEMOVE, PROC_REF(attempt_halt)) if(drifting_loop.status & MOVELOOP_STATUS_RUNNING) drifting_start(drifting_loop) // There's a good chance it'll autostart, gotta catch that @@ -49,6 +48,9 @@ visual_delay = start_delay apply_initial_visuals(visual_delay) + // Fire the engines! + if (drifting_loop.timer <= world.time) + SSnewtonian_movement.fire_moveloop(drifting_loop) /datum/drift_handler/Destroy() inertia_last_loc = null @@ -76,7 +78,7 @@ //It's ok if it's not, it's just important if it is. mob_parent.client?.visual_delay = MOVEMENT_ADJUSTED_GLIDE_SIZE(visual_delay, SSnewtonian_movement.visual_delay) -/datum/drift_handler/proc/newtonian_impulse(inertia_angle, start_delay, additional_force, controlled_cap) +/datum/drift_handler/proc/newtonian_impulse(inertia_angle, start_delay, additional_force, controlled_cap, force_loop = TRUE) SIGNAL_HANDLER inertia_last_loc = parent.loc // We've been told to move in the middle of deletion process, tell parent to create a new handler instead @@ -96,6 +98,9 @@ drifting_loop.set_angle(delta_to_angle(force_x, force_y)) drifting_loop.set_delay(get_loop_delay(parent)) + // We have to forcefully fire it here to avoid stuttering in case of server lag + if (drifting_loop.timer <= world.time && force_loop) + SSnewtonian_movement.fire_moveloop(drifting_loop) return TRUE /datum/drift_handler/proc/drifting_start() @@ -202,28 +207,28 @@ if(world.time < block_inputs_until) return COMSIG_MOB_CLIENT_BLOCK_PRE_MOVE -/datum/drift_handler/proc/attempt_halt(mob/source, movement_dir, continuous_move, atom/backup) - SIGNAL_HANDLER - - if ((backup.density || !backup.CanPass(source, get_dir(backup, source))) && (get_dir(source, backup) == movement_dir || source.loc == backup.loc)) +/datum/drift_handler/proc/attempt_halt(movement_dir, continuous_move, atom/backup) + if ((backup.density || !backup.CanPass(parent, get_dir(backup, parent))) && (get_dir(parent, backup) == movement_dir || parent.loc == backup.loc)) if (drift_force >= INERTIA_FORCE_THROW_FLOOR) - source.throw_at(backup, 1, floor(1 + (drift_force - INERTIA_FORCE_THROW_FLOOR) / INERTIA_FORCE_PER_THROW_FORCE), spin = FALSE) - return + parent.throw_at(backup, 1, floor(1 + (drift_force - INERTIA_FORCE_THROW_FLOOR) / INERTIA_FORCE_PER_THROW_FORCE), spin = FALSE) + return FALSE if (drift_force < INERTIA_FORCE_SPACEMOVE_GRAB || isnull(drifting_loop)) - return + return FALSE - if (!isnull(source.client) && source.client.intended_direction) - if ((source.client.intended_direction & movement_dir) && !(get_dir(source, backup) & movement_dir)) - return + if (ismob(parent)) + var/mob/source_user = parent + if (!isnull(source_user.client) && source_user.client.intended_direction) + if ((source_user.client.intended_direction & movement_dir) && !(get_dir(source_user, backup) & movement_dir)) + return FALSE - if (drift_force <= INERTIA_FORCE_SPACEMOVE_REDUCTION / source.inertia_force_weight) - glide_to_halt(get_loop_delay(source)) - return COMPONENT_PREVENT_SPACEMOVE_HALT + if (drift_force <= INERTIA_FORCE_SPACEMOVE_REDUCTION / parent.inertia_force_weight) + glide_to_halt(get_loop_delay(parent)) + return TRUE - drift_force -= INERTIA_FORCE_SPACEMOVE_REDUCTION / source.inertia_force_weight - drifting_loop.set_delay(get_loop_delay(source)) - return COMPONENT_PREVENT_SPACEMOVE_HALT + drift_force -= INERTIA_FORCE_SPACEMOVE_REDUCTION / parent.inertia_force_weight + drifting_loop.set_delay(get_loop_delay(parent)) + return TRUE /datum/drift_handler/proc/get_loop_delay(atom/movable/movable) return (DEFAULT_INERTIA_SPEED / ((1 - INERTIA_SPEED_COEF) + drift_force * INERTIA_SPEED_COEF)) * movable.inertia_move_multiplier @@ -236,7 +241,7 @@ /// Lack of angle means that we are trying to halt movement if (isnull(target_angle)) // Going through newtonian_move ensures that all Process_Spacemove code runs properly, instead of directly adjusting forces - parent.newtonian_move(reverse_angle(drifting_loop.angle), drift_force = min(drift_force, stabilization_force)) + parent.newtonian_move(REVERSE_ANGLE(drifting_loop.angle), drift_force = min(drift_force, stabilization_force)) return // Force required to be applied in order to get to the desired movement vector, with projection of current movement onto desired vector to ensure that we only compensate for excess @@ -259,4 +264,4 @@ var/projected_force = max(0, cos(target_angle - drifting_loop.angle)) * drift_force if (projected_force > 0) - parent.newtonian_move(reverse_angle(target_angle), projected_force) + parent.newtonian_move(REVERSE_ANGLE(target_angle), projected_force) diff --git a/code/datums/elements/basic_eating.dm b/code/datums/elements/basic_eating.dm index 4f4f493e0ef3..4be983b32113 100644 --- a/code/datums/elements/basic_eating.dm +++ b/code/datums/elements/basic_eating.dm @@ -30,16 +30,27 @@ src.drinking = drinking src.food_types = food_types - //this lets players eat + RegisterSignal(target, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(try_feed)) RegisterSignal(target, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_unarm_attack)) - //this lets ai eat. yes, i'm serious - RegisterSignal(target, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_pre_attackingtarget)) /datum/element/basic_eating/Detach(datum/target) REMOVE_TRAIT(target, TRAIT_MOB_EATER, REF(src)) - UnregisterSignal(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)) + + UnregisterSignal(target, list( + COMSIG_LIVING_UNARMED_ATTACK, + COMSIG_ATOM_ITEM_INTERACTION, + )) return ..() +/datum/element/basic_eating/proc/try_feed(atom/source, mob/living/user, atom/possible_food) + SIGNAL_HANDLER + if(user.combat_mode || !is_type_in_list(possible_food, food_types)) + return NONE + var/mob/living/living_source = source + if(living_source.stat != CONSCIOUS) + return NONE + return try_eating(source, possible_food, user) ? ITEM_INTERACT_SUCCESS : NONE + /datum/element/basic_eating/proc/on_unarm_attack(mob/living/eater, atom/target, proximity, modifiers) SIGNAL_HANDLER if(!proximity) @@ -49,14 +60,10 @@ return COMPONENT_CANCEL_ATTACK_CHAIN return NONE -/datum/element/basic_eating/proc/on_pre_attackingtarget(mob/living/eater, atom/target) - SIGNAL_HANDLER - try_eating(eater, target) - -/datum/element/basic_eating/proc/try_eating(mob/living/eater, atom/target) +/datum/element/basic_eating/proc/try_eating(mob/living/eater, atom/target, mob/living/feeder) if(!is_type_in_list(target, food_types)) return FALSE - if(SEND_SIGNAL(eater, COMSIG_MOB_PRE_EAT, target) & COMSIG_MOB_CANCEL_EAT) + if(SEND_SIGNAL(eater, COMSIG_MOB_PRE_EAT, target, feeder) & COMSIG_MOB_CANCEL_EAT) return FALSE var/eat_verb if(drinking) @@ -75,21 +82,22 @@ if (damage_amount > 0 && damage_type) eater.apply_damage(damage_amount, damage_type) eater.visible_message(span_notice("[eater] [eat_verb]s [target], and seems to hurt itself."), span_notice("You [eat_verb] [target], hurting yourself in the process.")) - finish_eating(eater, target) + finish_eating(eater, target, feeder) return TRUE eater.visible_message(span_notice("[eater] [eat_verb]s [target]."), span_notice("You [eat_verb] [target].")) - finish_eating(eater, target) + finish_eating(eater, target, feeder) return TRUE -/datum/element/basic_eating/proc/finish_eating(mob/living/eater, atom/target) +/datum/element/basic_eating/proc/finish_eating(mob/living/eater, atom/target, mob/living/feeder) set waitfor = FALSE - SEND_SIGNAL(eater, COMSIG_MOB_ATE) if(drinking) playsound(eater.loc,'sound/items/drink.ogg', rand(10,50), TRUE) else playsound(eater.loc,'sound/items/eatfood.ogg', rand(10,50), TRUE) var/atom/final_target = target + if(SEND_SIGNAL(eater, COMSIG_MOB_ATE, final_target, feeder) & COMSIG_MOB_TERMINATE_EAT) + return if(isstack(target)) //if stack, only consume 1 var/obj/item/stack/food_stack = target final_target = food_stack.split_stack(eater, 1) diff --git a/code/datums/elements/can_shatter.dm b/code/datums/elements/can_shatter.dm index df19e4ef1234..5d8824121931 100644 --- a/code/datums/elements/can_shatter.dm +++ b/code/datums/elements/can_shatter.dm @@ -53,9 +53,11 @@ /// Handles the actual shattering part, throwing shards of whatever is defined on the component everywhere /datum/element/can_shatter/proc/shatter(atom/movable/source, atom/hit_atom) - var/generator/scatter_gen = generator(GEN_CIRCLE, 0, 48, NORMAL_RAND) - var/scatter_turf = get_turf(hit_atom) + var/turf/scatter_turf = get_turf(hit_atom) + if(!hit_atom.CanPass(source, get_dir(source, hit_atom))) //Object is too dense to fall apart on + scatter_turf = get_turf(source) + var/generator/scatter_gen = generator(GEN_CIRCLE, 0, 48, NORMAL_RAND) for(var/obj/item/scattered_item as anything in source.contents) scattered_item.forceMove(scatter_turf) var/list/scatter_vector = scatter_gen.Rand() diff --git a/code/datums/elements/decals/blood.dm b/code/datums/elements/decals/blood.dm index 16fd4241147d..3d16df0c6128 100644 --- a/code/datums/elements/decals/blood.dm +++ b/code/datums/elements/decals/blood.dm @@ -26,7 +26,7 @@ var/icon/icon_for_size = icon(icon, icon_state) var/scale_factor_x = icon_for_size.Width()/ICON_SIZE_X var/scale_factor_y = icon_for_size.Height()/ICON_SIZE_Y - var/mutable_appearance/blood_splatter = mutable_appearance('icons/effects/blood.dmi', "itemblood", appearance_flags = RESET_COLOR) //MA of the blood that we apply + var/mutable_appearance/blood_splatter = mutable_appearance('icons/effects/blood.dmi', "itemblood", appearance_flags = KEEP_APART|RESET_COLOR) //MA of the blood that we apply blood_splatter.transform = blood_splatter.transform.Scale(scale_factor_x, scale_factor_y) blood_splatter.blend_mode = BLEND_INSET_OVERLAY blood_splatter.color = _color diff --git a/code/datums/elements/dryable.dm b/code/datums/elements/dryable.dm index d66ea96d8c1f..583c74764eec 100644 --- a/code/datums/elements/dryable.dm +++ b/code/datums/elements/dryable.dm @@ -22,10 +22,13 @@ /datum/element/dryable/proc/finish_drying(atom/source, datum/weakref/drying_user) SIGNAL_HANDLER + var/static/list/dried_color + if (isnull(dried_color)) + dried_color = color_transition_filter(COLOR_DRIED_TAN) var/atom/dried_atom = source if(dry_result == dried_atom.type)//if the dried type is the same as our currrent state, don't bother creating a whole new item, just re-color it. var/atom/movable/resulting_atom = dried_atom - resulting_atom.add_atom_colour(COLOR_DRIED_TAN, FIXED_COLOUR_PRIORITY) + resulting_atom.add_atom_colour(dried_color, FIXED_COLOUR_PRIORITY) apply_dried_status(resulting_atom, drying_user) return else if(isstack(source)) //Check if its a sheet diff --git a/code/datums/elements/fish_safe_storage.dm b/code/datums/elements/fish_safe_storage.dm index ec5c59848646..ec543313bc25 100644 --- a/code/datums/elements/fish_safe_storage.dm +++ b/code/datums/elements/fish_safe_storage.dm @@ -15,6 +15,7 @@ RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_enter)) RegisterSignal(target, COMSIG_ATOM_EXITED, PROC_REF(on_exit)) RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(on_init_on)) + ADD_TRAIT(target, TRAIT_STOP_FISH_FLOPPING, REF(src)) for(var/obj/item/fish/fish in target) tracked_fish |= fish fish.enter_stasis() @@ -24,6 +25,7 @@ tracked_fish -= fish REMOVE_TRAIT(fish, TRAIT_FISH_STASIS, REF(src)) UnregisterSignal(source, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON)) + REMOVE_TRAIT(source, TRAIT_STOP_FISH_FLOPPING, REF(src)) return ..() /datum/element/fish_safe_storage/proc/on_enter(datum/source, obj/item/fish/arrived) diff --git a/code/datums/elements/food/fried_item.dm b/code/datums/elements/food/fried_item.dm index bc21e51f24cd..7f8613a537f7 100644 --- a/code/datums/elements/food/fried_item.dm +++ b/code/datums/elements/food/fried_item.dm @@ -2,18 +2,21 @@ /datum/element/fried_item /// List of colors to apply the element target. /// Each index corresponds to a different level. - var/static/list/fried_colors = list( - COLOR_LIGHT_BROWN, - COLOR_BROWNER_BROWN, - COLOR_DARKER_BROWN, - COLOR_BLACK, - ) + var/static/list/fried_colors /datum/element/fried_item/Attach(datum/target, fry_time) . = ..() if(!isatom(target)) return ELEMENT_INCOMPATIBLE + if (isnull(fried_colors)) + fried_colors = list( + color_transition_filter(COLOR_LIGHT_BROWN, SATURATION_OVERRIDE), + color_transition_filter(COLOR_BROWNER_BROWN, SATURATION_OVERRIDE), + color_transition_filter(COLOR_DARKER_BROWN, SATURATION_OVERRIDE), + color_transition_filter(COLOR_BLACK, SATURATION_OVERRIDE), + ) + var/atom/this_food = target switch(fry_time) diff --git a/code/datums/elements/kneecapping.dm b/code/datums/elements/kneecapping.dm index 977268e94a10..49b77acedd72 100644 --- a/code/datums/elements/kneecapping.dm +++ b/code/datums/elements/kneecapping.dm @@ -78,15 +78,16 @@ attacker.visible_message(span_warning("[attacker] carefully aims [attacker.p_their()] [weapon] for a swing at [target]'s kneecaps!"), span_danger("You carefully aim \the [weapon] for a swing at [target]'s kneecaps!")) log_combat(attacker, target, "started aiming a swing to break the kneecaps of", weapon) - if(do_after(attacker, 3 SECONDS, target, interaction_key = weapon)) - attacker.visible_message(span_warning("[attacker] swings [attacker.p_their()] [weapon] at [target]'s kneecaps!"), span_danger("You swing \the [weapon] at [target]'s kneecaps!")) - - var/min_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 30, wound_source = weapon) - var/max_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 50, wound_source = weapon) - - leg.receive_damage(brute = weapon.force, wound_bonus = rand(min_wound, max_wound + 10), damage_source = "kneecapping") - target.emote("scream") - log_combat(attacker, target, "broke the kneecaps of", weapon) - target.update_damage_overlays() - attacker.do_attack_animation(target, used_item = weapon) - playsound(source = get_turf(weapon), soundin = weapon.hitsound, vol = weapon.get_clamped_volume(), vary = TRUE) + if(!do_after(attacker, 3 SECONDS, target, interaction_key = weapon)) + return + + attacker.visible_message(span_warning("[attacker] swings [attacker.p_their()] [weapon] at [target]'s kneecaps!"), span_danger("You swing \the [weapon] at [target]'s kneecaps!")) + + var/min_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 30, wound_source = weapon) + var/max_wound = leg.get_wound_threshold_of_wound_type(WOUND_BLUNT, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 50, wound_source = weapon) + + target.apply_damage(weapon.force, weapon.damtype, leg, wound_bonus = rand(min_wound, max_wound + 10), attacking_item = weapon) + target.emote("scream") + log_combat(attacker, target, "broke the kneecaps of", weapon) + attacker.do_attack_animation(target, used_item = weapon) + playsound(source = weapon, soundin = weapon.hitsound, vol = weapon.get_clamped_volume(), vary = TRUE) diff --git a/code/datums/elements/leeching_walk.dm b/code/datums/elements/leeching_walk.dm index c9f547189e69..f5148b43a5a5 100644 --- a/code/datums/elements/leeching_walk.dm +++ b/code/datums/elements/leeching_walk.dm @@ -24,9 +24,8 @@ var/turf/mover_turf = get_turf(source) if(HAS_TRAIT(mover_turf, TRAIT_RUSTY)) ADD_TRAIT(source, TRAIT_BATON_RESISTANCE, type) - return - - REMOVE_TRAIT(source, TRAIT_BATON_RESISTANCE, type) + else + REMOVE_TRAIT(source, TRAIT_BATON_RESISTANCE, type) /** * Signal proc for [COMSIG_LIVING_LIFE]. @@ -43,17 +42,18 @@ // Heals all damage + Stamina var/need_mob_update = FALSE - need_mob_update += source.adjustBruteLoss(-3, updating_health = FALSE) - need_mob_update += source.adjustFireLoss(-3, updating_health = FALSE) - need_mob_update += source.adjustToxLoss(-3, updating_health = FALSE, forced = TRUE) // Slimes are people to - need_mob_update += source.adjustOxyLoss(-1.5, updating_health = FALSE) - need_mob_update += source.adjustStaminaLoss(-10, updating_stamina = FALSE) + var/delta_time = DELTA_WORLD_TIME(SSmobs) * 0.5 // SSmobs.wait is 2 secs, so this should be halved. + need_mob_update += source.adjustBruteLoss(-3 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustFireLoss(-3 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustToxLoss(-3 * delta_time, updating_health = FALSE, forced = TRUE) // Slimes are people too + need_mob_update += source.adjustOxyLoss(-1.5 * delta_time, updating_health = FALSE) + need_mob_update += source.adjustStaminaLoss(-10 * delta_time, updating_stamina = FALSE) if(need_mob_update) source.updatehealth() // Reduces duration of stuns/etc - source.AdjustAllImmobility(-0.5 SECONDS) + source.AdjustAllImmobility((-0.5 SECONDS) * delta_time) // Heals blood loss if(source.blood_volume < BLOOD_VOLUME_NORMAL) - source.blood_volume += 2.5 * seconds_per_tick + source.blood_volume += 2.5 * delta_time // Slowly regulates your body temp - source.adjust_bodytemperature((source.get_body_temp_normal() - source.bodytemperature)/5) + source.adjust_bodytemperature((source.get_body_temp_normal() - source.bodytemperature) / 5) diff --git a/code/datums/elements/nav_computer_icon.dm b/code/datums/elements/nav_computer_icon.dm new file mode 100644 index 000000000000..4e9b6a3a1889 --- /dev/null +++ b/code/datums/elements/nav_computer_icon.dm @@ -0,0 +1,44 @@ +/** + * element for atoms that have helper icons overlayed on their position in the shuttle navigation computer, such as airlocks + */ +/datum/element/nav_computer_icon + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + var/use_icon + var/use_icon_state + var/only_show_on_shuttle_edge + +/datum/element/nav_computer_icon/Attach(datum/target, use_icon, use_icon_state, only_show_on_shuttle_edge) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + src.use_icon = use_icon + src.use_icon_state = use_icon_state + src.only_show_on_shuttle_edge = only_show_on_shuttle_edge + + RegisterSignal(target, COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED, PROC_REF(provide_image)) + +/datum/element/nav_computer_icon/proc/provide_image(datum/source, list/images_out) + SIGNAL_HANDLER + var/obj/source_obj = source + var/turf/source_turf = get_turf(source_obj) + if(!source_turf) + return + if(only_show_on_shuttle_edge) + var/isOnEdge = FALSE + for(var/direction in GLOB.cardinals) + var/turf/turf = get_step(source_obj, direction) + if(!istype(turf?.loc, /area/shuttle)) + isOnEdge = TRUE + break + if(!isOnEdge) + return + + var/image/the_image = image(use_icon, source_turf, use_icon_state) + the_image.dir = source_obj.dir + images_out += the_image + +/datum/element/nav_computer_icon/Detach(datum/source) + . = ..() + UnregisterSignal(source, COMSIG_SHUTTLE_NAV_COMPUTER_IMAGE_REQUESTED) diff --git a/code/datums/elements/pet_cult.dm b/code/datums/elements/pet_cult.dm index 36941e7b7429..f26e6e343e66 100644 --- a/code/datums/elements/pet_cult.dm +++ b/code/datums/elements/pet_cult.dm @@ -90,7 +90,8 @@ source.ai_controller.set_blackboard_key(BB_CULT_TEAM, team) var/static/list/new_pet_commands = list( - /datum/pet_command/point_targeting/attack, + /datum/pet_command/move, + /datum/pet_command/attack, /datum/pet_command/follow, /datum/pet_command/free, /datum/pet_command/idle, diff --git a/code/datums/elements/slapcrafting.dm b/code/datums/elements/slapcrafting.dm index 4b58bddd2a0f..046a8668a297 100644 --- a/code/datums/elements/slapcrafting.dm +++ b/code/datums/elements/slapcrafting.dm @@ -134,7 +134,7 @@ for(var/datum/crafting_recipe/recipe as anything in slapcraft_recipes) var/atom/result = initial(recipe.result) - examine_list += "See Recipe For [initial(result.name)]" + examine_list += "See Recipe For [initial(result.name)]" /datum/element/slapcrafting/proc/topic_handler(atom/source, user, href_list) SIGNAL_HANDLER @@ -180,7 +180,7 @@ // If we did find ingredients then add them onto the list. if(length(string_ingredient_list)) to_chat(user, span_boldnotice("Extra Ingredients:")) - to_chat(user, examine_block(span_notice(string_ingredient_list))) + to_chat(user, boxed_message(span_notice(string_ingredient_list))) var/list/tool_list = "" @@ -194,7 +194,7 @@ if(length(tool_list)) to_chat(user, span_boldnotice("Required Tools:")) - to_chat(user, examine_block(span_notice(tool_list))) + to_chat(user, boxed_message(span_notice(tool_list))) qdel(cur_recipe) diff --git a/code/datums/elements/squish.dm b/code/datums/elements/squish.dm index 2e8e273eb35f..872f837d96e1 100644 --- a/code/datums/elements/squish.dm +++ b/code/datums/elements/squish.dm @@ -6,37 +6,42 @@ * * It's an element that squishes things. After the duration passes, it reverses the transformation it squished with, taking into account if they are a different orientation than they started (read: rotationally-fluid) * - * Normal squishes apply vertically, as if the target is being squished from above, but you can set reverse to TRUE if you want to squish them from the sides, like if they pancake into a wall from the East or West + * Normal squishes apply vertically, as if the target is being squished from above, but you can set horizontal_squish to TRUE if you want to squish them from the sides, like if they pancake into a wall from the East or West */ /datum/element/squish element_flags = ELEMENT_DETACH_ON_HOST_DESTROY -/datum/element/squish/Attach(datum/target, duration=20 SECONDS, reverse=FALSE) +/datum/element/squish/Attach(atom/target, duration=20 SECONDS, horizontal_squish=FALSE) . = ..() - if(!iscarbon(target)) + + if(!isatom(target)) return ELEMENT_INCOMPATIBLE - var/mob/living/carbon/C = target - var/was_lying = C.body_position == LYING_DOWN - addtimer(CALLBACK(src, PROC_REF(Detach), C, was_lying, reverse), duration) + var/was_lying = FALSE + if(iscarbon(target)) + var/mob/living/carbon/carboniucus = target + was_lying = carboniucus.body_position == LYING_DOWN + addtimer(CALLBACK(src, PROC_REF(Detach), target, was_lying, horizontal_squish), duration) - if(reverse) - C.transform = C.transform.Scale(SHORT, TALL) + if(horizontal_squish) + target.transform = target.transform.Scale(SHORT, TALL) else - C.transform = C.transform.Scale(TALL, SHORT) + target.transform = target.transform.Scale(TALL, SHORT) -/datum/element/squish/Detach(mob/living/carbon/C, was_lying, reverse) +/datum/element/squish/Detach(atom/target, was_lying, horizontal_squish) . = ..() - if(istype(C)) - var/is_lying = C.body_position == LYING_DOWN + var/is_lying = FALSE + if(iscarbon(target)) + var/mob/living/carbon/carboniucus = target + is_lying = carboniucus.body_position == LYING_DOWN - if(reverse) - is_lying = !is_lying + if(horizontal_squish) + is_lying = !is_lying - if(was_lying == is_lying) - C.transform = C.transform.Scale(SHORT, TALL) - else - C.transform = C.transform.Scale(TALL, SHORT) + if(was_lying == is_lying) + target.transform = target.transform.Scale(SHORT, TALL) + else + target.transform = target.transform.Scale(TALL, SHORT) #undef SHORT #undef TALL diff --git a/code/datums/elements/update_icon_updates_onmob.dm b/code/datums/elements/update_icon_updates_onmob.dm index cfbf16317fa5..69346949c596 100644 --- a/code/datums/elements/update_icon_updates_onmob.dm +++ b/code/datums/elements/update_icon_updates_onmob.dm @@ -25,5 +25,3 @@ M.update_held_items() else M.update_clothing((target.slot_flags|update_flags)) - if(update_body) - M.update_body() diff --git a/code/datums/elements/weapon_description.dm b/code/datums/elements/weapon_description.dm index eda7ca59b49e..022318abfcf0 100644 --- a/code/datums/elements/weapon_description.dm +++ b/code/datums/elements/weapon_description.dm @@ -39,7 +39,7 @@ SIGNAL_HANDLER if(item.force >= 5 || item.throwforce >= 5 || item.override_notes || item.offensive_notes || attached_proc) /// Only show this tag for items that could feasibly be weapons, shields, or those that have special notes - examine_texts += span_notice("See combat information.") + examine_texts += span_notice("See combat information.") /** * @@ -57,7 +57,7 @@ SIGNAL_HANDLER if(href_list["examine"]) - to_chat(user, span_notice(examine_block("[build_label_text(source)]"))) + to_chat(user, span_notice(boxed_message("[build_label_text(source)]"))) /** * @@ -73,9 +73,9 @@ // Doesn't show the base notes for items that have the override notes variable set to true if(!source.override_notes) - if (source.sharpness & SHARP_EDGED) + if (source.get_sharpness() & SHARP_EDGED) readout += "It's sharp and could cause bleeding wounds." - if (source.sharpness & SHARP_POINTY) + if (source.get_sharpness() & SHARP_POINTY) readout += "It's pointy and could cause piercing wounds." // Make sure not to divide by 0 on accident if(source.force > 0) diff --git a/code/datums/embed_data.dm b/code/datums/embed_data.dm index a82d305c8e6e..865b285d09ba 100644 --- a/code/datums/embed_data.dm +++ b/code/datums/embed_data.dm @@ -35,6 +35,8 @@ GLOBAL_LIST_INIT(embed_by_type, generate_embed_type_cache()) var/jostle_chance = 5 /// Coefficient of multiplication for the damage the item does while var/jostle_pain_mult = 1 + /// Call this proc on jostling, if it exists! + var/datum/callback/jostle_callback /// This percentage of all pain will be dealt as stam damage rather than brute (0-1) var/pain_stam_pct = 0 @@ -51,5 +53,6 @@ GLOBAL_LIST_INIT(embed_by_type, generate_embed_type_cache()) data.ignore_throwspeed_threshold = !isnull(ignore_throwspeed_threshold) ? ignore_throwspeed_threshold : src.ignore_throwspeed_threshold data.jostle_chance = !isnull(jostle_chance) ? jostle_chance : src.jostle_chance data.jostle_pain_mult = !isnull(jostle_pain_mult) ? jostle_pain_mult : src.jostle_pain_mult + data.jostle_callback = !isnull(jostle_callback) ? jostle_callback : src.jostle_callback data.pain_stam_pct = !isnull(pain_stam_pct) ? pain_stam_pct : src.pain_stam_pct return data diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index ceaa53e04552..1e8870ddf3e4 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -35,10 +35,10 @@ ///calls from a head of staff autoconnect, if the receiving pad is not secure. var/head_call = FALSE -//creates a holocall made by `caller` from `calling_pad` to `callees` -/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE) +//creates a holocall made by `call_source` from `calling_pad` to `callees` +/datum/holocall/New(mob/living/call_source, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE) call_start_time = world.time - user = caller + user = call_source calling_pad.outgoing_call = src calling_holopad = calling_pad head_call = elevated_access diff --git a/code/datums/keybinding/_keybindings.dm b/code/datums/keybinding/_keybindings.dm index dfcf492c1809..a989d0d22a88 100644 --- a/code/datums/keybinding/_keybindings.dm +++ b/code/datums/keybinding/_keybindings.dm @@ -21,6 +21,8 @@ return SEND_SIGNAL(user.mob, keybind_signal) & COMSIG_KB_ACTIVATED /datum/keybinding/proc/up(client/user) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(user.mob, DEACTIVATE_KEYBIND(keybind_signal)) return FALSE /datum/keybinding/proc/can_use(client/user) diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index eb666f570284..7605e3ad2de2 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -16,10 +16,20 @@ . = ..() if(.) return - var/mob/living/L = user.mob - L.resist() + var/mob/living/owner = user.mob + owner.resist() + if (owner.hud_used?.resist_icon) + owner.hud_used.resist_icon.icon_state = "[owner.hud_used.resist_icon.base_icon_state]_on" return TRUE +/datum/keybinding/living/resist/up(client/user) + . = ..() + if(.) + return + var/mob/living/owner = user.mob + if (owner.hud_used?.resist_icon) + owner.hud_used.resist_icon.icon_state = owner.hud_used.resist_icon.base_icon_state + /datum/keybinding/living/look_up // hotkey_keys = list("L") // ORIGINAL hotkey_keys = list("P") //NOVA EDIT CHANGE - CUSTOMIZATION @@ -37,6 +47,7 @@ return TRUE /datum/keybinding/living/look_up/up(client/user) + . = ..() var/mob/living/L = user.mob L.end_look_up() return TRUE @@ -58,6 +69,7 @@ return TRUE /datum/keybinding/living/look_down/up(client/user) + . = ..() var/mob/living/L = user.mob L.end_look_down() return TRUE @@ -136,6 +148,7 @@ return TRUE /datum/keybinding/living/toggle_move_intent/up(client/user) + . = ..() var/mob/living/M = user.mob M.toggle_move_intent() return TRUE diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 4963e87266cb..a1bd06742b55 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -191,3 +191,10 @@ if(.) return user.movement_locked = FALSE + +/datum/keybinding/living/view_pet_data + hotkey_keys = list("Shift") + name = "view_pet_commands" + full_name = "View Pet Commands" + description = "Hold down to see all the commands you can give your pets!" + keybind_signal = COMSIG_KB_LIVING_VIEW_PET_COMMANDS diff --git a/code/datums/looping_sounds/_looping_sound.dm b/code/datums/looping_sounds/_looping_sound.dm index d0ad6544ca6e..1dc2e69f2ca8 100644 --- a/code/datums/looping_sounds/_looping_sound.dm +++ b/code/datums/looping_sounds/_looping_sound.dm @@ -174,7 +174,7 @@ if(!each_once) . = play_from while(!isfile(.) && !isnull(.)) - . = pick_weight(.) + . = pick_weight_recursive(.) return . if(in_order) @@ -192,7 +192,7 @@ // Tree is a list of lists containign files // If an entry in the tree goes to 0 length, we cut it from the list tree += list(.) - . = pick_weight(.) + . = pick_weight_recursive(.) if(!isfile(.)) return diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index c4648a929b30..92f78074c987 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -1,13 +1,17 @@ /datum/looping_sound/showering start_sound = 'sound/machines/shower/shower_start.ogg' start_length = 2 - mid_sounds = list('sound/machines/shower/shower_mid1.ogg' = 1, 'sound/machines/shower/shower_mid2.ogg' = 1, 'sound/machines/shower/shower_mid3.ogg' = 1) + mid_sounds = list( + 'sound/machines/shower/shower_mid1.ogg', + 'sound/machines/shower/shower_mid2.ogg', + 'sound/machines/shower/shower_mid3.ogg', + ) mid_length = 10 end_sound = 'sound/machines/shower/shower_end.ogg' volume = 20 /datum/looping_sound/supermatter - mid_sounds = list('sound/machines/sm/loops/calm.ogg' = 1) + mid_sounds = list('sound/machines/sm/loops/calm.ogg') mid_length = 60 volume = 40 extra_range = 25 @@ -16,14 +20,14 @@ vary = TRUE /datum/looping_sound/destabilized_crystal - mid_sounds = list('sound/machines/sm/loops/delamming.ogg' = 1) + mid_sounds = list('sound/machines/sm/loops/delamming.ogg') mid_length = 60 volume = 55 extra_range = 15 vary = TRUE /datum/looping_sound/hypertorus - mid_sounds = list('sound/machines/hypertorus/loops/hypertorus_nominal.ogg' = 1) + mid_sounds = list('sound/machines/hypertorus/loops/hypertorus_nominal.ogg') mid_length = 60 volume = 55 extra_range = 15 @@ -32,35 +36,41 @@ /datum/looping_sound/generator start_sound = 'sound/machines/generator/generator_start.ogg' start_length = 4 - mid_sounds = list('sound/machines/generator/generator_mid1.ogg' = 1, 'sound/machines/generator/generator_mid2.ogg' = 1, 'sound/machines/generator/generator_mid3.ogg' = 1) + mid_sounds = list( + 'sound/machines/generator/generator_mid1.ogg', + 'sound/machines/generator/generator_mid2.ogg', + 'sound/machines/generator/generator_mid3.ogg', + ) mid_length = 4 end_sound = 'sound/machines/generator/generator_end.ogg' volume = 40 - /datum/looping_sound/deep_fryer start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions start_length = 10 - mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) + mid_sounds = list( + 'sound/machines/fryer/deep_fryer_1.ogg', + 'sound/machines/fryer/deep_fryer_2.ogg', + ) mid_length = 2 end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' volume = 15 /datum/looping_sound/clock - mid_sounds = list('sound/ambience/misc/ticking_clock.ogg' = 1) + mid_sounds = list('sound/ambience/misc/ticking_clock.ogg') mid_length = 40 volume = 50 ignore_walls = FALSE /datum/looping_sound/grill - mid_sounds = list('sound/machines/grill/grillsizzle.ogg' = 1) + mid_sounds = list('sound/machines/grill/grillsizzle.ogg') mid_length = 18 volume = 50 /datum/looping_sound/oven start_sound = 'sound/machines/oven/oven_loop_start.ogg' //my immersions start_length = 12 - mid_sounds = list('sound/machines/oven/oven_loop_mid.ogg' = 1) + mid_sounds = list('sound/machines/oven/oven_loop_mid.ogg') mid_length = 13 end_sound = 'sound/machines/oven/oven_loop_end.ogg' volume = 100 @@ -68,19 +78,25 @@ /datum/looping_sound/deep_fryer mid_length = 2 - mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) + mid_sounds = list( + 'sound/machines/fryer/deep_fryer_1.ogg', + 'sound/machines/fryer/deep_fryer_2.ogg', + ) volume = 30 /datum/looping_sound/microwave start_sound = 'sound/machines/microwave/microwave-start.ogg' start_length = 10 - mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg' = 10, 'sound/machines/microwave/microwave-mid2.ogg' = 1) + mid_sounds = list( + 'sound/machines/microwave/microwave-mid1.ogg' = 10, + 'sound/machines/microwave/microwave-mid2.ogg' = 1, + ) mid_length = 10 end_sound = 'sound/machines/microwave/microwave-end.ogg' volume = 90 /datum/looping_sound/lathe_print - mid_sounds = list('sound/machines/lathe/lathe_print.ogg' = 1) + mid_sounds = list('sound/machines/lathe/lathe_print.ogg') mid_length = 20 volume = 50 vary = TRUE @@ -90,19 +106,19 @@ /datum/looping_sound/jackpot mid_length = 11 - mid_sounds = list('sound/machines/roulette/roulettejackpot.ogg' = 1) + mid_sounds = list('sound/machines/roulette/roulettejackpot.ogg') volume = 85 vary = TRUE /datum/looping_sound/server mid_sounds = list( - 'sound/machines/tcomms/tcomms_mid1.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid2.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid3.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid4.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid5.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid6.ogg' = 1, - 'sound/machines/tcomms/tcomms_mid7.ogg' = 1, + 'sound/machines/tcomms/tcomms_mid1.ogg', + 'sound/machines/tcomms/tcomms_mid2.ogg', + 'sound/machines/tcomms/tcomms_mid3.ogg', + 'sound/machines/tcomms/tcomms_mid4.ogg', + 'sound/machines/tcomms/tcomms_mid5.ogg', + 'sound/machines/tcomms/tcomms_mid6.ogg', + 'sound/machines/tcomms/tcomms_mid7.ogg', ) mid_length = 1.8 SECONDS extra_range = -8 @@ -116,7 +132,10 @@ start_sound = 'sound/machines/computer/computer_start.ogg' start_length = 7.2 SECONDS start_volume = 10 - mid_sounds = list('sound/machines/computer/computer_mid1.ogg' = 1, 'sound/machines/computer/computer_mid2.ogg' = 1) + mid_sounds = list( + 'sound/machines/computer/computer_mid1.ogg', + 'sound/machines/computer/computer_mid2.ogg', + ) mid_length = 1.8 SECONDS end_sound = 'sound/machines/computer/computer_end.ogg' end_volume = 10 @@ -141,7 +160,12 @@ falloff_exponent = 20 /datum/looping_sound/firealarm - mid_sounds = list('sound/machines/fire_alarm/FireAlarm1.ogg' = 1,'sound/machines/fire_alarm/FireAlarm2.ogg' = 1,'sound/machines/fire_alarm/FireAlarm3.ogg' = 1,'sound/machines/fire_alarm/FireAlarm4.ogg' = 1) + mid_sounds = list( + 'sound/machines/fire_alarm/FireAlarm1.ogg', + 'sound/machines/fire_alarm/FireAlarm2.ogg', + 'sound/machines/fire_alarm/FireAlarm3.ogg', + 'sound/machines/fire_alarm/FireAlarm4.ogg', + ) mid_length = 2.4 SECONDS volume = 30 @@ -151,30 +175,30 @@ falloff_exponent = 5 /datum/looping_sound/boiling - mid_sounds = list('sound/effects/bubbles/bubbles2.ogg' = 1) + mid_sounds = list('sound/effects/bubbles/bubbles2.ogg') mid_length = 7 SECONDS volume = 25 /datum/looping_sound/typing mid_sounds = list( - 'sound/machines/terminal/terminal_button01.ogg' = 1, - 'sound/machines/terminal/terminal_button02.ogg' = 1, - 'sound/machines/terminal/terminal_button03.ogg' = 1, - 'sound/machines/terminal/terminal_button04.ogg' = 1, - 'sound/machines/terminal/terminal_button05.ogg' = 1, - 'sound/machines/terminal/terminal_button06.ogg' = 1, - 'sound/machines/terminal/terminal_button07.ogg' = 1, - 'sound/machines/terminal/terminal_button08.ogg' = 1, + 'sound/machines/terminal/terminal_button01.ogg', + 'sound/machines/terminal/terminal_button02.ogg', + 'sound/machines/terminal/terminal_button03.ogg', + 'sound/machines/terminal/terminal_button04.ogg', + 'sound/machines/terminal/terminal_button05.ogg', + 'sound/machines/terminal/terminal_button06.ogg', + 'sound/machines/terminal/terminal_button07.ogg', + 'sound/machines/terminal/terminal_button08.ogg', ) mid_length = 0.3 SECONDS /datum/looping_sound/soup mid_sounds = list( - 'sound/effects/soup_boil/soup_boil1.ogg' = 1, - 'sound/effects/soup_boil/soup_boil2.ogg' = 1, - 'sound/effects/soup_boil/soup_boil3.ogg' = 1, - 'sound/effects/soup_boil/soup_boil4.ogg' = 1, - 'sound/effects/soup_boil/soup_boil5.ogg' = 1, + 'sound/effects/soup_boil/soup_boil1.ogg', + 'sound/effects/soup_boil/soup_boil2.ogg', + 'sound/effects/soup_boil/soup_boil3.ogg', + 'sound/effects/soup_boil/soup_boil4.ogg', + 'sound/effects/soup_boil/soup_boil5.ogg', ) mid_length = 3 SECONDS volume = 80 @@ -182,3 +206,19 @@ end_volume = 60 extra_range = MEDIUM_RANGE_SOUND_EXTRARANGE falloff_exponent = 4 + +/datum/looping_sound/cryo_cell + mid_sounds = list( + 'sound/machines/cryo/cryo_1.ogg', + 'sound/machines/cryo/cryo_2.ogg', + 'sound/machines/cryo/cryo_3.ogg', + 'sound/machines/cryo/cryo_4.ogg', + 'sound/machines/cryo/cryo_5.ogg', + 'sound/machines/cryo/cryo_6.ogg', + 'sound/machines/cryo/cryo_7.ogg', + 'sound/machines/cryo/cryo_8.ogg', + 'sound/machines/cryo/cryo_9.ogg', + 'sound/machines/cryo/cryo_10.ogg', + ) + mid_length = 5 SECONDS + volume = 50 diff --git a/code/datums/map_config.dm b/code/datums/map_config.dm index fe3dd85237a0..160dcd1ca751 100644 --- a/code/datums/map_config.dm +++ b/code/datums/map_config.dm @@ -243,7 +243,7 @@ #endif defaulted = FALSE - return TRUE + return json #undef CHECK_EXISTS /datum/map_config/proc/GetFullMapPaths() diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm index c588572db60a..d012df9008f8 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -130,7 +130,7 @@ new_turf.turf_flags |= NO_RUINS var/message = "[name] terrain generation finished in [(REALTIMEOFDAY - start_time)/10]s!" - to_chat(world, span_boldannounce("[message]")) + to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) @@ -207,7 +207,7 @@ generated_turfs_per_biome[biome] = generated_turfs var/message = "[name] terrain generation finished in [(REALTIMEOFDAY - start_time)/10]s!" - to_chat(world, span_boldannounce("[message]")) + to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) @@ -300,7 +300,7 @@ CHECK_TICK var/message = "[name] terrain population finished in [(REALTIMEOFDAY - start_time)/10]s!" - add_startup_message(message) //NOVA EDIT CHANGE - ORIGINAL: to_chat(world, span_boldannounce("[message]")) + add_startup_message(message) //NOVA EDIT CHANGE - ORIGINAL: to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) @@ -323,7 +323,7 @@ // No sense in doing anything here if nothing is allowed anyway. if(!flora_allowed && !features_allowed && !fauna_allowed) var/message = "[name] terrain population finished in [(REALTIMEOFDAY - start_time)/10]s!" - to_chat(world, span_boldannounce("[message]")) + to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) return @@ -334,7 +334,7 @@ CHECK_TICK var/message = "[name] terrain population finished in [(REALTIMEOFDAY - start_time)/10]s!" - to_chat(world, span_boldannounce("[message]")) + to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index d2142b02a8bc..b5ff49037e6f 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -254,6 +254,7 @@ icon = 'icons/obj/weapons/staff.dmi' icon_state = "bostaff0" base_icon_state = "bostaff" + icon_angle = -135 lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' block_chance = 50 diff --git a/code/datums/mind/skills.dm b/code/datums/mind/skills.dm index 474291d5ae0d..80a78c3d950f 100644 --- a/code/datums/mind/skills.dm +++ b/code/datums/mind/skills.dm @@ -75,4 +75,4 @@ var/datum/skill/the_skill = i msg += "[initial(the_skill.name)] - [get_skill_level_name(the_skill)]\n" msg += "" - to_chat(user, examine_block(msg)) + to_chat(user, boxed_message(msg)) diff --git a/code/datums/mood.dm b/code/datums/mood.dm index dff22d453960..fa7012d2f736 100644 --- a/code/datums/mood.dm +++ b/code/datums/mood.dm @@ -445,7 +445,7 @@ msg += span_boldnicegreen(event.description + "\n") else msg += "[span_grey("I don't have much of a reaction to anything right now.")]\n" - to_chat(user, examine_block(msg)) + to_chat(user, boxed_message(msg)) /// Updates the mob's moodies, if the area provides a mood bonus /datum/mood/proc/check_area_mood(datum/source, area/new_area) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 3ec4264b125c..32bc26771f35 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -122,9 +122,14 @@ /datum/mood_event/heretics description = "THE HIGHER I RISE, THE MORE I SEE." - mood_change = 10 //maybe being a cultist isnt that bad after all + mood_change = 10 //maybe being a heretic isnt that bad after all hidden = TRUE +/datum/mood_event/rift_fishing + description = "THE MORE I FISH, THE HIGHER I RISE." + mood_change = 7 + timeout = 5 MINUTES + /datum/mood_event/family_heirloom description = "My family heirloom is safe with me." mood_change = 1 diff --git a/code/datums/mutations/tongue_spike.dm b/code/datums/mutations/tongue_spike.dm index c6a48a32a144..663dcd2541ac 100644 --- a/code/datums/mutations/tongue_spike.dm +++ b/code/datums/mutations/tongue_spike.dm @@ -45,6 +45,7 @@ desc = "Hardened biomass, shaped into a spike. Very pointy!" icon = 'icons/obj/weapons/thrown.dmi' icon_state = "tonguespike" + icon_angle = 45 force = 2 throwforce = 25 throw_speed = 4 diff --git a/code/datums/profiling.dm b/code/datums/profiling.dm index 56dd844fb1f6..b717346e3fa8 100644 --- a/code/datums/profiling.dm +++ b/code/datums/profiling.dm @@ -15,4 +15,6 @@ GLOBAL_REAL_VAR(PROFILE_TIME) var/list/data = PROFILE_STORE[entry] lines += "[entry] => [num2text(data[PROFILE_ITEM_TIME], 10)]ms ([data[PROFILE_ITEM_COUNT]]) (avg:[num2text(data[PROFILE_ITEM_TIME]/(data[PROFILE_ITEM_COUNT] || 1), 99)])" - user << browse("
  1. [lines.Join("
  2. ")]
", "window=[url_encode(GUID())]") + var/datum/browser/browser = new(user, "[url_encode(GUID())]", null, 500, 500) + browser.set_content("
  1. [lines.Join("
  2. ")]
") + browser.open() diff --git a/code/datums/quirks/negative_quirks/addict.dm b/code/datums/quirks/negative_quirks/addict.dm index 3916184e3dbe..4292556e1f5b 100644 --- a/code/datums/quirks/negative_quirks/addict.dm +++ b/code/datums/quirks/negative_quirks/addict.dm @@ -4,6 +4,7 @@ gain_text = span_danger("You suddenly feel the craving for... something? You're not sure what it is.") medical_record_text = "Patient has a history with SOMETHING but he refuses to tell us what it is." abstract_parent_type = /datum/quirk/item_quirk/addict + quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES var/datum/reagent/reagent_type //!If this is defined, reagent_id will be unused and the defined reagent type will be instead. var/datum/reagent/reagent_instance //! actual instanced version of the reagent var/where_drug //! Where the drug spawned @@ -86,7 +87,6 @@ gain_text = span_danger("You suddenly feel the craving for drugs.") medical_record_text = "Patient has a history of hard drugs." hardcore_value = 4 - quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES mail_goodies = list(/obj/effect/spawner/random/contraband/narcotics) drug_flavour_text = "Better hope you don't run out..." diff --git a/code/datums/quirks/negative_quirks/blood_deficiency.dm b/code/datums/quirks/negative_quirks/blood_deficiency.dm index 238126f4d79f..a5ac11714bd5 100644 --- a/code/datums/quirks/negative_quirks/blood_deficiency.dm +++ b/code/datums/quirks/negative_quirks/blood_deficiency.dm @@ -33,7 +33,7 @@ human_holder.blood_volume = max(min_blood, human_holder.blood_volume - human_holder.dna.species.blood_deficiency_drain_rate * seconds_per_tick) -/datum/quirk/blooddeficiency/proc/update_mail(datum/source, datum/species/new_species, datum/species/old_species) +/datum/quirk/blooddeficiency/proc/update_mail(datum/source, datum/species/new_species, datum/species/old_species, pref_load, regenerate_icons) SIGNAL_HANDLER mail_goodies.Cut() diff --git a/code/datums/quirks/negative_quirks/chronic_illness.dm b/code/datums/quirks/negative_quirks/chronic_illness.dm index f0809b55d2b0..04a676965dbe 100644 --- a/code/datums/quirks/negative_quirks/chronic_illness.dm +++ b/code/datums/quirks/negative_quirks/chronic_illness.dm @@ -1,11 +1,11 @@ /datum/quirk/item_quirk/chronic_illness - name = "Chronic Illness" - desc = "You have a chronic illness that requires constant medication to keep under control." + name = "Eradicative Chronic Illness" + desc = "You have an anomalous chronic illness that requires constant medication to keep under control, or else causes timestream correction." icon = FA_ICON_DISEASE value = -12 - gain_text = span_danger("You feel a bit off today.") - lose_text = span_notice("You feel a bit better today.") - medical_record_text = "Patient has a chronic illness that requires constant medication to keep under control." + gain_text = span_danger("You feel like you are fading away...") + lose_text = span_notice("You suddenly feel more substantial.") + medical_record_text = "Patient has an anomalous chronic illness that requires constant medication to keep under control." hardcore_value = 12 mail_goodies = list(/obj/item/storage/pill_bottle/sansufentanyl) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 4e7c25377e3d..3d392c501114 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -306,16 +306,9 @@ newRod.activated() if(!itemUser.has_hand_for_held_index(hand)) //If user does not have the corresponding hand anymore, give them one and return the rod to their hand - if(((hand % 2) == 0)) - var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_R_ARM, FALSE, FALSE) - if(L.try_attach_limb(itemUser)) - L.update_limb(is_creating = TRUE) - itemUser.update_body_parts() - itemUser.put_in_hand(newRod, hand, forced = TRUE) - else - qdel(L) - consume_owner() //we can't regrow, abort abort - return + var/zone = IS_LEFT_INDEX(hand) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM + if(itemUser.regenerate_limb(zone, FALSE)) + itemUser.put_in_hand(newRod, hand, forced = TRUE) else var/obj/item/bodypart/L = itemUser.newBodyPart(BODY_ZONE_L_ARM, FALSE, FALSE) if(L.try_attach_limb(itemUser)) diff --git a/code/datums/status_effects/debuffs/choke.dm b/code/datums/status_effects/debuffs/choke.dm index 9113c8a1a023..e8af4b1b94dc 100644 --- a/code/datums/status_effects/debuffs/choke.dm +++ b/code/datums/status_effects/debuffs/choke.dm @@ -280,10 +280,8 @@ /datum/status_effect/choke/proc/deal_damage(seconds_between_ticks) owner.losebreath += 1 * seconds_between_ticks // 1 breath loss a second. This will deal additional breath damage, and prevent breathing if(flaming) - var/obj/item/bodypart/head = owner.get_bodypart(BODY_ZONE_HEAD) - if(head) - head.receive_damage(0, 2 * seconds_between_ticks, damage_source = "choking") - owner.adjustStaminaLoss(2 * seconds_between_ticks) + owner.apply_damage(2 * seconds_between_ticks, BURN, BODY_ZONE_HEAD, attacking_item = "choking") + owner.apply_damage(2 * seconds_between_ticks, STAMINA) /datum/status_effect/choke/proc/do_vfx(client/vfx_on) var/old_x = delta_x diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 4e69513797c7..e58aff569b34 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -19,12 +19,11 @@ /datum/status_effect/incapacitating/on_creation(mob/living/new_owner, set_duration) if(isnum(set_duration)) duration = set_duration - return ..() - -/datum/status_effect/incapacitating/on_apply() + . = ..() + if(!.) + return if(needs_update_stat || issilicon(owner)) owner.update_stat() - return TRUE /datum/status_effect/incapacitating/on_remove() if(needs_update_stat || issilicon(owner)) //silicons need stat updates in addition to normal canmove updates @@ -351,19 +350,33 @@ duration = 300 //if you leave for 30 seconds you lose the mark, deal with it status_type = STATUS_EFFECT_REFRESH alert_type = null - var/mutable_appearance/marked_underlay + /// The bubble that is added to the mob as a visual + var/obj/effect/abstract/crusher_mark/marked_underlay + /// If the projectile that applies this was boosted, the mark will also be boosted var/boosted = FALSE + /// How long before the mark is ready to be detonated. Used for both the visual overlay and to determine when it's ready + var/ready_delay = 0.8 SECONDS + /// Tracks world.time when the mark was applied + var/mark_applied /datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, was_boosted) . = ..() boosted = was_boosted + mark_applied = world.time /datum/status_effect/crusher_mark/on_apply() if(owner.mob_size >= MOB_SIZE_LARGE && !HAS_TRAIT(owner, TRAIT_OVERSIZED)) // NOVA EDIT CHANGE - Original: if(owner.mob_size >= MOB_SIZE_LARGE) - marked_underlay = mutable_appearance('icons/effects/effects.dmi', boosted ? "shield" : "shield2") + marked_underlay = new() marked_underlay.pixel_x = -owner.pixel_x marked_underlay.pixel_y = -owner.pixel_y - owner.underlays += marked_underlay + + var/list/new_color = list( + 0, 1, 0, + 0, 1, 0, + 0, 1, 0 + ) + owner.vis_contents += marked_underlay + animate(marked_underlay, color = new_color, time = ready_delay, loop = 1) return TRUE return FALSE @@ -373,6 +386,20 @@ QDEL_NULL(marked_underlay) return ..() +// Object used to apply a underlay to the mob that gets this status applied +/obj/effect/abstract/crusher_mark + name = "Crusher mark underlay" + icon = 'icons/effects/effects.dmi' + icon_state = "shield" + appearance_flags = TILE_BOUND|LONG_GLIDE|RESET_COLOR + vis_flags = VIS_UNDERLAY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + color = list( + 1, 0, 0, + 1, 0, 0, + 1, 0, 0 + ) + /datum/status_effect/stacking/saw_bleed id = "saw_bleed" tick_interval = 0.6 SECONDS @@ -708,7 +735,7 @@ /datum/status_effect/go_away id = "go_away" - duration = 100 + duration = 10 SECONDS status_type = STATUS_EFFECT_REPLACE tick_interval = 0.2 SECONDS alert_type = /atom/movable/screen/alert/status_effect/go_away @@ -724,6 +751,17 @@ var/turf/T = get_step(owner, direction) owner.forceMove(T) +/datum/status_effect/go_away/deletes_mob + id = "go_away_deletes_mob" + duration = INFINITY + +/datum/status_effect/go_away/deluxe/on_creation(mob/living/new_owner, set_duration) + . = ..() + RegisterSignal(new_owner, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(wipe_bozo)) + +/datum/status_effect/go_away/deluxe/proc/wipe_bozo() + qdel(owner) + /atom/movable/screen/alert/status_effect/go_away name = "TO THE STARS AND BEYOND!" desc = "I must go, my people need me!" @@ -841,8 +879,7 @@ /datum/status_effect/ants/tick(seconds_between_ticks) var/mob/living/carbon/human/victim = owner - var/need_mob_update - need_mob_update = victim.adjustBruteLoss(max(0.1, round((ants_remaining * damage_per_ant) * seconds_between_ticks,0.1)), updating_health = FALSE) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds. + victim.apply_damage(max(0.1, round((ants_remaining * damage_per_ant), 0.1)) * seconds_between_ticks, BRUTE, spread_damage = TRUE) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds. if(victim.stat <= SOFT_CRIT) //Makes sure people don't scratch at themselves while they're in a critical condition if(prob(15)) switch(rand(1,2)) @@ -853,26 +890,21 @@ if(prob(50)) // Most of the damage is done through random chance. When tested yielded an average 100 brute with 200u ants. switch(rand(1,50)) if (1 to 8) //16% Chance - var/obj/item/bodypart/head/hed = victim.get_bodypart(BODY_ZONE_HEAD) to_chat(victim, span_danger("You scratch at the ants on your scalp!.")) - need_mob_update += hed.receive_damage(brute = 0.4 * seconds_between_ticks, burn = 0, updating_health = FALSE) + owner.apply_damage(0.4 * seconds_between_ticks, BRUTE, BODY_ZONE_HEAD) if (9 to 29) //40% chance - var/obj/item/bodypart/arm = victim.get_bodypart(pick(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM)) to_chat(victim, span_danger("You scratch at the ants on your arms!")) - need_mob_update += arm.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE) + owner.apply_damage(1.2 * seconds_between_ticks, BRUTE, pick(GLOB.arm_zones)) if (30 to 49) //38% chance - var/obj/item/bodypart/leg = victim.get_bodypart(pick(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG)) to_chat(victim, span_danger("You scratch at the ants on your leg!")) - need_mob_update += leg.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE) + owner.apply_damage(1.2 * seconds_between_ticks, BRUTE, pick(GLOB.leg_zones)) if(50) // 2% chance to_chat(victim, span_danger("You rub some ants away from your eyes!")) victim.set_eye_blur_if_lower(6 SECONDS) ants_remaining -= 5 // To balance out the blindness, it'll be a little shorter. ants_remaining-- - if(need_mob_update) - victim.updatehealth() if(ants_remaining <= 0 || victim.stat >= HARD_CRIT) - victim.remove_status_effect(type) //If this person has no more ants on them or are dead, they are no longer affected. + qdel(src) //If this person has no more ants on them or are dead, they are no longer affected. /atom/movable/screen/alert/status_effect/ants name = "Ants!" diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index 0d2b964c509d..00a6d5eff208 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -109,6 +109,7 @@ . = ..() owner.sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC owner.add_mood_event(id, /datum/mood_event/drunk) + RegisterSignal(owner, COMSIG_MOB_FIRED_GUN, PROC_REF(drunk_gun_fired)) /datum/status_effect/inebriated/drunk/on_remove() clear_effects() @@ -126,6 +127,19 @@ if(owner.sound_environment_override == SOUND_ENVIRONMENT_PSYCHOTIC) owner.sound_environment_override = SOUND_ENVIRONMENT_NONE + UnregisterSignal(owner, COMSIG_MOB_FIRED_GUN) + +/datum/status_effect/inebriated/drunk/proc/drunk_gun_fired(datum/source, obj/item/gun/gun, atom/firing_at, params, zone, bonus_spread_values) + SIGNAL_HANDLER + + // excusing the bartender, because shotgun + if(HAS_TRAIT(owner, TRAIT_DRUNKEN_BRAWLER)) + return + // what makes me a good demoman? + if(istype(gun, /obj/item/gun/grenadelauncher) || istype(gun, /obj/item/gun/ballistic/revolver/grenadelauncher)) + return + bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += (drunk_value * 0.5) + /datum/status_effect/inebriated/drunk/set_drunk_value(set_to) . = ..() if(QDELETED(src)) diff --git a/code/datums/status_effects/debuffs/terrified.dm b/code/datums/status_effects/debuffs/terrified.dm index 61a6ecd4eda3..61c4abcea3bf 100644 --- a/code/datums/status_effects/debuffs/terrified.dm +++ b/code/datums/status_effects/debuffs/terrified.dm @@ -96,6 +96,9 @@ /datum/status_effect/terrified/proc/comfort_owner(datum/source, mob/living/hugger) SIGNAL_HANDLER + if(hugger == owner) + return + if(isnightmare(hugger)) //hey wait a minute, that's not a comforting, friendly hug! if(check_surrounding_darkness()) addtimer(CALLBACK(src, PROC_REF(freak_out), HUG_TERROR_AMOUNT)) diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index cde4bc0e2b49..19249fd932b9 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -692,17 +692,14 @@ icon_state = "shower_regen_catgirl" /atom/movable/screen/alert/status_effect/washing_regen/dislike - name = "Washing" desc = "This water feels dirty..." icon_state = "shower_regen_dirty" /atom/movable/screen/alert/status_effect/washing_regen/bloody_like - name = "Washing" desc = "Mhhhmmmm... the crimson red drops of life. How delightful." icon_state = "shower_regen_blood_happy" /atom/movable/screen/alert/status_effect/washing_regen/bloody_dislike - name = "Washing" desc = "Is that... blood? What the fuck!" icon_state = "shower_regen_blood_bad" diff --git a/code/datums/status_effects/stacking_effect.dm b/code/datums/status_effects/stacking_effect.dm index acdefd8290c8..d3f128045ce0 100644 --- a/code/datums/status_effects/stacking_effect.dm +++ b/code/datums/status_effects/stacking_effect.dm @@ -119,8 +119,7 @@ return FALSE status_overlay = mutable_appearance(overlay_file, "[overlay_state][stacks]") status_underlay = mutable_appearance(underlay_file, "[underlay_state][stacks]") - var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) - var/icon_height = I.Height() + var/icon_height = owner.get_cached_height() status_overlay.pixel_x = -owner.pixel_x status_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) status_overlay.transform = matrix() * (icon_height/ICON_SIZE_Y) //scale the status's overlay size based on the target's icon size diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index 92a3a55ac692..67ee23120a63 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -30,6 +30,7 @@ status_type = STATUS_EFFECT_REPLACE tick_interval = STATUS_EFFECT_NO_TICK alert_type = /atom/movable/screen/alert/status_effect/limp + on_remove_on_mob_delete = TRUE var/msg_stage = 0//so you dont get the most intense messages immediately /// The left leg of the limping person var/obj/item/bodypart/leg/left/left diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 7fa512897135..fa16ea3819c0 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -1064,6 +1064,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) toggle_collection_mode(triggered.owner) + return COMPONENT_ACTION_BLOCK_TRIGGER + /datum/storage/proc/action_deleted(datum/source) SIGNAL_HANDLER diff --git a/code/datums/storage/subtypes/rped.dm b/code/datums/storage/subtypes/rped.dm index 9931cff7372f..a54d52ca359c 100644 --- a/code/datums/storage/subtypes/rped.dm +++ b/code/datums/storage/subtypes/rped.dm @@ -6,7 +6,6 @@ #define MAX_STACK_PICKUP 30 /datum/storage/rped - allow_quick_empty = TRUE allow_quick_gather = TRUE max_slots = 50 max_total_storage = 100 @@ -14,7 +13,7 @@ numerical_stacking = TRUE /** - * as of now only these stack components are required to build machines like[thermomaachine,crystallizer,electrolyzer] + * as of now only these stack components are required to build machines like[thermomachine,crystallizer,electrolyzer] * so we limit the rped to pick up only these stack types so players dont cheat and use this as a general storage medium */ var/static/list/allowed_material_types = list( @@ -33,11 +32,20 @@ ) /datum/storage/rped/can_insert(obj/item/to_insert, mob/user, messages = TRUE, force = FALSE) - . = ..() - if(!.) - return . + //only stock parts permited + if(to_insert.get_part_rating()) + return ..() + + //some exceptions to non stock parts + var/static/list/obj/item/exceptions = list( + /obj/item/stack, + /obj/item/circuitboard/machine, + /obj/item/circuitboard/computer, + ) + + return is_type_in_list(to_insert, exceptions) ? ..() : FALSE - //we check how much of glass,plasteel & cable the user can insert +/datum/storage/rped/attempt_insert(obj/item/to_insert, mob/user, override, force, messages) if(isstack(to_insert)) //user tried to insert invalid stacktype if(!is_type_in_list(to_insert, allowed_material_types) && !is_type_in_list(to_insert, allowed_bluespace_types)) @@ -53,60 +61,58 @@ //if yes count total bluespace stuff is the RPED and then compare the total amount to the value the user is trying to insert if(is_type_in_list(stack_content, allowed_bluespace_types)) present_amount += stack_content.amount + //count other normal stack stuff - else if(istype(to_insert,stack_content.type)) + else if(the_stack.merge_type == stack_content.merge_type) present_amount = stack_content.amount break - //no more storage for this specific stack type - if(MAX_STACK_PICKUP - present_amount == 0) - return FALSE + var/available = MAX_STACK_PICKUP - present_amount - //we want the user to insert the exact stack amount which is available so we dont have to bother subtracting & leaving left overs for the user - var/available = MAX_STACK_PICKUP-present_amount - if(available - the_stack.amount < 0) + //no more storage for this specific stack type + if(!available) return FALSE - else if(istype(to_insert, /obj/item/circuitboard/machine) || istype(to_insert, /obj/item/circuitboard/computer)) - return TRUE + var/obj/item/stack/target = the_stack + if(the_stack.amount > available) //take in only a portion of the stack that can fit in our quota + target = fast_split_stack(the_stack, available) + target.copy_evidences(the_stack) - //check normal insertion of other stock parts - else if(!to_insert.get_part_rating()) - return FALSE + . = ..(target, user, override, force, messages) + if(!. && target != the_stack) //in case of failure merge back the split amount into the original + the_stack.add(target.amount) + qdel(target) - return . - -/datum/storage/rped/mass_empty(datum/source, mob/user) - if(!allow_quick_empty) return - remove_lowest_tier(user.drop_location()) + return ..() -/** - * Searches through everything currently in storage, calculates the lowest tier of parts inside of it, - * and then dumps out every part that has the equal tier of parts. Likely a worse implementation of remove_all. - * - * Arguments - * * atom/dump_loc - where we're placing the item - */ -/datum/storage/rped/proc/remove_lowest_tier(atom/dump_loc = parent.drop_location()) +/datum/storage/rped/mass_empty(datum/source, mob/user) var/list/obj/item/parts_list = list() - var/current_lowest_tier = INFINITY - for(var/obj/item/thing in real_location) parts_list += thing + if(!parts_list.len) + return - if(parts_list.len > 0) - parts_list = reverse_range(sortTim(parts_list, GLOBAL_PROC_REF(cmp_rped_sort))) - current_lowest_tier = parts_list[1].get_part_rating() - if(ismob(parent.loc)) - parent.balloon_alert(parent.loc, "dropping lowest rated parts...") - for(var/obj/item/part in parts_list) - if(part.get_part_rating() != current_lowest_tier) - break - if(!attempt_remove(part, dump_loc, silent = TRUE)) - continue - part.pixel_x = part.base_pixel_x + rand(-8, 8) - part.pixel_y = part.base_pixel_y + rand(-8, 8) + var/current_lowest_tier = INFINITY + parts_list = reverse_range(sortTim(parts_list, GLOBAL_PROC_REF(cmp_rped_sort))) + current_lowest_tier = parts_list[1].get_part_rating() + if(ismob(parent.loc)) + parent.balloon_alert(parent.loc, "dropping lowest rated parts...") + + var/dump_loc = user.drop_location() + for(var/obj/item/part in parts_list) + if(part.get_part_rating() != current_lowest_tier) + break + if(!attempt_remove(part, dump_loc, silent = TRUE)) + continue + part.pixel_x = part.base_pixel_x + rand(-8, 8) + part.pixel_y = part.base_pixel_y + rand(-8, 8) + +///bluespace variant +/datum/storage/rped/bluespace + max_slots = 400 + max_total_storage = 800 + max_specific_storage = WEIGHT_CLASS_GIGANTIC #undef MAX_STACK_PICKUP diff --git a/code/datums/votes/_vote_datum.dm b/code/datums/votes/_vote_datum.dm index 76833f73ff5b..957160dea7d3 100644 --- a/code/datums/votes/_vote_datum.dm +++ b/code/datums/votes/_vote_datum.dm @@ -170,13 +170,14 @@ * Return a formatted string of text to be displayed to everyone. */ /datum/vote/proc/get_result_text(list/all_winners, real_winner, list/non_voters) + var/title_text = "" var/returned_text = "" if(override_question) - returned_text += span_bold(override_question) + title_text += span_bold(override_question) else - returned_text += span_bold("[capitalize(name)] Vote") + title_text += span_bold("[capitalize(name)] Vote") - returned_text += "\nWinner Selection: " + returned_text += "Winner Selection: " switch(winner_method) if(VOTE_WINNER_METHOD_NONE) returned_text += "None" @@ -215,7 +216,7 @@ returned_text += "\n" returned_text += get_winner_text(all_winners, real_winner, non_voters) - return returned_text + return fieldset_block(title_text, returned_text, "boxed_message purple_box") /** * Gets the text that displays the winning options within the result text. diff --git a/code/datums/votes/map_vote.dm b/code/datums/votes/map_vote.dm index b4f938a42e45..c5f90f16d136 100644 --- a/code/datums/votes/map_vote.dm +++ b/code/datums/votes/map_vote.dm @@ -10,6 +10,7 @@ default_choices = SSmap_vote.get_valid_map_vote_choices() /datum/vote/map_vote/create_vote() + default_choices = SSmap_vote.get_valid_map_vote_choices() . = ..() if(!.) return FALSE diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index a9b86e8d53d6..09f181afee3b 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -26,7 +26,7 @@ var/require_comms_key = FALSE /datum/world_topic/proc/TryRun(list/input) - key_valid = config && (CONFIG_GET(string/comms_key) == input["key"]) + key_valid = (CONFIG_GET(string/comms_key) == input["key"]) && CONFIG_GET(string/comms_key) && input["key"] input -= "key" if(require_comms_key && !key_valid) . = "Bad Key" @@ -114,7 +114,7 @@ var/message = "CROSS-SECTOR MESSAGE (INCOMING): [input["sender_ckey"]] (from [input["source"]]) is about to send \ the following message (will autoapprove in [soft_filter_passed ? "[extended_time_display]" : "[normal_time_display]"]): \ - REJECT

\ + REJECT

\ [html_encode(input["message"])]" if(soft_filter_passed) diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index 546b40ff4b64..5372869032c7 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -60,9 +60,10 @@ /datum/wound/blunt/bone/set_victim(new_victim) if (victim) - UnregisterSignal(victim, COMSIG_LIVING_UNARMED_ATTACK) + UnregisterSignal(victim, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_MOB_FIRED_GUN)) if (new_victim) RegisterSignal(new_victim, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(attack_with_hurt_hand)) + RegisterSignal(new_victim, COMSIG_MOB_FIRED_GUN, PROC_REF(firing_with_messed_up_hand)) return ..() @@ -119,19 +120,49 @@ // With a severe or critical wound, you have a 15% or 30% chance to proc pain on hit if(prob((severity - 1) * 15)) // And you have a 70% or 50% chance to actually land the blow, respectively - if(prob(70 - 20 * (severity - 1))) - to_chat(victim, span_userdanger("The fracture in your [limb.plaintext_zone] shoots with pain as you strike [target]!")) - limb.receive_damage(brute=rand(1,5)) + if(HAS_TRAIT(victim, TRAIT_ANALGESIA) || prob(70 - 20 * (severity - 1))) + if(!HAS_TRAIT(victim, TRAIT_ANALGESIA)) + to_chat(victim, span_danger("The fracture in your [limb.plaintext_zone] shoots with pain as you strike [target]!")) + victim.apply_damage(rand(1, 5), BRUTE, limb, wound_bonus = CANT_WOUND, wound_clothing = FALSE) else victim.visible_message(span_danger("[victim] weakly strikes [target] with [victim.p_their()] broken [limb.plaintext_zone], recoiling from pain!"), \ span_userdanger("You fail to strike [target] as the fracture in your [limb.plaintext_zone] lights up in unbearable pain!"), vision_distance=COMBAT_MESSAGE_RANGE) INVOKE_ASYNC(victim, TYPE_PROC_REF(/mob, emote), "scream") victim.Stun(0.5 SECONDS) - limb.receive_damage(brute=rand(3,7)) + victim.apply_damage(rand(3, 7), BRUTE, limb, wound_bonus = CANT_WOUND, wound_clothing = FALSE) return COMPONENT_CANCEL_ATTACK_CHAIN return NONE +/// If we're a human who's firing a gun with a broken arm, we might hurt ourselves doing so +/datum/wound/blunt/bone/proc/firing_with_messed_up_hand(datum/source, obj/item/gun/gun, atom/firing_at, params, zone, bonus_spread_values) + SIGNAL_HANDLER + + switch(limb.body_zone) + if(BODY_ZONE_L_ARM) + // Heavy guns use both hands so they will always get a penalty + // (Yes, this means having two broken arms will make heavy weapons SOOO much worse) + // Otherwise make sure THIS hand is firing THIS gun + if(gun.weapon_weight <= WEAPON_MEDIUM && !IS_LEFT_INDEX(victim.get_held_index_of_item(gun))) + return + + if(BODY_ZONE_R_ARM) + // Ditto but for right arm + if(gun.weapon_weight <= WEAPON_MEDIUM && !IS_RIGHT_INDEX(victim.get_held_index_of_item(gun))) + return + + else + // This is not arm wound, so we don't care + return + + if(gun.recoil > 0 && severity >= WOUND_SEVERITY_SEVERE && prob(25 * (severity - 1))) + if(!HAS_TRAIT(victim, TRAIT_ANALGESIA)) + to_chat(victim, span_danger("The fracture in your [limb.plaintext_zone] explodes with pain as [gun] kicks back!")) + victim.apply_damage(rand(1, 3) * (severity - 1) * gun.weapon_weight, BRUTE, limb, wound_bonus = CANT_WOUND, wound_clothing = FALSE) + + if(!HAS_TRAIT(victim, TRAIT_ANALGESIA)) + bonus_spread_values[MAX_BONUS_SPREAD_INDEX] += (15 * severity * (limb.current_gauze?.splint_factor || 1)) + /datum/wound/blunt/bone/receive_damage(wounding_type, wounding_dmg, wound_bonus) if(!victim || wounding_dmg < WOUND_MINIMUM_DAMAGE) return @@ -276,12 +307,12 @@ user.visible_message(span_danger("[user] snaps [victim]'s dislocated [limb.plaintext_zone] back into place!"), span_notice("You snap [victim]'s dislocated [limb.plaintext_zone] back into place!"), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] snaps your dislocated [limb.plaintext_zone] back into place!")) victim.emote("scream") - limb.receive_damage(brute=20, wound_bonus=CANT_WOUND) + victim.apply_damage(20, BRUTE, limb, wound_bonus = CANT_WOUND) qdel(src) else user.visible_message(span_danger("[user] wrenches [victim]'s dislocated [limb.plaintext_zone] around painfully!"), span_danger("You wrench [victim]'s dislocated [limb.plaintext_zone] around painfully!"), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] wrenches your dislocated [limb.plaintext_zone] around painfully!")) - limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + victim.apply_damage(10, BRUTE, limb, wound_bonus = CANT_WOUND) chiropractice(user) /// If someone is snapping our dislocated joint into a fracture by hand with an aggro grab and harm or disarm intent @@ -295,14 +326,13 @@ user.visible_message(span_danger("[user] snaps [victim]'s dislocated [limb.plaintext_zone] with a sickening crack!"), span_danger("You snap [victim]'s dislocated [limb.plaintext_zone] with a sickening crack!"), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] snaps your dislocated [limb.plaintext_zone] with a sickening crack!")) victim.emote("scream") - limb.receive_damage(brute=25, wound_bonus=30) + victim.apply_damage(25, BRUTE, limb, wound_bonus = 30) else user.visible_message(span_danger("[user] wrenches [victim]'s dislocated [limb.plaintext_zone] around painfully!"), span_danger("You wrench [victim]'s dislocated [limb.plaintext_zone] around painfully!"), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] wrenches your dislocated [limb.plaintext_zone] around painfully!")) - limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + victim.apply_damage(10, BRUTE, limb, wound_bonus = CANT_WOUND) malpractice(user) - /datum/wound/blunt/bone/moderate/treat(obj/item/I, mob/user) var/scanned = HAS_TRAIT(src, TRAIT_WOUND_SCANNED) var/self_penalty_mult = user == victim ? 1.5 : 1 @@ -318,10 +348,10 @@ return TRUE if(victim == user) - limb.receive_damage(brute=15, wound_bonus=CANT_WOUND) + victim.apply_damage(15, BRUTE, limb, wound_bonus = CANT_WOUND) victim.visible_message(span_danger("[user] finishes resetting [victim.p_their()] [limb.plaintext_zone]!"), span_userdanger("You reset your [limb.plaintext_zone]!")) else - limb.receive_damage(brute=10, wound_bonus=CANT_WOUND) + victim.apply_damage(10, BRUTE, limb, wound_bonus = CANT_WOUND) user.visible_message(span_danger("[user] finishes resetting [victim]'s [limb.plaintext_zone]!"), span_nicegreen("You finish resetting [victim]'s [limb.plaintext_zone]!"), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] resets your [limb.plaintext_zone]!")) @@ -441,8 +471,8 @@ return TRUE victim.visible_message(span_notice("[victim] finishes applying [I] to [victim.p_their()] [limb.plaintext_zone], grimacing from the pain!"), span_notice("You finish applying [I] to your [limb.plaintext_zone], and your bones explode in pain!")) - limb.receive_damage(25, wound_bonus=CANT_WOUND) - victim.adjustStaminaLoss(100) + victim.apply_damage(25, BRUTE, limb, wound_bonus = CANT_WOUND) + victim.apply_damage(100, STAMINA) gelled = TRUE return TRUE diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 1106f0bea76a..7defb5cfcb69 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -158,7 +158,7 @@ if(4 to INFINITY) bandage_condition = "clean" - condition += " underneath a dressing of [bandage_condition] [limb.current_gauze.name]" + condition += " underneath a dressing of [bandage_condition] [limb.current_gauze.name]." else switch(infestation) if(WOUND_INFECTION_MODERATE to WOUND_INFECTION_SEVERE) @@ -222,25 +222,13 @@ new burn common procs */ -/// if someone is using ointment or mesh on our burns -/datum/wound/burn/flesh/proc/ointmentmesh(obj/item/stack/medical/I, mob/user) - user.visible_message(span_notice("[user] begins applying [I] to [victim]'s [limb.plaintext_zone]..."), span_notice("You begin applying [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone]...")) - if (I.amount <= 0) +/// Checks if the wound is in a state that ointment or flesh will help +/datum/wound/burn/flesh/proc/can_be_ointmented_or_meshed() + if(infestation > 0 || sanitization < infestation) return TRUE - if(!do_after(user, (user == victim ? I.self_delay : I.other_delay), target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + if(flesh_damage > 0 || flesh_healing <= flesh_damage) return TRUE - - limb.heal_damage(I.heal_brute, I.heal_burn) - user.visible_message(span_green("[user] applies [I] to [victim]."), span_green("You apply [I] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone].")) - I.use(1) - sanitization += I.sanitization - flesh_healing += I.flesh_regeneration - - if((infestation <= 0 || sanitization >= infestation) && (flesh_damage <= 0 || flesh_healing > flesh_damage)) - to_chat(user, span_notice("You've done all you can with [I], now you must wait for the flesh on [victim]'s [limb.plaintext_zone] to recover.")) - return TRUE - else - return try_treating(I, user) + return FALSE /// Paramedic UV penlights /datum/wound/burn/flesh/proc/uv(obj/item/flashlight/pen/paramedic/I, mob/user) @@ -257,15 +245,7 @@ return TRUE /datum/wound/burn/flesh/treat(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/medical/ointment)) - return ointmentmesh(I, user) - else if(istype(I, /obj/item/stack/medical/mesh)) - var/obj/item/stack/medical/mesh/mesh_check = I - if(!mesh_check.is_open) - to_chat(user, span_warning("You need to open [mesh_check] first.")) - return - return ointmentmesh(mesh_check, user) - else if(istype(I, /obj/item/flashlight/pen/paramedic)) + if(istype(I, /obj/item/flashlight/pen/paramedic)) return uv(I, user) // people complained about burns not healing on stasis beds, so in addition to checking if it's cured, they also get the special ability to very slowly heal on stasis beds if they have the healing effects stored diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index fa357d47fe9a..3ad724d03c23 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -16,6 +16,8 @@ /// How much blood we start losing when this wound is first applied var/initial_flow + /// How much our blood_flow will naturally decrease per second, even without gauze + var/clot_rate /// If gauzed, what percent of the internal bleeding actually clots of the total absorption rate var/gauzed_clot_rate @@ -71,35 +73,45 @@ return BLOOD_FLOW_STEADY if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS)) return BLOOD_FLOW_INCREASING - if(limb.current_gauze) + if(limb.current_gauze || clot_rate > 0) return BLOOD_FLOW_DECREASING + if(clot_rate < 0) + return BLOOD_FLOW_INCREASING return BLOOD_FLOW_STEADY /datum/wound/pierce/bleed/handle_process(seconds_per_tick, times_fired) if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return - set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)) if(limb.can_bleed()) if(victim.bodytemperature < (BODYTEMP_NORMAL - 10)) adjust_blood_flow(-0.1 * seconds_per_tick) + if(QDELETED(src)) + return if(SPT_PROB(2.5, seconds_per_tick)) to_chat(victim, span_notice("You feel the [LOWER_TEXT(name)] in your [limb.plaintext_zone] firming up from the cold!")) if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS)) adjust_blood_flow(0.25 * seconds_per_tick) // old heparin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first + //gauze always reduces blood flow, even for non bleeders if(limb.current_gauze) - adjust_blood_flow(-limb.current_gauze.absorption_rate * gauzed_clot_rate * seconds_per_tick) - limb.current_gauze.absorption_capacity -= limb.current_gauze.absorption_rate * seconds_per_tick - - if(blood_flow <= 0) - qdel(src) - -/datum/wound/pierce/bleed/on_stasis(seconds_per_tick, times_fired) + if(clot_rate > 0) + adjust_blood_flow(-clot_rate * seconds_per_tick) + var/gauze_power = limb.current_gauze.absorption_rate + limb.seep_gauze(gauze_power * seconds_per_tick) + adjust_blood_flow(-gauze_power * gauzed_clot_rate * seconds_per_tick) + //otherwise, only clot if it's a bleeder + else if(limb.can_bleed()) + adjust_blood_flow(-clot_rate * seconds_per_tick) + +/datum/wound/pierce/bleed/adjust_blood_flow(adjust_by, minimum) . = ..() - if(blood_flow <= 0) + if(blood_flow > WOUND_MAX_BLOODFLOW) + blood_flow = WOUND_MAX_BLOODFLOW + if(blood_flow <= 0 && !QDELETED(src)) + to_chat(victim, span_green("The holes on your [limb.plaintext_zone] have [!limb.can_bleed() ? "healed up" : "stopped bleeding"]!")) qdel(src) /datum/wound/pierce/bleed/check_grab_treatments(obj/item/I, mob/user) @@ -107,9 +119,7 @@ return TRUE /datum/wound/pierce/bleed/treat(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/medical/suture)) - return suture(I, user) - else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature()) + if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature()) return tool_cauterize(I, user) /datum/wound/pierce/bleed/on_xadone(power) @@ -122,32 +132,6 @@ . = ..() adjust_blood_flow(-0.025 * reac_volume) // 20u * 0.05 = -1 blood flow, less than with slashes but still good considering smaller bleed rates -/// If someone is using a suture to close this puncture -/datum/wound/pierce/bleed/proc/suture(obj/item/stack/medical/suture/I, mob/user) - var/self_penalty_mult = (user == victim ? 1.4 : 1) - var/treatment_delay = base_treat_time * self_penalty_mult - - if(HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) - treatment_delay *= 0.5 - user.visible_message(span_notice("[user] begins expertly stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I], keeping the holo-image information in mind...")) - else - user.visible_message(span_notice("[user] begins stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) - - if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) - return TRUE - var/bleeding_wording = (!limb.can_bleed() ? "holes" : "bleeding") - user.visible_message(span_green("[user] stitches up some of the [bleeding_wording] on [victim]."), span_green("You stitch up some of the [bleeding_wording] on [user == victim ? "yourself" : "[victim]"].")) - var/blood_sutured = I.stop_bleeding / self_penalty_mult - adjust_blood_flow(-blood_sutured) - limb.heal_damage(I.heal_brute, I.heal_burn) - I.use(1) - - if(blood_flow > 0) - return try_treating(I, user) - else - to_chat(user, span_green("You successfully close the hole in [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone].")) - return TRUE - /// If someone is using either a cautery tool or something with heat to cauterize this pierce /datum/wound/pierce/bleed/proc/tool_cauterize(obj/item/I, mob/user) @@ -162,12 +146,16 @@ else user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) + playsound(user, 'sound/items/handling/surgery/cautery1.ogg', 75, TRUE) + if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return TRUE + playsound(user, 'sound/items/handling/surgery/cautery2.ogg', 75, TRUE) + var/bleeding_wording = (!limb.can_bleed() ? "holes" : "bleeding") user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim].")) - limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND) + victim.apply_damage(2 + severity, BURN, limb, wound_bonus = CANT_WOUND) if(prob(30)) victim.emote("scream") var/blood_cauterized = (0.6 / (self_penalty_mult * improv_penalty_mult)) @@ -195,12 +183,13 @@ cauterization, or in extreme circumstances, exposure to extreme cold or vaccuum. \ Follow with food and a rest period." treat_text_short = "Apply bandaging or suturing." - examine_desc = "has a small, circular hole, gently bleeding" + examine_desc = "has a small, torn hole, gently bleeding" occur_text = "spurts out a thin stream of blood" sound_effect = 'sound/effects/wounds/pierce1.ogg' severity = WOUND_SEVERITY_MODERATE initial_flow = 1.5 gauzed_clot_rate = 0.8 + clot_rate = 0.03 internal_bleeding_chance = 30 internal_bleeding_coefficient = 1.25 threshold_penalty = 20 @@ -210,6 +199,11 @@ simple_treat_text = "Bandaging the wound will reduce blood loss, help the wound close by itself quicker, and speed up the blood recovery period. The wound itself can be slowly sutured shut." homemade_treat_text = "Tea stimulates the body's natural healing systems, slightly fastening clotting. The wound itself can be rinsed off on a sink or shower as well. Other remedies are unnecessary." +/datum/wound/pierce/bleed/moderate/update_descriptions() + if(!limb.can_bleed()) + examine_desc = "has a small, torn hole" + occur_text = "splits a small hole open" + /datum/wound_pregen_data/flesh_pierce/breakage abstract = FALSE @@ -217,13 +211,35 @@ threshold_minimum = 30 -/datum/wound/pierce/bleed/moderate/update_descriptions() +/datum/wound_pregen_data/flesh_pierce/breakage/get_weight(obj/item/bodypart/limb, woundtype, damage, attack_direction, damage_source) + if (isprojectile(damage_source)) + return 0 + return weight + +/datum/wound/pierce/bleed/moderate/projectile + name = "Minor Skin Penetration" + desc = "Patient's skin has been pierced through, causing severe bruising and minor internal bleeding in affected area." + treat_text = "Apply bandaging or suturing to the wound, make use of blood clotting agents, \ + cauterization, or in extreme circumstances, exposure to extreme cold or vaccuum. \ + Follow with food and a rest period." + examine_desc = "has a small, circular hole, gently bleeding" + clot_rate = 0 + +/datum/wound/pierce/bleed/moderate/projectile/update_descriptions() if(!limb.can_bleed()) examine_desc = "has a small, circular hole" occur_text = "splits a small hole open" +/datum/wound_pregen_data/flesh_pierce/breakage/projectile + wound_path_to_generate = /datum/wound/pierce/bleed/moderate/projectile + +/datum/wound_pregen_data/flesh_pierce/breakage/projectile/get_weight(obj/item/bodypart/limb, woundtype, damage, attack_direction, damage_source) + if (!isprojectile(damage_source)) + return 0 + return weight + /datum/wound/pierce/bleed/severe - name = "Open Puncture" + name = "Open Stab Puncture" desc = "Patient's internal tissue is penetrated, causing sizeable internal bleeding and reduced limb stability." treat_text = "Swiftly apply bandaging or suturing to the wound, make use of blood clotting agents or saline-glucose, \ cauterization, or in extreme circumstances, exposure to extreme cold or vaccuum. \ @@ -235,6 +251,7 @@ severity = WOUND_SEVERITY_SEVERE initial_flow = 2.25 gauzed_clot_rate = 0.6 + clot_rate = 0.02 internal_bleeding_chance = 60 internal_bleeding_coefficient = 1.5 threshold_penalty = 35 @@ -244,6 +261,10 @@ simple_treat_text = "Bandaging the wound is essential, and will reduce blood loss. Afterwards, the wound can be sutured shut, preferably while the patient is resting and/or grasping their wound." homemade_treat_text = "Bed sheets can be ripped up to make makeshift gauze. Flour, table salt, or salt mixed with water can be applied directly to stem the flow, though unmixed salt will irritate the skin and worsen natural healing. Resting and grabbing your wound will also reduce bleeding." +/datum/wound/pierce/bleed/severe/update_descriptions() + if(!limb.can_bleed()) + occur_text = "tears a hole open" + /datum/wound_pregen_data/flesh_pierce/open_puncture abstract = FALSE @@ -251,9 +272,23 @@ threshold_minimum = 50 -/datum/wound/pierce/bleed/severe/update_descriptions() - if(!limb.can_bleed()) - occur_text = "tears a hole open" +/datum/wound_pregen_data/flesh_pierce/open_puncture/get_weight(obj/item/bodypart/limb, woundtype, damage, attack_direction, damage_source) + if (isprojectile(damage_source)) + return 0 + return weight + +/datum/wound/pierce/bleed/severe/projectile + name = "Open Bullet Puncture" + examine_desc = "is pierced clear through, with bits of tissue obscuring the cleanly torn hole" + clot_rate = 0 + +/datum/wound_pregen_data/flesh_pierce/open_puncture/projectile + wound_path_to_generate = /datum/wound/pierce/bleed/severe/projectile + +/datum/wound_pregen_data/flesh_pierce/open_puncture/projectile/get_weight(obj/item/bodypart/limb, woundtype, damage, attack_direction, damage_source) + if (!isprojectile(damage_source)) + return 0 + return weight /datum/wound/pierce/bleed/severe/eye name = "Eyeball Puncture" diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index fd3cb4bd7b2b..2ec5700e03c0 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -36,9 +36,6 @@ /// Once the blood flow drops below minimum_flow, we demote it to this type of wound. If there's none, we're all better var/demotes_to - /// The maximum flow we've had so far - var/highest_flow - /// A bad system I'm using to track the worst scar we earned (since we can demote, we want the biggest our wound has been, not what it was when it was cured (probably moderate)) var/datum/scar/highest_scar @@ -133,44 +130,23 @@ return BLOOD_FLOW_INCREASING /datum/wound/slash/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return // in case the victim has the NOBLOOD trait, the wound will simply not clot on its own if(limb.can_bleed()) - set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)) + if(clot_rate > 0) + adjust_blood_flow(-clot_rate * seconds_per_tick) + if(QDELETED(src)) + return if(HAS_TRAIT(victim, TRAIT_BLOODY_MESS)) adjust_blood_flow(0.25) // old heparin used to just add +2 bleed stacks per tick, this adds 0.5 bleed flow to all open cuts which is probably even stronger as long as you can cut them first - //gauze always reduces blood flow, even for non bleeders if(limb.current_gauze) - if(clot_rate > 0) - adjust_blood_flow(-clot_rate * seconds_per_tick) - adjust_blood_flow(-limb.current_gauze.absorption_rate * seconds_per_tick) - limb.seep_gauze(limb.current_gauze.absorption_rate * seconds_per_tick) - //otherwise, only clot if it's a bleeder - else if(limb.can_bleed()) - adjust_blood_flow(-clot_rate * seconds_per_tick) - - if(blood_flow > highest_flow) - highest_flow = blood_flow - - if(blood_flow < minimum_flow) - if(demotes_to) - replace_wound(new demotes_to) - else - to_chat(victim, span_green("The cut on your [limb.plaintext_zone] has [!limb.can_bleed() ? "healed up" : "stopped bleeding"]!")) - qdel(src) - -/datum/wound/slash/flesh/on_stasis(seconds_per_tick, times_fired) - if(blood_flow >= minimum_flow) - return - if(demotes_to) - replace_wound(new demotes_to) - return - qdel(src) + var/gauze_power = limb.current_gauze.absorption_rate + limb.seep_gauze(gauze_power * seconds_per_tick) + adjust_blood_flow(-gauze_power * seconds_per_tick) /* BEWARE, THE BELOW NONSENSE IS MADNESS. bones.dm looks more like what I have in mind and is sufficiently clean, don't pay attention to this messiness */ @@ -185,8 +161,6 @@ return las_cauterize(I, user) else if(I.tool_behaviour == TOOL_CAUTERY || I.get_temperature()) return tool_cauterize(I, user) - else if(istype(I, /obj/item/stack/medical/suture)) - return suture(I, user) /datum/wound/slash/flesh/try_handling(mob/living/user) if(user.pulling != victim || !HAS_TRAIT(user, TRAIT_WOUND_LICKER) || !victim.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE)) @@ -212,8 +186,7 @@ /// if a felinid is licking this cut to reduce bleeding /datum/wound/slash/flesh/proc/lick_wounds(mob/living/carbon/human/user) // transmission is one way patient -> felinid since google said cat saliva is antiseptic or whatever, and also because felinids are already risking getting beaten for this even without people suspecting they're spreading a deathvirus - for(var/i in victim.diseases) - var/datum/disease/iter_disease = i + for(var/datum/disease/iter_disease as anything in victim.diseases) if(iter_disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS)) continue user.ForceContractDisease(iter_disease) @@ -225,18 +198,28 @@ user.visible_message(span_notice("[user] licks the wounds on [victim]'s [limb.plaintext_zone]."), span_notice("You lick some of the wounds on [victim]'s [limb.plaintext_zone]"), ignored_mobs=victim) to_chat(victim, span_green("[user] licks the wounds on your [limb.plaintext_zone]!")) + var/mob/victim_stored = victim adjust_blood_flow(-0.5) if(blood_flow > minimum_flow) try_handling(user) else if(demotes_to) - to_chat(user, span_green("You successfully lower the severity of [victim]'s cuts.")) + to_chat(user, span_green("You successfully lower the severity of [user == victim_stored ? "your" : "[victim_stored]'s"] cuts.")) -/datum/wound/slash/flesh/on_xadone(power) +/datum/wound/slash/flesh/adjust_blood_flow(adjust_by, minimum) . = ..() + if(blood_flow > WOUND_MAX_BLOODFLOW) + blood_flow = WOUND_MAX_BLOODFLOW + if(blood_flow < minimum_flow && !QDELETED(src)) + if(demotes_to) + replace_wound(new demotes_to) + else + to_chat(victim, span_green("The cut on your [limb.plaintext_zone] has [!limb.can_bleed() ? "healed up" : "stopped bleeding"]!")) + qdel(src) - if (limb) // parent can cause us to be removed, so its reasonable to check if we're still applied - adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort +/datum/wound/slash/flesh/on_xadone(power) + . = ..() + adjust_blood_flow(-0.03 * power) // i think it's like a minimum of 3 power, so .09 blood_flow reduction per tick is pretty good for 0 effort /datum/wound/slash/flesh/on_synthflesh(reac_volume) . = ..() @@ -271,50 +254,29 @@ else user.visible_message(span_danger("[user] begins cauterizing [victim]'s [limb.plaintext_zone] with [I]..."), span_warning("You begin cauterizing [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) + playsound(user, 'sound/items/handling/surgery/cautery1.ogg', 75, TRUE) + if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) return + + playsound(user, 'sound/items/handling/surgery/cautery2.ogg', 75, TRUE) + var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding") user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim].")) - limb.receive_damage(burn = 2 + severity, wound_bonus = CANT_WOUND) + victim.apply_damage(2 + severity, BURN, limb, wound_bonus = CANT_WOUND) if(prob(30)) victim.emote("scream") var/blood_cauterized = (0.6 / (self_penalty_mult * improv_penalty_mult)) + var/mob/victim_stored = victim adjust_blood_flow(-blood_cauterized) if(blood_flow > minimum_flow) return try_treating(I, user) else if(demotes_to) - to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.")) + to_chat(user, span_green("You successfully lower the severity of [user == victim_stored ? "your" : "[victim_stored]'s"] cuts.")) return TRUE return FALSE -/// If someone is using a suture to close this cut -/datum/wound/slash/flesh/proc/suture(obj/item/stack/medical/suture/I, mob/user) - var/self_penalty_mult = (user == victim ? 1.4 : 1) - var/treatment_delay = base_treat_time * self_penalty_mult - - if(HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) - treatment_delay *= 0.5 - user.visible_message(span_notice("[user] begins expertly stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I], keeping the holo-image information in mind...")) - else - user.visible_message(span_notice("[user] begins stitching [victim]'s [limb.plaintext_zone] with [I]..."), span_notice("You begin stitching [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone] with [I]...")) - - if(!do_after(user, treatment_delay, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) - return TRUE - var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding") - user.visible_message(span_green("[user] stitches up some of the [bleeding_wording] on [victim]."), span_green("You stitch up some of the [bleeding_wording] on [user == victim ? "yourself" : "[victim]"].")) - var/blood_sutured = I.stop_bleeding / self_penalty_mult - adjust_blood_flow(-blood_sutured) - limb.heal_damage(I.heal_brute, I.heal_burn) - I.use(1) - - if(blood_flow > minimum_flow) - return try_treating(I, user) - else if(demotes_to) - to_chat(user, span_green("You successfully lower the severity of [user == victim ? "your" : "[victim]'s"] cuts.")) - return TRUE - return TRUE - /datum/wound/slash/get_limb_examine_description() return span_warning("The flesh on this limb appears badly lacerated.") diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index b988fa0b6daa..450a29d9cbd3 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -80,8 +80,8 @@ var/power_light = TRUE var/power_environ = TRUE var/power_apc_charge = TRUE - - var/has_gravity = FALSE + /// The default gravity for the area + var/default_gravity = ZERO_GRAVITY var/parallax_movedir = 0 diff --git a/code/game/area/areas/away_content.dm b/code/game/area/areas/away_content.dm index 30dc8e3126b9..b3cbc312cd24 100644 --- a/code/game/area/areas/away_content.dm +++ b/code/game/area/areas/away_content.dm @@ -8,7 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30" name = "Strange Location" icon = 'icons/area/areas_away_missions.dmi' icon_state = "away" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY ambience_index = AMBIENCE_AWAY sound_environment = SOUND_ENVIRONMENT_ROOM area_flags = NOTELEPORT|UNIQUE_AREA //NOVA EDIT CHANGE @@ -34,7 +34,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30" static_lighting = FALSE base_lighting_alpha = 255 area_flags = UNIQUE_AREA|NOTELEPORT - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY /area/awaymission/secret area_flags = UNIQUE_AREA|NOTELEPORT|HIDDEN_AREA @@ -46,7 +46,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30" outdoors = TRUE /area/awaymission/secret/unpowered/no_grav - has_gravity = FALSE + default_gravity = ZERO_GRAVITY /area/awaymission/secret/fullbright static_lighting = FALSE diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index 4049e9600dbc..217adeaea506 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -7,7 +7,7 @@ icon_state = "centcom" static_lighting = TRUE requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = UNIQUE_AREA | NOTELEPORT flags_1 = NONE @@ -156,7 +156,7 @@ icon_state = "wizards_den" static_lighting = TRUE requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = UNIQUE_AREA | NOTELEPORT flags_1 = NONE @@ -169,7 +169,7 @@ area_flags = UNIQUE_AREA | NOTELEPORT static_lighting = FALSE base_lighting_alpha = 255 - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY flags_1 = NONE //Syndicates @@ -177,7 +177,7 @@ name = "Syndicate Mothership" icon_state = "syndie-ship" requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = UNIQUE_AREA | NOTELEPORT flags_1 = NONE ambience_index = AMBIENCE_DANGER @@ -222,7 +222,7 @@ base_lighting_alpha = 255 requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY flags_1 = NONE area_flags = BLOCK_SUICIDE | UNIQUE_AREA @@ -233,7 +233,7 @@ requires_power = FALSE static_lighting = FALSE base_lighting_alpha = 255 - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY flags_1 = NONE area_flags = UNIQUE_AREA | NOTELEPORT | NO_DEATH_MESSAGE | BLOCK_SUICIDE @@ -278,7 +278,7 @@ name = "\improper Asteroid" icon_state = "asteroid" requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = UNIQUE_AREA ambience_index = AMBIENCE_MINING flags_1 = CAN_BE_DIRTY_1 diff --git a/code/game/area/areas/mining.dm b/code/game/area/areas/mining.dm index be6db4e077fe..4254e23d62bc 100644 --- a/code/game/area/areas/mining.dm +++ b/code/game/area/areas/mining.dm @@ -2,7 +2,7 @@ /area/mine icon = 'icons/area/areas_station.dmi' icon_state = "mining" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED | CULT_PERMITTED ambient_buzz = 'sound/ambience/lavaland/magma.ogg' @@ -130,7 +130,7 @@ /area/lavaland icon = 'icons/area/areas_station.dmi' icon_state = "mining" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY flags_1 = NONE area_flags = VALID_TERRITORY | UNIQUE_AREA | FLORA_ALLOWED sound_environment = SOUND_AREA_LAVALAND @@ -190,7 +190,7 @@ /area/icemoon icon = 'icons/area/areas_station.dmi' icon_state = "mining" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY flags_1 = NONE area_flags = UNIQUE_AREA | FLORA_ALLOWED ambience_index = AMBIENCE_ICEMOON diff --git a/code/game/area/areas/misc.dm b/code/game/area/areas/misc.dm index 8aa6adc738c4..00ce0d6f4641 100644 --- a/code/game/area/areas/misc.dm +++ b/code/game/area/areas/misc.dm @@ -5,13 +5,12 @@ requires_power = TRUE always_unpowered = TRUE static_lighting = FALSE - base_lighting_alpha = 255 base_lighting_color = COLOR_STARLIGHT power_light = FALSE power_equip = FALSE power_environ = FALSE - area_flags = UNIQUE_AREA + area_flags = UNIQUE_AREA|NO_GRAVITY outdoors = TRUE ambience_index = AMBIENCE_SPACE flags_1 = CAN_BE_DIRTY_1 @@ -22,7 +21,6 @@ /area/space/nearstation icon_state = "space_near" - area_flags = UNIQUE_AREA static_lighting = TRUE base_lighting_alpha = 0 base_lighting_color = null @@ -33,12 +31,12 @@ requires_power = FALSE static_lighting = FALSE base_lighting_alpha = 255 - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY ambient_buzz = null /area/misc/testroom requires_power = FALSE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY // Mobs should be able to see inside the testroom static_lighting = FALSE base_lighting_alpha = 255 diff --git a/code/game/area/areas/ruins/_ruins.dm b/code/game/area/areas/ruins/_ruins.dm index 69e17d365caf..46cf851b1ebd 100644 --- a/code/game/area/areas/ruins/_ruins.dm +++ b/code/game/area/areas/ruins/_ruins.dm @@ -4,7 +4,7 @@ name = "\improper Unexplored Location" icon = 'icons/area/areas_ruins.dmi' icon_state = "ruins" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY area_flags = HIDDEN_AREA | BLOBS_ALLOWED | UNIQUE_AREA ambience_index = AMBIENCE_RUINS flags_1 = CAN_BE_DIRTY_1 @@ -14,7 +14,7 @@ always_unpowered = TRUE /area/ruin/unpowered/no_grav - has_gravity = FALSE + default_gravity = ZERO_GRAVITY /area/ruin/powered requires_power = FALSE diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm index 3e9db5ba8441..e922d089d5e4 100644 --- a/code/game/area/areas/ruins/space.dm +++ b/code/game/area/areas/ruins/space.dm @@ -1,7 +1,7 @@ //Space Ruin Parents /area/ruin/space - has_gravity = FALSE + default_gravity = ZERO_GRAVITY area_flags = UNIQUE_AREA /area/ruin/space/unpowered @@ -11,7 +11,7 @@ power_environ = FALSE /area/ruin/space/has_grav - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY /area/ruin/space/has_grav/powered requires_power = FALSE @@ -530,18 +530,18 @@ /area/ruin/space/djstation name = "\improper Ruskie DJ Station" icon_state = "DJ" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY /area/ruin/space/djstation/solars name = "\improper DJ Station Solars" icon_state = "DJ" area_flags = UNIQUE_AREA - has_gravity = STANDARD_GRAVITY + default_gravity = ZERO_GRAVITY /area/ruin/space/djstation/service name = "\improper DJ Station Service" icon_state = "DJ" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY //ABANDONED TELEPORTER diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index 6d68f47e7a8b..360500959d94 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -6,7 +6,7 @@ name = "Shuttle" requires_power = FALSE static_lighting = TRUE - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY always_unpowered = FALSE // Loading the same shuttle map at a different time will produce distinct area instances. area_flags = NONE @@ -256,7 +256,7 @@ // ----------- Arena Shuttle /area/shuttle/shuttle_arena name = "arena" - has_gravity = STANDARD_GRAVITY + default_gravity = STANDARD_GRAVITY requires_power = FALSE /obj/effect/forcefield/arena_shuttle diff --git a/code/game/area/areas/station/science.dm b/code/game/area/areas/station/science.dm index 2787a4ff87fe..40bdd3786571 100644 --- a/code/game/area/areas/station/science.dm +++ b/code/game/area/areas/station/science.dm @@ -126,4 +126,7 @@ /area/station/science/ordnance/bomb name = "\improper Ordnance Bomb Site" icon_state = "ord_boom" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED + area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED | NO_GRAVITY + +/area/station/science/ordnance/bomb/planet + area_flags = /area/station/science/ordnance/bomb::area_flags & ~NO_GRAVITY diff --git a/code/game/area/areas/station/solars.dm b/code/game/area/areas/station/solars.dm index 57376e2fb17b..8d3a81420e7d 100644 --- a/code/game/area/areas/station/solars.dm +++ b/code/game/area/areas/station/solars.dm @@ -5,11 +5,12 @@ /area/station/solars icon_state = "panels" requires_power = FALSE - area_flags = UNIQUE_AREA + area_flags = UNIQUE_AREA|NO_GRAVITY flags_1 = NONE ambience_index = AMBIENCE_ENGI airlock_wires = /datum/wires/airlock/engineering sound_environment = SOUND_AREA_SPACE + default_gravity = ZERO_GRAVITY /area/station/solars/fore name = "\improper Fore Solar Array" @@ -40,10 +41,20 @@ name = "\improper Starboard Bow Solar Array" icon_state = "panelsFS" +/area/station/solars/starboard/fore/asteriod + name = "\improper Starboard Bow Asteriod Solar Array" + icon_state = "panelsFS" + area_flags = UNIQUE_AREA // solar areas directly on asteriod have gravity + /area/station/solars/port name = "\improper Port Solar Array" icon_state = "panelsP" +/area/station/solars/port/asteriod + name = "\improper Port Asteriod Solar Array" + icon_state = "panelsP" + area_flags = UNIQUE_AREA // solar areas directly on asteriod have gravity + /area/station/solars/port/aft name = "\improper Port Quarter Solar Array" icon_state = "panelsAP" diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index da652be4b2cb..bc9b9b8ba8bc 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -722,7 +722,7 @@ return . = density density = new_value - + SEND_SIGNAL(src, COMSIG_ATOM_DENSITY_CHANGED) ///Setter for the `base_pixel_x` variable to append behavior related to its changing. /atom/proc/set_base_pixel_x(new_value) @@ -763,6 +763,7 @@ * Gravity situations: * * No gravity if you're not in a turf * * No gravity if this atom is in is a space turf + * * No gravity if the area has NO_GRAVITY flag (space, ordnance bomb site, nearstation, solars) * * Gravity if the area it's in always has gravity * * Gravity if there's a gravity generator on the z level * * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY @@ -790,7 +791,7 @@ var/area/turf_area = gravity_turf.loc - return !gravity_turf.force_no_gravity && (SSmapping.gravity_by_z_level[gravity_turf.z] || turf_area.has_gravity) + return (!gravity_turf.force_no_gravity && !(turf_area.area_flags & NO_GRAVITY)) && (SSmapping.gravity_by_z_level[gravity_turf.z] || turf_area.default_gravity) /** * Used to set something as 'open' if it's being used as a supplypod @@ -868,6 +869,8 @@ user.face_atom(src) ///NOVA EDIT ADDITION END + SEND_SIGNAL(user, COMSIG_ATOM_MOUSE_ENTERED, src) + // Screentips var/datum/hud/active_hud = user.hud_used if(!active_hud) diff --git a/code/game/atom/atom_color.dm b/code/game/atom/atom_color.dm index 2508e86f44d9..4b20a0042280 100644 --- a/code/game/atom/atom_color.dm +++ b/code/game/atom/atom_color.dm @@ -3,6 +3,9 @@ A System that gives finer control over which atom colour to colour the atom with. The "highest priority" one is always displayed as opposed to the default of "whichever was set last is displayed" + + It can also be used for color filters, since some effects (using non-RGB space matrices) + are impossible to achieve with just the color variable */ /atom @@ -12,6 +15,8 @@ * its inherent color, the colored paint applied on it, special color effect etc... */ var/list/atom_colours + /// Currently used color filter - cached because its applied to all of our overlays because BYOND is horrific + var/cached_color_filter ///Adds an instance of colour_type to the atom's atom_colours list /atom/proc/add_atom_colour(coloration, colour_priority) @@ -22,7 +27,12 @@ return if(colour_priority > atom_colours.len) return - atom_colours[colour_priority] = coloration + var/color_type = ATOM_COLOR_TYPE_NORMAL + if (islist(coloration)) + var/list/color_matrix = coloration + if (color_matrix["type"] == "color") + color_type = ATOM_COLOR_TYPE_FILTER + atom_colours[colour_priority] = list(coloration, color_type) update_atom_colour() @@ -32,8 +42,13 @@ return if(colour_priority > atom_colours.len) return - if(coloration && atom_colours[colour_priority] != coloration) - return //if we don't have the expected color (for a specific priority) to remove, do nothing + if(coloration && atom_colours[colour_priority]) + if (atom_colours[colour_priority][ATOM_COLOR_TYPE_INDEX] == ATOM_COLOR_TYPE_NORMAL) + if (atom_colours[colour_priority][ATOM_COLOR_VALUE_INDEX] != coloration) + return //if we don't have the expected color (for a specific priority) to remove, do nothing + else + if (!islist(coloration) || !compare_list(coloration, atom_colours[colour_priority][ATOM_COLOR_VALUE_INDEX]["color"])) + return atom_colours[colour_priority] = null update_atom_colour() @@ -43,29 +58,69 @@ */ /atom/proc/is_atom_colour(looking_for_color, min_priority_index = 1, max_priority_index = COLOUR_PRIORITY_AMOUNT) // make sure uppertext hex strings don't mess with LOWER_TEXT hex strings - looking_for_color = LOWER_TEXT(looking_for_color) + if (!islist(looking_for_color)) + looking_for_color = LOWER_TEXT(looking_for_color) if(!LAZYLEN(atom_colours)) // no atom colors list has been set up, just check the color var - return LOWER_TEXT(color) == looking_for_color + if (!islist(color)) + return LOWER_TEXT(color) == looking_for_color + if (!islist(looking_for_color)) + return FALSE + return compare_list(color, looking_for_color) for(var/i in min_priority_index to max_priority_index) - if(LOWER_TEXT(atom_colours[i]) == looking_for_color) + if (!atom_colours[i]) + continue + + if (!islist(looking_for_color)) + if (islist(atom_colours[i][ATOM_COLOR_VALUE_INDEX])) + continue + + if (LOWER_TEXT(atom_colours[i][ATOM_COLOR_VALUE_INDEX]) == looking_for_color) + return TRUE + + continue + + var/compared_matrix = atom_colours[i][ATOM_COLOR_VALUE_INDEX] + if (atom_colours[i][ATOM_COLOR_TYPE_INDEX] == ATOM_COLOR_TYPE_FILTER) + compared_matrix = atom_colours[i][ATOM_COLOR_VALUE_INDEX]["color"] + + if (compare_list(looking_for_color, compared_matrix)) return TRUE return FALSE ///Resets the atom's color to null, and then sets it to the highest priority colour available /atom/proc/update_atom_colour() + var/old_filter = cached_color_filter color = null - if(!atom_colours) + cached_color_filter = null + remove_filter(ATOM_PRIORITY_COLOR_FILTER) + REMOVE_KEEP_TOGETHER(src, ATOM_COLOR_TRAIT) + + if (!atom_colours) + if (old_filter) + update_appearance() return - for(var/checked_color in atom_colours) - if(islist(checked_color)) - var/list/color_list = checked_color - if(color_list.len) - color = color_list - return - else if(checked_color) - color = checked_color - return + + for (var/list/checked_color in atom_colours) + if (checked_color[ATOM_COLOR_TYPE_INDEX] == ATOM_COLOR_TYPE_FILTER) + add_filter(ATOM_PRIORITY_COLOR_FILTER, ATOM_PRIORITY_COLOR_FILTER_PRIORITY, checked_color[ATOM_COLOR_VALUE_INDEX]) + cached_color_filter = checked_color[ATOM_COLOR_VALUE_INDEX] + break + + if (length(checked_color[ATOM_COLOR_VALUE_INDEX])) + color = checked_color[ATOM_COLOR_VALUE_INDEX] + break + + ADD_KEEP_TOGETHER(src, ATOM_COLOR_TRAIT) + if (cached_color_filter != old_filter) + update_appearance() + +/// Same as update_atom_color, but simplifies overlay coloring +/atom/proc/color_atom_overlay(mutable_appearance/overlay) + overlay.color = color + if (!cached_color_filter) + return overlay + return filter_appearance_recursive(overlay, cached_color_filter) diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 7a7dc8d3a877..14a8b41e6e10 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -199,7 +199,7 @@ . = ..() var/refid = REF(src) . += "[VV_HREF_TARGETREF(refid, VV_HK_AUTO_RENAME, "[src]")]" - . += "
<< [dir2text(dir) || dir] >>" + . += "
<< [dir2text(dir) || dir] >>" /** * call back when a var is edited on this atom diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index fbad5d993fe7..3d5c717c2af7 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1155,6 +1155,12 @@ loc = destination if(!same_loc) + if(loc == oldloc) + // when attempting to move an atom A into an atom B which already contains A, BYOND seems + // to silently refuse to move A to the new loc. This can really break stuff (see #77067) + stack_trace("Attempt to move [src] to [destination] was rejected by BYOND, possibly due to cyclic contents") + return FALSE + if(is_multi_tile && isturf(destination)) var/list/new_locs = block( destination, @@ -1284,12 +1290,12 @@ /// Only moves the object if it's under no gravity /// Accepts the direction to move, if the push should be instant, and an optional parameter to fine tune the start delay /// Drift force determines how much acceleration should be applied. Controlled cap, if set, will ensure that if the object was moving slower than the cap before, it cannot accelerate past the cap from this move. -/atom/movable/proc/newtonian_move(inertia_angle, instant = FALSE, start_delay = 0, drift_force = 1 NEWTONS, controlled_cap = null) +/atom/movable/proc/newtonian_move(inertia_angle, instant = FALSE, start_delay = 0, drift_force = 1 NEWTONS, controlled_cap = null, force_loop = TRUE) if(!isturf(loc) || Process_Spacemove(angle2dir(inertia_angle), continuous_move = TRUE)) return FALSE if (!isnull(drift_handler)) - if (drift_handler.newtonian_impulse(inertia_angle, start_delay, drift_force, controlled_cap)) + if (drift_handler.newtonian_impulse(inertia_angle, start_delay, drift_force, controlled_cap, force_loop)) return TRUE new /datum/drift_handler(src, inertia_angle, instant, start_delay, drift_force) @@ -1503,9 +1509,16 @@ return -/atom/movable/proc/do_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item, no_effect, fov_effect = TRUE) +/atom/movable/proc/do_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item, no_effect, fov_effect = TRUE, item_animation_override = null) if(!no_effect && (visual_effect_icon || used_item)) - do_item_attack_animation(attacked_atom, visual_effect_icon, used_item) + var/animation_type = item_animation_override || ATTACK_ANIMATION_BLUNT + if (used_item && !item_animation_override) + switch(used_item.get_sharpness()) + if (SHARP_EDGED) + animation_type = ATTACK_ANIMATION_SLASH + if (SHARP_POINTY) + animation_type = ATTACK_ANIMATION_PIERCE + do_item_attack_animation(attacked_atom, visual_effect_icon, used_item, animation_type = animation_type) if(attacked_atom == src) return //don't do an animation if attacking self diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 7d2c032a35b2..442493f348d6 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -166,73 +166,65 @@ Medical HUD! Basic mode needs suit sensors on. //called when a living mob changes health /mob/living/proc/med_hud_set_health() - var/image/holder = hud_list?[HEALTH_HUD] - if (isnull(holder)) - return - - holder.icon_state = "hud[RoundHealth(src)]" - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y - -//for carbon suit sensors -/mob/living/carbon/med_hud_set_health() - ..() + set_hud_image_state(HEALTH_HUD, "hud[RoundHealth(src)]") -//called when a carbon changes stat, virus or XENO_HOST +// Called when a carbon changes stat, virus or XENO_HOST +// Returns TRUE if the mob is considered "perfectly healthy", FALSE otherwise /mob/living/proc/med_hud_set_status() - var/image/holder = hud_list?[STATUS_HUD] - if (isnull(holder)) - return - - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) - holder.icon_state = "huddead" - else - holder.icon_state = "hudhealthy" + set_hud_image_state(STATUS_HUD, "huddead") + return FALSE -/mob/living/carbon/med_hud_set_status() - var/image/holder = hud_list?[STATUS_HUD] - if (isnull(holder)) - return + set_hud_image_state(STATUS_HUD, "hudhealthy") + return TRUE - var/icon/I = icon(icon, icon_state, dir) - var/virus_threat = check_virus() - holder.pixel_y = I.Height() - ICON_SIZE_Y +/mob/living/carbon/med_hud_set_status() if(HAS_TRAIT(src, TRAIT_XENO_HOST)) - holder.icon_state = "hudxeno" - else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) + set_hud_image_state(STATUS_HUD, "hudxeno") + return FALSE + + if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) if(HAS_TRAIT(src, TRAIT_MIND_TEMPORARILY_GONE) || can_defib_client()) - holder.icon_state = "huddefib" + set_hud_image_state(STATUS_HUD, "huddefib") else if(HAS_TRAIT(src, TRAIT_GHOSTROLE_ON_REVIVE)) - holder.icon_state = "hudghost" + set_hud_image_state(STATUS_HUD, "hudghost") else - holder.icon_state = "huddead" - else - switch(virus_threat) - if(DISEASE_SEVERITY_UNCURABLE) - holder.icon_state = "hudill6" - if(DISEASE_SEVERITY_BIOHAZARD) - holder.icon_state = "hudill5" - if(DISEASE_SEVERITY_DANGEROUS) - holder.icon_state = "hudill4" - if(DISEASE_SEVERITY_HARMFUL) - holder.icon_state = "hudill3" - if(DISEASE_SEVERITY_MEDIUM) - holder.icon_state = "hudill2" - if(DISEASE_SEVERITY_MINOR) - holder.icon_state = "hudill1" - if(DISEASE_SEVERITY_NONTHREAT) - holder.icon_state = "hudill0" - if(DISEASE_SEVERITY_POSITIVE) - holder.icon_state = "hudbuff" - if(null) - holder.icon_state = "hudhealthy" - if(ishuman(src)) - var/mob/living/carbon/human/crew = src - var/obj/item/clothing/under/uniform = crew.w_uniform - if(uniform && uniform.has_sensor == BROKEN_SENSORS) - holder.icon_state = "hudnosensor" + set_hud_image_state(STATUS_HUD, "huddead") + return FALSE + + var/virus_threat = check_virus() + if (!virus_threat) + set_hud_image_state(STATUS_HUD, "hudhealthy") + return TRUE + + switch(virus_threat) + if(DISEASE_SEVERITY_UNCURABLE) + set_hud_image_state(STATUS_HUD, "hudill6") + if(DISEASE_SEVERITY_BIOHAZARD) + set_hud_image_state(STATUS_HUD, "hudill5") + if(DISEASE_SEVERITY_DANGEROUS) + set_hud_image_state(STATUS_HUD, "hudill4") + if(DISEASE_SEVERITY_HARMFUL) + set_hud_image_state(STATUS_HUD, "hudill3") + if(DISEASE_SEVERITY_MEDIUM) + set_hud_image_state(STATUS_HUD, "hudill2") + if(DISEASE_SEVERITY_MINOR) + set_hud_image_state(STATUS_HUD, "hudill1") + if(DISEASE_SEVERITY_NONTHREAT) + set_hud_image_state(STATUS_HUD, "hudill0") + if(DISEASE_SEVERITY_POSITIVE) + set_hud_image_state(STATUS_HUD, "hudbuff") + return FALSE + +/mob/living/carbon/human/med_hud_set_status() + . = ..() + if (!.) + return + var/obj/item/clothing/under/uniform = w_uniform + if(istype(uniform) && uniform.has_sensor == BROKEN_SENSORS) + set_hud_image_state(STATUS_HUD, "hudnosensor") + return FALSE + /*********************************************** FAN HUDs! For identifying other fans on-sight. @@ -241,29 +233,22 @@ FAN HUDs! For identifying other fans on-sight. //HOOKS /mob/living/carbon/human/proc/fan_hud_set_fandom() - var/image/holder = hud_list[FAN_HUD] - var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y - holder.icon_state = "hudfan_no" - var/obj/item/clothing/under/undershirt = w_uniform if(!istype(undershirt)) set_hud_image_inactive(FAN_HUD) return + set_hud_image_active(FAN_HUD) for(var/accessory in undershirt.attached_accessories) if(istype(accessory, /obj/item/clothing/accessory/mime_fan_pin)) - holder.icon_state = "mime_fan_pin" - break + set_hud_image_state(FAN_HUD, "mime_fan_pin") + return if(istype(accessory, /obj/item/clothing/accessory/clown_enjoyer_pin)) - holder.icon_state = "clown_enjoyer_pin" - break - - set_hud_image_active(FAN_HUD) - return - + set_hud_image_state(FAN_HUD, "clown_enjoyer_pin") + return + set_hud_image_state(FAN_HUD, "hudfan_no") /*********************************************** Security HUDs! Basic mode shows only the job. @@ -272,55 +257,37 @@ Security HUDs! Basic mode shows only the job. //HOOKS /mob/living/carbon/human/proc/sec_hud_set_ID() - var/image/holder = hud_list[ID_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y var/sechud_icon_state = wear_id?.get_sechud_job_icon_state() if(!sechud_icon_state || HAS_TRAIT(src, TRAIT_UNKNOWN)) sechud_icon_state = "hudno_id" - holder.icon_state = sechud_icon_state + set_hud_image_state(ID_HUD, sechud_icon_state) sec_hud_set_security_status() //NOVA EDIT START - var/image/permit_holder = hud_list[PERMIT_HUD] - permit_holder.pixel_y = I.Height() - world.icon_size var/permit_icon_state = wear_id?.get_gun_permit_iconstate() if(!permit_icon_state) permit_icon_state = "hudfan_no" - permit_holder.icon_state = permit_icon_state + set_hud_image_state(PERMIT_HUD, permit_icon_state) //NOVA EDIT END /mob/living/proc/sec_hud_set_implants() - var/image/holder - for(var/i in (list(IMPSEC_FIRST_HUD, IMPLOYAL_HUD, IMPSEC_SECOND_HUD) & hud_list)) - holder = hud_list[i] - holder.icon_state = null - set_hud_image_inactive(i) + for(var/hud_type in (list(IMPSEC_FIRST_HUD, IMPLOYAL_HUD, IMPSEC_SECOND_HUD) & hud_list)) + set_hud_image_inactive(hud_type) var/security_slot = 1 //Which of the two security hud slots are we putting found security implants in? for(var/obj/item/implant/current_implant in implants) if(current_implant.implant_flags & IMPLANT_TYPE_SECURITY) switch(security_slot) if(1) - holder = hud_list[IMPSEC_FIRST_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y - holder.icon_state = current_implant.hud_icon_state + set_hud_image_state(IMPSEC_FIRST_HUD, current_implant.hud_icon_state) set_hud_image_active(IMPSEC_FIRST_HUD) security_slot++ if(2) //Theoretically if we somehow get multiple sec implants, whatever the most recently implanted implant is will take over the 2nd position - holder = hud_list[IMPSEC_SECOND_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y - holder.pixel_x = initial(holder.pixel_x) + (ICON_SIZE_X / 4 - 1) //Adds an offset that mirrors the hud blip to the other side of the mob. - holder.icon_state = current_implant.hud_icon_state + set_hud_image_state(IMPSEC_SECOND_HUD, current_implant.hud_icon_state, x_offset = (ICON_SIZE_X / 4 - 1)) //Adds an offset that mirrors the hud blip to the other side of the mob set_hud_image_active(IMPSEC_SECOND_HUD) if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) - holder = hud_list[IMPLOYAL_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y - holder.icon_state = "hud_imp_loyal" + set_hud_image_state(IMPLOYAL_HUD, "hud_imp_loyal") set_hud_image_active(IMPLOYAL_HUD) /mob/living/carbon/human/proc/sec_hud_set_security_status() @@ -328,39 +295,33 @@ Security HUDs! Basic mode shows only the job. // We haven't finished initializing yet, huds will be updated once we are return - var/image/holder = hud_list[WANTED_HUD] - var/icon/sec_icon = icon(icon, icon_state, dir) - holder.pixel_y = sec_icon.Height() - ICON_SIZE_Y - if (HAS_TRAIT(src, TRAIT_ALWAYS_WANTED)) - holder.icon_state = "hudwanted" + set_hud_image_state(WANTED_HUD, "hudwanted") set_hud_image_active(WANTED_HUD) return var/perp_name = get_face_name(get_id_name("")) if(!perp_name || !GLOB.manifest) - holder.icon_state = null set_hud_image_inactive(WANTED_HUD) return var/datum/record/crew/target = find_record(perp_name) if(!target || target.wanted_status == WANTED_NONE) - holder.icon_state = null set_hud_image_inactive(WANTED_HUD) return switch(target.wanted_status) if(WANTED_ARREST) - holder.icon_state = "hudwanted" + set_hud_image_state(WANTED_HUD, "hudwanted") if(WANTED_PRISONER) - holder.icon_state = "hudincarcerated" + set_hud_image_state(WANTED_HUD, "hudincarcerated") if(WANTED_SUSPECT) - holder.icon_state = "hudsuspected" + set_hud_image_state(WANTED_HUD, "hudsuspected") if(WANTED_PAROLE) - holder.icon_state = "hudparolled" + set_hud_image_state(WANTED_HUD, "hudparolled") if(WANTED_DISCHARGED) - holder.icon_state = "huddischarged" + set_hud_image_state(WANTED_HUD, "huddischarged") set_hud_image_active(WANTED_HUD) @@ -405,170 +366,132 @@ Diagnostic HUDs! //Sillycone hooks /mob/living/silicon/proc/diag_hud_set_health() - var/image/holder = hud_list[DIAG_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(stat == DEAD) - holder.icon_state = "huddiagdead" + set_hud_image_state(DIAG_HUD, "huddiagdead") else - holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + set_hud_image_state(DIAG_HUD, "huddiag[RoundDiagBar(health/maxHealth)]") /mob/living/silicon/proc/diag_hud_set_status() - var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y switch(stat) if(CONSCIOUS) - holder.icon_state = "hudstat" + set_hud_image_state(DIAG_STAT_HUD, "hudstat") if(UNCONSCIOUS, HARD_CRIT) - holder.icon_state = "hudoffline" + set_hud_image_state(DIAG_STAT_HUD, "hudoffline") else - holder.icon_state = "huddead2" + set_hud_image_state(DIAG_STAT_HUD, "huddead2") //Borgie battery tracking! /mob/living/silicon/robot/proc/diag_hud_set_borgcell() - var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) - holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" + set_hud_image_state(DIAG_BATT_HUD, "hudbatt[RoundDiagBar(chargelvl)]") else - holder.icon_state = "hudnobatt" + set_hud_image_state(DIAG_BATT_HUD, "hudnobatt") //borg-AI shell tracking -/mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows tracking beacons on the mech - var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y +/mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows if AI is controlling a cyborg via a BORIS module if(!shell) //Not an AI shell - holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) return - else if(deployed) //AI shell in use by an AI - holder.icon_state = "hudtrackingai" + if(deployed) //AI shell in use by an AI + set_hud_image_state(DIAG_TRACK_HUD, "hudtrackingai") else //Empty AI shell - holder.icon_state = "hudtracking" + set_hud_image_state(DIAG_TRACK_HUD, "hudtracking") set_hud_image_active(DIAG_TRACK_HUD) //AI side tracking of AI shell control -/mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech - var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y +/mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows if AI is currently shunted into a BORIS borg if(!deployed_shell) - holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) - else //AI is currently controlling a shell - holder.icon_state = "hudtrackingai" - set_hud_image_active(DIAG_TRACK_HUD) + return + //AI is currently controlling a shell + set_hud_image_state(DIAG_TRACK_HUD, "hudtrackingai") + set_hud_image_active(DIAG_TRACK_HUD) /*~~~~~~~~~~~~~~~~~~~~ BIG STOMPY MECHS ~~~~~~~~~~~~~~~~~~~~~*/ /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth() - var/image/holder = hud_list[DIAG_MECH_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y - holder.icon_state = "huddiag[RoundDiagBar(atom_integrity/max_integrity)]" - + set_hud_image_state(DIAG_MECH_HUD, "huddiag[RoundDiagBar(atom_integrity/max_integrity)]") /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell() - var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = cell.charge/cell.maxcharge - holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" + set_hud_image_state(DIAG_BATT_HUD, "hudbatt[RoundDiagBar(chargelvl)]") else - holder.icon_state = "hudnobatt" + set_hud_image_state(DIAG_BATT_HUD, "hudnobatt") /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat() - var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y - if(internal_damage) - holder.icon_state = "hudwarn" - set_hud_image_active(DIAG_STAT_HUD) + if(!internal_damage) + set_hud_image_inactive(DIAG_STAT_HUD) return - holder.icon_state = null - set_hud_image_inactive(DIAG_STAT_HUD) + + set_hud_image_state(DIAG_STAT_HUD, "hudwarn") + set_hud_image_active(DIAG_STAT_HUD) ///Shows tracking beacons on the mech /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() - var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y var/new_icon_state //This var exists so that the holder's icon state is set only once in the event of multiple mech beacons. - for(var/obj/item/mecha_parts/mecha_tracking/T in trackers) - if(T.ai_beacon) //Beacon with AI uplink + for(var/obj/item/mecha_parts/mecha_tracking/tracker in trackers) + if(tracker.ai_beacon) //Beacon with AI uplink new_icon_state = "hudtrackingai" break //Immediately terminate upon finding an AI beacon to ensure it is always shown over the normal one, as mechs can have several trackers. else new_icon_state = "hudtracking" - holder.icon_state = new_icon_state + set_hud_image_state(DIAG_TRACK_HUD, new_icon_state) ///Shows inbuilt camera on the mech; if the camera's view range was affected by an EMP, shows a red blip while it's affected /obj/vehicle/sealed/mecha/proc/diag_hud_set_camera() - var/image/holder = hud_list[DIAG_CAMERA_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y - if(chassis_camera?.is_emp_scrambled) - holder.icon_state = "hudcamera_empd" + if(!chassis_camera) + set_hud_image_inactive(DIAG_CAMERA_HUD) return - holder.icon_state = "hudcamera" + + set_hud_image_active(DIAG_CAMERA_HUD) + if(chassis_camera?.is_emp_scrambled) + set_hud_image_state(DIAG_CAMERA_HUD, "hudcamera_empd") + else + set_hud_image_state(DIAG_CAMERA_HUD, "hudcamera") /*~~~~~~~~~ Bots! ~~~~~~~~~~*/ /mob/living/simple_animal/bot/proc/diag_hud_set_bothealth() - var/image/holder = hud_list[DIAG_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y - holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + set_hud_image_state(DIAG_HUD, "huddiag[RoundDiagBar(health/maxHealth)]") /mob/living/simple_animal/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed - var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) - holder.icon_state = "hudstat" + set_hud_image_state(DIAG_STAT_HUD, "hudstat") else if(stat) //Generally EMP causes this - holder.icon_state = "hudoffline" + set_hud_image_state(DIAG_STAT_HUD, "hudoffline") else //Bot is off - holder.icon_state = "huddead2" + set_hud_image_state(DIAG_STAT_HUD, "huddead2") /mob/living/simple_animal/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation - var/image/holder = hud_list[DIAG_BOT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(client) //If the bot is player controlled, it will not be following mode logic! - holder.icon_state = "hudsentient" + set_hud_image_state(DIAG_BOT_HUD, "hudsentient") return switch(mode) if(BOT_SUMMON, BOT_RESPONDING) //Responding to PDA or AI summons - holder.icon_state = "hudcalled" + set_hud_image_state(DIAG_BOT_HUD, "hudcalled") if(BOT_CLEANING, BOT_HEALING) //Cleanbot cleaning, repairbot fixing, or Medibot Healing - holder.icon_state = "hudworking" + set_hud_image_state(DIAG_BOT_HUD, "hudworking") if(BOT_PATROL, BOT_START_PATROL) //Patrol mode - holder.icon_state = "hudpatrol" + set_hud_image_state(DIAG_BOT_HUD, "hudpatrol") if(BOT_PREP_ARREST, BOT_ARREST, BOT_HUNT) //STOP RIGHT THERE, CRIMINAL SCUM! - holder.icon_state = "hudalert" + set_hud_image_state(DIAG_BOT_HUD, "hudalert") if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES. - holder.icon_state = "hudmove" + set_hud_image_state(DIAG_BOT_HUD, "hudmove") else - holder.icon_state = "" + set_hud_image_state(DIAG_BOT_HUD, "") /mob/living/simple_animal/bot/mulebot/proc/diag_hud_set_mulebotcell() - var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) - holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" + set_hud_image_state(DIAG_BATT_HUD, "hudbatt[RoundDiagBar(chargelvl)]") else - holder.icon_state = "hudnobatt" + set_hud_image_state(DIAG_STAT_HUD, "hudnobatt") + /*~~~~~~~~~~~~ Airlocks! ~~~~~~~~~~~~~*/ @@ -587,3 +510,64 @@ Diagnostic HUDs! holder.loc = get_turf(src) SET_PLANE(holder,ABOVE_LIGHTING_PLANE,src) set_hud_image_active(MALF_APC_HUD) + +#define CACHED_WIDTH_INDEX "width" +#define CACHED_HEIGHT_INDEX "height" + +/atom/proc/get_cached_width() + if (isnull(icon)) + return 0 + var/list/dimensions = get_icon_dimensions(icon) + return dimensions[CACHED_WIDTH_INDEX] + +/atom/proc/get_cached_height() + if (isnull(icon)) + return 0 + var/list/dimensions = get_icon_dimensions(icon) + return dimensions[CACHED_HEIGHT_INDEX] + +#undef CACHED_WIDTH_INDEX +#undef CACHED_HEIGHT_INDEX + +/atom/proc/get_visual_width() + var/width = get_cached_width() + var/height = get_cached_height() + var/scale_list = list( + width * transform.a + height * transform.b + transform.c, + width * transform.a + transform.c, + height * transform.b + transform.c, + transform.c + ) + return max(scale_list) - min(scale_list) + +/atom/proc/get_visual_height() + var/width = get_cached_width() + var/height = get_cached_height() + var/scale_list = list( + width * transform.d + height * transform.e + transform.f, + width * transform.d + transform.f, + height * transform.e + transform.f, + transform.f + ) + return max(scale_list) - min(scale_list) + +/atom/proc/adjust_hud_position(image/holder, animate_time = null) + if (animate_time) + animate(holder, pixel_x = -(get_cached_width() - ICON_SIZE_X) / 2, pixel_y = get_cached_height() - ICON_SIZE_Y, time = animate_time) + return + holder.pixel_x = -(get_cached_width() - ICON_SIZE_X) / 2 + holder.pixel_y = get_cached_height() - ICON_SIZE_Y + +/atom/proc/set_hud_image_state(hud_type, hud_state, x_offset = 0, y_offset = 0) + if (!hud_list) // Still initializing + return + var/image/holder = hud_list[hud_type] + if (!holder) + return + if (!istype(holder)) // Can contain lists for HUD_LIST_LIST hinted HUDs, if someone fucks up and passes this here we wanna know about it + CRASH("[src] ([type]) had a HUD_LIST_LIST hud_type [hud_type] passed into set_hud_image_state!") + holder.icon_state = hud_state + adjust_hud_position(holder) + if (x_offset || y_offset) + holder.pixel_x += x_offset + holder.pixel_y += y_offset diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 24ad407763ba..9e6799d8ab38 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -96,61 +96,62 @@ layer = BELOW_OBJ_LAYER //keeps shit coming out of the machine from ending up underneath it. flags_ricochet = RICOCHET_HARD receive_ricochet_chance_mod = 0.3 - anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT blocks_emissive = EMISSIVE_BLOCK_GENERIC initial_language_holder = /datum/language_holder/speaking_machine + armor_type = /datum/armor/obj_machinery + ///see code/__DEFINES/stat.dm var/machine_stat = NONE + ///see code/__DEFINES/machines.dm var/use_power = IDLE_POWER_USE - //0 = dont use power - //1 = use idle_power_usage - //2 = use active_power_usage ///the amount of static power load this machine adds to its area's power_usage list when use_power = IDLE_POWER_USE var/idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION ///the amount of static power load this machine adds to its area's power_usage list when use_power = ACTIVE_POWER_USE var/active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION ///the current amount of static power usage this machine is taking from its area var/static_power_usage = 0 + //AREA_USAGE_EQUIP,AREA_USAGE_ENVIRON or AREA_USAGE_LIGHT var/power_channel = AREA_USAGE_EQUIP - //AREA_USAGE_EQUIP,AREA_USAGE_ENVIRON or AREA_USAGE_LIGHT ///A combination of factors such as having power, not being broken and so on. Boolean. var/is_operational = TRUE - var/wire_compatible = FALSE - - var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames. + ///list of all the parts used to build it, if made from certain kinds of frames. + var/list/component_parts = null + ///Is the machines maintainence panel open. var/panel_open = FALSE + ///Is the machine open or closed 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 + ///If this machine is critical to station operation and should have the area be excempted from power failures. + var/critical_machine = FALSE + ///if set, turned into typecache in Initialize, other wise, defaults to mob/living typecache + var/list/occupant_typecache + ///The mob that is sealed inside the machine var/atom/movable/occupant = null - /// Viable flags to go here are START_PROCESSING_ON_INIT, or START_PROCESSING_MANUALLY. See code\__DEFINES\machines.dm for more information on these flags. + ///Viable flags to go here are START_PROCESSING_ON_INIT, or START_PROCESSING_MANUALLY. See code\__DEFINES\machines.dm for more information on these flags. var/processing_flags = START_PROCESSING_ON_INIT - /// What subsystem this machine will use, which is generally SSmachines or SSfastprocess. By default all machinery use SSmachines. This fires a machine's process() roughly every 2 seconds. + ///What subsystem this machine will use, which is generally SSmachines or SSfastprocess. By default all machinery use SSmachines. This fires a machine's process() roughly every 2 seconds. var/subsystem_type = /datum/controller/subsystem/machines - var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created - - var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN|INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_OPEN_SILICON - var/fair_market_price = 69 - var/market_verb = "Customer" + ///Circuit to be created and inserted when the machinery is created + var/obj/item/circuitboard/circuit + ///See code/DEFINES/interaction_flags.dm + var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON + ///The department we are paying to use this machine var/payment_department = ACCOUNT_ENG - + ///Used in NAP violation, pay fine + var/fair_market_price = 5 ///Is this machine currently in the atmos machinery queue? var/atmos_processing = FALSE - /// world.time of last use by [/mob/living] + ///world.time of last use by [/mob/living] var/last_used_time = 0 - /// Mobtype of last user. Typecast to [/mob/living] for initial() usage + ///Mobtype of last user. Typecast to [/mob/living] for initial() usage var/mob/living/last_user_mobtype - /// Do we want to hook into on_enter_area and on_exit_area? - /// Disables some optimizations + ///Do we want to hook into on_enter_area and on_exit_area? + ///Disables some optimizations var/always_area_sensitive = FALSE - ///Multiplier for power consumption. - var/machine_power_rectifier = 1 - /// What was our power state the last time we updated its appearance? - /// TRUE for on, FALSE for off, -1 for never checked + ///What was our power state the last time we updated its appearance? + ///TRUE for on, FALSE for off, -1 for never checked var/appearance_power_state = -1 - armor_type = /datum/armor/obj_machinery /datum/armor/obj_machinery melee = 25 @@ -187,15 +188,6 @@ SHOULD_NOT_OVERRIDE(TRUE) post_machine_initialize() -/obj/machinery/Destroy(force) - SSmachines.unregister_machine(src) - end_processing() - - clear_components() - unset_static_power() - - return ..() - /** * Called in LateInitialize meant to be the machine replacement to it * This sets up power for the machine and requires parent be called, @@ -203,13 +195,25 @@ * This is the proc to override if you want to do anything in LateInitialize. */ /obj/machinery/proc/post_machine_initialize() + PROTECTED_PROC(TRUE) SHOULD_CALL_PARENT(TRUE) + power_change() if(use_power == NO_POWER_USE) return update_current_power_usage() setup_area_power_relationship() + +/obj/machinery/Destroy(force) + SSmachines.unregister_machine(src) + end_processing() + + clear_components() + unset_static_power() + + return ..() + /** * proc to call when the machine starts to require power after a duration of not requiring power * sets up power related connections to its area if it exists and becomes area sensitive @@ -271,19 +275,16 @@ SEND_SIGNAL(src, COMSIG_MACHINERY_SET_OCCUPANT, new_occupant) occupant = new_occupant -/// Helper proc for telling a machine to start processing with the subsystem type that is located in its `subsystem_type` var. +/// Helper proc for telling a machine to start processing /obj/machinery/proc/begin_processing() var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems START_PROCESSING(subsystem, src) -/// Helper proc for telling a machine to stop processing with the subsystem type that is located in its `subsystem_type` var. +/// Helper proc for telling a machine to stop processing /obj/machinery/proc/end_processing() var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems STOP_PROCESSING(subsystem, src) -/obj/machinery/proc/locate_machinery() - return - ///Early process for machines added to SSmachines.processing_early to prioritize power draw /obj/machinery/proc/process_early() set waitfor = FALSE @@ -303,6 +304,8 @@ ///Called when we want to change the value of the machine_stat variable. Holds bitflags. /obj/machinery/proc/set_machine_stat(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + if(new_value == machine_stat) return . = machine_stat @@ -312,6 +315,8 @@ ///Called when the value of `machine_stat` changes, so we can react to it. /obj/machinery/proc/on_set_machine_stat(old_value) + PROTECTED_PROC(TRUE) + //From off to on. if((old_value & (NOPOWER|BROKEN|MAINT)) && !(machine_stat & (NOPOWER|BROKEN|MAINT))) set_is_operational(TRUE) @@ -335,13 +340,6 @@ remove_all_languages(source = LANGUAGE_EMP) grant_random_uncommon_language(source = LANGUAGE_EMP) -/obj/machinery/base_item_interaction(mob/living/user, obj/item/tool, list/modifiers) - //takes priority in case material container or other atoms that hook onto item interaction signals won't give it a chance - if(istype(tool, /obj/item/storage/part_replacer)) - return tool.interact_with_atom(src, user, modifiers) - - return ..() - /** * Opens the machine. * @@ -496,6 +494,7 @@ ///internal proc that removes all static power usage from the current area /obj/machinery/proc/unset_static_power() SHOULD_NOT_OVERRIDE(TRUE) + var/old_usage = static_power_usage var/area/our_area = get_area(src) @@ -582,6 +581,8 @@ ///Called when we want to change the value of the `is_operational` variable. Boolean. /obj/machinery/proc/set_is_operational(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + if(new_value == is_operational) return . = is_operational @@ -591,10 +592,14 @@ ///Called when the value of `is_operational` changes, so we can react to it. /obj/machinery/proc/on_set_is_operational(old_value) + PROTECTED_PROC(TRUE) + return ///Called when we want to change the value of the `panel_open` variable. Boolean. /obj/machinery/proc/set_panel_open(new_value) + SHOULD_NOT_OVERRIDE(TRUE) + if(panel_open == new_value) return var/old_value = panel_open @@ -603,10 +608,14 @@ ///Called when the value of `panel_open` changes, so we can react to it. /obj/machinery/proc/on_set_panel_open(old_value) + PROTECTED_PROC(TRUE) + return /// Toggles the panel_open var. Defined for convienience /obj/machinery/proc/toggle_panel_open() + SHOULD_NOT_OVERRIDE(TRUE) + set_panel_open(!panel_open) /obj/machinery/can_interact(mob/user) @@ -663,7 +672,14 @@ return TRUE // If we passed all of those checks, woohoo! We can interact with this machine. +/** + * Checks for NAP non aggression principle, an anarcho capitalist event triggered by admins + * where using machines cost money + */ /obj/machinery/proc/check_nap_violations() + PROTECTED_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + if(!SSeconomy.full_ancap) return TRUE if(!occupant || state_open) @@ -671,16 +687,16 @@ var/mob/living/occupant_mob = occupant var/obj/item/card/id/occupant_id = occupant_mob.get_idcard(TRUE) if(!occupant_id) - say("[market_verb] NAP Violation: No ID card found.") + say("Customer NAP Violation: No ID card found.") nap_violation(occupant_mob) return FALSE var/datum/bank_account/insurance = occupant_id.registered_account if(!insurance) - say("[market_verb] NAP Violation: No bank account found.") + say("Customer NAP Violation: No bank account found.") nap_violation(occupant_mob) return FALSE if(!insurance.adjust_money(-fair_market_price)) - say("[market_verb] NAP Violation: Unable to pay.") + say("Customer NAP Violation: Unable to pay.") nap_violation(occupant_mob) return FALSE var/datum/bank_account/department_account = SSeconomy.get_dep_account(payment_department) @@ -688,7 +704,15 @@ department_account.adjust_money(fair_market_price) return TRUE +/** + * Actions to take in case of NAP violation + * Arguments + * + * * mob/violator - the mob who violated the NAP aggrement + */ /obj/machinery/proc/nap_violation(mob/violator) + PROTECTED_PROC(TRUE) + return //////////////////////////////////////////////////////////////////////////////////////////// @@ -744,13 +768,10 @@ /obj/machinery/attack_hulk(mob/living/carbon/user) . = ..() - var/obj/item/bodypart/arm = user.hand_bodyparts[user.active_hand_index] - if(!arm) - return - if(arm.bodypart_disabled) + var/obj/item/bodypart/arm = user.get_active_hand() + if(!arm || arm.bodypart_disabled) return - var/damage = damage_deflection * 0.1 - arm.receive_damage(brute=damage, wound_bonus = CANT_WOUND) + user.apply_damage(damage_deflection * 0.1, BRUTE, arm, wound_bonus = CANT_WOUND) /obj/machinery/attack_robot(mob/user) if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON) && !isAdminGhostAI(user)) @@ -799,10 +820,14 @@ if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE_TOOLS) return ITEM_INTERACT_BLOCKING + //takes priority in case material container or other atoms that hook onto item interaction signals won't give it a chance + if(istype(tool, /obj/item/storage/part_replacer)) + update_last_used(user) + return tool.interact_with_atom(src, user, modifiers) + . = ..() if(.) update_last_used(user) - return . /obj/machinery/_try_interact(mob/user) if((interaction_flags_machine & INTERACT_MACHINE_WIRES_IF_OPEN) && panel_open && (attempt_wire_interaction(user) == WIRE_INTERACTION_BLOCK)) @@ -836,6 +861,8 @@ SEND_SIGNAL(src, COMSIG_MACHINERY_REFRESH_PARTS) /obj/machinery/proc/default_pry_open(obj/item/crowbar, close_after_pry = FALSE, open_density = FALSE, closed_density = TRUE) + PROTECTED_PROC(TRUE) + . = !(state_open || panel_open || is_operational) && crowbar.tool_behaviour == TOOL_CROWBAR if(!.) return @@ -846,6 +873,8 @@ close_machine(density_to_set = closed_density) /obj/machinery/proc/default_deconstruction_crowbar(obj/item/crowbar, ignore_panel = 0, custom_deconstruct = FALSE) + PROTECTED_PROC(TRUE) + . = (panel_open || ignore_panel) && crowbar.tool_behaviour == TOOL_CROWBAR if(!. || custom_deconstruct) return @@ -991,21 +1020,16 @@ return TRUE /obj/machinery/proc/exchange_parts(mob/user, obj/item/storage/part_replacer/replacer_tool) - if(!istype(replacer_tool)) + if(!istype(replacer_tool) || !component_parts) return FALSE - var/shouldplaysound = FALSE - if(!component_parts) - return FALSE - - if(!panel_open && !replacer_tool.works_from_distance) + var/works_from_distance = istype(replacer_tool, /obj/item/storage/part_replacer/bluespace) + if(!panel_open && !works_from_distance) to_chat(user, display_parts(user)) - if(shouldplaysound) - replacer_tool.play_rped_sound() return FALSE var/obj/item/circuitboard/machine/machine_board = locate(/obj/item/circuitboard/machine) in component_parts - if(replacer_tool.works_from_distance) + if(works_from_distance) to_chat(user, display_parts(user)) if(!machine_board) return FALSE @@ -1016,6 +1040,7 @@ * completly ignoring the tier 4 component inside * we also ignore stack components inside the RPED cause we dont exchange that */ + var/shouldplaysound = FALSE var/list/part_list = replacer_tool.get_sorted_parts(ignore_stacks = TRUE) if(!part_list.len) return FALSE @@ -1046,7 +1071,7 @@ if(!istype(secondary_part, required_type)) continue // If it's a corrupt or rigged cell, attempting to send it through Bluespace could have unforeseen consequences. - if(istype(secondary_part, /obj/item/stock_parts/power_store/cell) && replacer_tool.works_from_distance) + if(istype(secondary_part, /obj/item/stock_parts/power_store/cell) && works_from_distance) var/obj/item/stock_parts/power_store/cell/checked_cell = secondary_part // If it's rigged or corrupted, max the charge. Then explode it. if(checked_cell.rigged || checked_cell.corrupted) diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 9e089eeaf2be..3b01c40403d8 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -6,6 +6,14 @@ var/airlock_state var/frequency + +/obj/machinery/door/airlock/mouse_drop_receive(mob/living/dropping, mob/user, params) + . = ..() + // We add the component only once here & not in Initialize() because there are tons of airlocks & we don't want to add to their init times + // This is on airlock rather than on door because windoors are door and leaning looks whack on windoors + LoadComponent(/datum/component/leanable, dropping) + + /// Forces the airlock to unbolt and open /obj/machinery/door/airlock/proc/secure_open() locked = FALSE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 06c88f4749e1..85db1e34e6d1 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -88,7 +88,7 @@ return CONTEXTUAL_SCREENTIP_SET /obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool) - . = ITEM_INTERACT_BLOCKING + . = NONE if(default_deconstruction_crowbar(tool)) return ITEM_INTERACT_SUCCESS diff --git a/code/game/machinery/big_manipulator.dm b/code/game/machinery/big_manipulator.dm index 21a7de89fe61..a14a6b853117 100644 --- a/code/game/machinery/big_manipulator.dm +++ b/code/game/machinery/big_manipulator.dm @@ -288,7 +288,12 @@ target.forceMove(drop_turf) target.dir = get_dir(get_turf(target), get_turf(src)) else - target.forceMove(where_we_drop) + var/atom/drop_target = where_we_drop + if(drop_target.atom_storage) + if(!drop_target.atom_storage.attempt_insert(target, override = TRUE, messages = FALSE)) + target.forceMove(drop_target.drop_location()) + else + target.forceMove(where_we_drop) finish_manipulation() /// 3.3 take and drop proc from [take and drop procs loop]: diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 7b66872f52bb..aa93bbb431d2 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -12,6 +12,7 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.02 resistance_flags = LAVA_PROOF | FIRE_PROOF interaction_flags_machine = parent_type::interaction_flags_machine | INTERACT_MACHINE_OPEN + mouse_over_pointer = MOUSE_HAND_POINTER ///Icon suffix for the skin of the front pannel that is added to base_icon_state var/skin = "" ///Whether it is possible to change the panel skin diff --git a/code/game/machinery/camera/camera_construction.dm b/code/game/machinery/camera/camera_construction.dm index b3593aad6e7e..19d7d2a39567 100644 --- a/code/game/machinery/camera/camera_construction.dm +++ b/code/game/machinery/camera/camera_construction.dm @@ -189,9 +189,9 @@ ai.last_tablet_note_seen = "[itemname][info]" if(user.name == "Unknown") - to_chat(ai, "[span_name(user)] holds \a [itemname] up to one of your cameras ...") + to_chat(ai, "[span_name(user)] holds \a [itemname] up to one of your cameras ...") else - to_chat(ai, "[user] holds \a [itemname] up to one of your cameras ...") + to_chat(ai, "[user] holds \a [itemname] up to one of your cameras ...") continue if (potential_viewer.client?.eye == src) @@ -232,16 +232,16 @@ log_paper("[key_name(user)] held [last_shown_paper] up to [src], requesting [key_name(ai)] read it.") if(user.name == "Unknown") - to_chat(ai, "[span_name(user.name)] holds \a [item_name] up to one of your cameras ...") + to_chat(ai, "[span_name(user.name)] holds \a [item_name] up to one of your cameras ...") else - to_chat(ai, "[user] holds \a [item_name] up to one of your cameras ...") + to_chat(ai, "[user] holds \a [item_name] up to one of your cameras ...") continue // If it's not an AI, eye if the client's eye is set to the camera. I wonder if this even works anymore with tgui camera apps and stuff? if (potential_viewer.client?.eye == src) log_paper("[key_name(user)] held [last_shown_paper] up to [src], and [key_name(potential_viewer)] may read it.") potential_viewer.log_talk(item_name, LOG_VICTIM, tag="Pressed to camera from [key_name(user)]", log_globally=FALSE) - to_chat(potential_viewer, "[span_name(user)] holds \a [item_name] up to your camera...") + to_chat(potential_viewer, "[span_name(user)] holds \a [item_name] up to your camera...") return return ..() diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 05027b03494d..e106d76145ca 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -19,6 +19,8 @@ var/time_to_unscrew = 2 SECONDS /// Are we authenticated to use this? Used by things like comms console, security and medical data, and apc controller. var/authenticated = FALSE + /// Will projectiles be able to pass over this computer? + var/projectiles_pass_chance = 65 /datum/armor/machinery_computer fire = 40 @@ -28,6 +30,28 @@ . = ..() power_change() +/obj/machinery/computer/mouse_drop_receive(mob/living/dropping, mob/user, params) + . = ..() + // We add the component only once here & not in Initialize() because there are tons of computers & we don't want to add to their init times + LoadComponent(/datum/component/leanable, dropping) + +/obj/machinery/computer/CanAllowThrough(atom/movable/mover, border_dir) // allows projectiles to fly over the computer + . = ..() + if(.) + return + if(!projectiles_pass_chance) + return FALSE + if(!isprojectile(mover)) + return FALSE + var/obj/projectile/proj = mover + if(!anchored) + return TRUE + if(proj.firer && Adjacent(proj.firer)) + return TRUE + if(prob(projectiles_pass_chance)) + return TRUE + return FALSE + /obj/machinery/computer/process() if(machine_stat & (NOPOWER|BROKEN)) return FALSE @@ -88,13 +112,15 @@ set_light(0) /obj/machinery/computer/proc/imprint_gps(gps_tag) // Currently used by the upload computers and communications console - var/tracker = gps_tag - if(!tracker) // Don't give a null GPS signal if there is none - return - for(var/obj/item/circuitboard/computer/board in src.contents) - if(!contents || board.GetComponent(/datum/component/gps)) - CRASH("[src] Called imprint_gps without setting gps_tag") - board.AddComponent(/datum/component/gps, "[tracker]") + if(!length(gps_tag)) // Don't give a null GPS signal if there is none + CRASH("[src] called imprint_gps without setting gps_tag") + var/set_tracker = FALSE + for(var/obj/item/circuitboard/computer/board in contents) + if(board.GetComponent(/datum/component/gps)) + return + board.AddComponent(/datum/component/gps, "[gps_tag]") + set_tracker = TRUE + if (set_tracker) balloon_alert_to_viewers("board tracker enabled", vision_distance = 1) /obj/machinery/computer/emp_act(severity) diff --git a/code/game/machinery/computer/arcade/_arcade.dm b/code/game/machinery/computer/arcade/_arcade.dm index eb91fa44f1c7..1627a3d0fe81 100644 --- a/code/game/machinery/computer/arcade/_arcade.dm +++ b/code/game/machinery/computer/arcade/_arcade.dm @@ -7,6 +7,7 @@ icon_screen = "invaders" light_color = LIGHT_COLOR_GREEN interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_LITERACY + projectiles_pass_chance = 0 // I guess gambling can save your life huh? ///If set, will dispense these as prizes instead of the default GLOB.arcade_prize_pool ///Like prize pool, it must be a list of the prize and the weight of being selected. diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index a37bee62567e..bc5714791803 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -125,8 +125,6 @@ if(add_cabling(user, cable, time = 0)) if(!no_sound) replacer.play_rped_sound() - if(replacer.works_from_distance) - user.Beam(src, icon_state = "rped_upgrade", time = 0.5 SECONDS) no_sound = TRUE return install_parts_from_part_replacer(user, replacer, no_sound = no_sound) // Recursive call to handle the next part @@ -140,8 +138,6 @@ if(add_glass(user, glass_sheets, time = 0)) if(!no_sound) replacer.play_rped_sound() - if(replacer.works_from_distance) - user.Beam(src, icon_state = "rped_upgrade", time = 0.5 SECONDS) return TRUE return FALSE diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 4df303f3b54e..4582a5c9d5ba 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -217,6 +217,9 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE) var/new_sec_level = SSsecurity_level.text_level_to_number(params["newSecurityLevel"]) if (new_sec_level < SEC_LEVEL_GREEN || new_sec_level > SEC_LEVEL_AMBER) //NOVA EDIT CHANGE - ALERTS return + if (SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_DELTA) + to_chat(user, span_warning("Central Command has placed a lock on the alert level due to a doomsday!")) + return if (SSsecurity_level.get_current_level_as_number() == new_sec_level) return @@ -360,7 +363,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE) span_adminnotice( \ "CROSS-SECTOR MESSAGE (OUTGOING): [ADMIN_LOOKUPFLW(user)] is about to send \ the following message to [destination] (will autoapprove in [GLOB.communications_controller.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \ - REJECT
\ + REJECT
\ [html_encode(message)]" \ ) ) @@ -422,7 +425,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE) state = STATE_MAIN playsound(src, 'sound/machines/terminal/terminal_on.ogg', 50, FALSE) - imprint_gps(gps_tag = "Encrypted Communications Channel") + imprint_gps("Encrypted Communications Channel") if ("toggleEmergencyAccess") if(emergency_access_cooldown(user)) //if were in cooldown, dont allow the following code diff --git a/code/game/machinery/computer/records/medical.dm b/code/game/machinery/computer/records/medical.dm index 259c78d976ac..794b6e61c79a 100644 --- a/code/game/machinery/computer/records/medical.dm +++ b/code/game/machinery/computer/records/medical.dm @@ -18,6 +18,7 @@ icon_screen = "medlaptop" icon_keyboard = "laptop_key" pass_flags = PASSTABLE + projectiles_pass_chance = 100 /obj/machinery/computer/records/medical/attacked_by(obj/item/attacking_item, mob/living/user) . = ..() @@ -101,7 +102,9 @@ if("add_note") if(!params["content"]) return FALSE - var/content = trim(params["content"], MAX_MESSAGE_LEN) + var/content = reject_bad_name(params["content"], allow_numbers = TRUE, max_length = MAX_MESSAGE_LEN, strict = TRUE, cap_after_symbols = FALSE) + if(!content) + return FALSE var/datum/medical_note/new_note = new(usr.name, content) while(length(target.medical_notes) > 2) diff --git a/code/game/machinery/computer/records/records.dm b/code/game/machinery/computer/records/records.dm index 9da92ba5da44..8bf91bc51b5f 100644 --- a/code/game/machinery/computer/records/records.dm +++ b/code/game/machinery/computer/records/records.dm @@ -41,9 +41,9 @@ if(!field || !(field in target?.vars)) return FALSE - var/value = trim(params["value"], MAX_BROADCAST_LEN) - investigate_log("[key_name(user)] changed the field: \"[field]\" with value: \"[target.vars[field]]\" to new value: \"[value || "Unknown"]\"", INVESTIGATE_RECORDS) - target.vars[field] = value || "Unknown" + var/value = reject_bad_name(params["value"], allow_numbers = TRUE, max_length = MAX_BROADCAST_LEN, strict = TRUE, cap_after_symbols = FALSE) || "Unknown" + investigate_log("[key_name(user)] changed the field: \"[field]\" with value: \"[target.vars[field]]\" to new value: \"[value]\"", INVESTIGATE_RECORDS) + target.vars[field] = value return TRUE diff --git a/code/game/machinery/computer/records/security.dm b/code/game/machinery/computer/records/security.dm index 1209079d1ba6..6a2f20043fd8 100644 --- a/code/game/machinery/computer/records/security.dm +++ b/code/game/machinery/computer/records/security.dm @@ -27,6 +27,7 @@ icon_screen = "seclaptop" icon_keyboard = "laptop_key" pass_flags = PASSTABLE + projectiles_pass_chance = 100 /obj/machinery/computer/records/security/laptop/syndie desc = "A cheap, jailbroken security laptop. It functions as a security records console. It's bolted to the table." diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 12aa1c3ce036..228391e6bdee 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -176,7 +176,7 @@ if(!isnull(console_location)) to_chat(R, span_alert("The approximate location of the console that is keeping you locked down is [console_location]")) if(R.connected_ai) - to_chat(R.connected_ai, "[!R.lockcharge ? span_notice("NOTICE - Cyborg lockdown lifted") : span_alert("ALERT - Cyborg lockdown detected")]: [R.name]
") + to_chat(R.connected_ai, "[!R.lockcharge ? span_notice("NOTICE - Cyborg lockdown lifted") : span_alert("ALERT - Cyborg lockdown detected")]: [R.name]
") /obj/machinery/computer/robotics/proc/borg_destroyed() SIGNAL_HANDLER diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 8cd12610c748..74e6d22e3635 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -116,7 +116,7 @@ say("Processing hub calibration to target...") calibrating = TRUE power_station.update_appearance() - addtimer(CALLBACK(src, PROC_REF(finish_calibration)), 50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration + addtimer(CALLBACK(src, PROC_REF(finish_calibration)), 5 SECONDS * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration return TRUE /obj/machinery/computer/teleporter/proc/set_teleport_target(new_target) diff --git a/code/game/machinery/computer/telescreen.dm b/code/game/machinery/computer/telescreen.dm index 3325146be413..b8f034e3580a 100644 --- a/code/game/machinery/computer/telescreen.dm +++ b/code/game/machinery/computer/telescreen.dm @@ -12,6 +12,7 @@ light_power = 0 /// The kind of wallframe that this telescreen drops var/frame_type = /obj/item/wallframe/telescreen + projectiles_pass_chance = 100 /obj/item/wallframe/telescreen name = "telescreen frame" diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index f0b3434ec85c..0a41adcac98f 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -22,6 +22,11 @@ if(circuit) . += "It has \a [circuit] installed." +/obj/structure/frame/CanAllowThrough(atom/movable/mover, border_dir) + if(isprojectile(mover)) + return TRUE + return ..() + /obj/structure/frame/atom_deconstruct(disassembled = TRUE) var/atom/movable/drop_loc = drop_location() new /obj/item/stack/sheet/iron(drop_loc, 5) @@ -112,6 +117,16 @@ return install_board(user, tool, by_hand = TRUE) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING return NONE +/obj/structure/frame/ranged_item_interaction(mob/living/user, obj/item/tool, list/modifiers) + . = NONE + + if(!istype(tool, /obj/item/storage/part_replacer/bluespace)) + return + + . = item_interaction(user, tool, modifiers) + if(. & ITEM_INTERACT_ANY_BLOCKER) + user.Beam(tool, icon_state = "rped_upgrade", time = 0.5 SECONDS) + /** * Installs the passed circuit board into the frame * @@ -173,7 +188,7 @@ if(QDELETED(target_board) || QDELETED(src) || QDELETED(user) || !(target_board in replacer) || !user.is_holding(replacer)) return FALSE // User still within range? - var/close_enough = replacer.works_from_distance || user.Adjacent(src) + var/close_enough = istype(replacer, /obj/item/storage/part_replacer/bluespace) || user.Adjacent(src) if(!close_enough) return FALSE @@ -182,8 +197,6 @@ install_parts_from_part_replacer(user, replacer, no_sound = TRUE) if(!no_sound) replacer.play_rped_sound() - if(replacer.works_from_distance) - user.Beam(src, icon_state = "rped_upgrade", time = 0.5 SECONDS) return TRUE return FALSE diff --git a/code/game/machinery/dna_infuser/infuser_actions.dm b/code/game/machinery/dna_infuser/infuser_actions.dm index 466bed9e17ef..9613854627f0 100644 --- a/code/game/machinery/dna_infuser/infuser_actions.dm +++ b/code/game/machinery/dna_infuser/infuser_actions.dm @@ -37,7 +37,7 @@ // We do this in InterceptClickOn() instead of Activate() // because we use the click parameters for aiming the projectile // (or something like that) -/datum/action/cooldown/ink_spit/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/ink_spit/InterceptClickOn(mob/living/clicker, params, atom/target) if(!LAZYACCESS(params2list(params), RIGHT_CLICK)) return . = ..() @@ -45,16 +45,16 @@ return var/modifiers = params2list(params) - caller.visible_message( - span_danger("[caller] spits ink!"), + clicker.visible_message( + span_danger("[clicker] spits ink!"), span_bold("You spit ink."), ) - var/obj/projectile/ink_spit/ink = new /obj/projectile/ink_spit(caller.loc) - ink.aim_projectile(target, caller, modifiers) - ink.firer = caller + var/obj/projectile/ink_spit/ink = new /obj/projectile/ink_spit(clicker.loc) + ink.aim_projectile(target, clicker, modifiers) + ink.firer = clicker ink.fire() - playsound(caller, 'sound/items/weapons/pierce.ogg', 20, TRUE, -1) - caller.newtonian_move(get_angle(target, caller)) + playsound(clicker, 'sound/items/weapons/pierce.ogg', 20, TRUE, -1) + clicker.newtonian_move(get_angle(target, clicker)) StartCooldown() return TRUE diff --git a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm index 9a873b5e373f..221881c6ea5b 100644 --- a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm @@ -98,6 +98,7 @@ name = "carp tooth" desc = "Looks sharp. Sharp enough to poke someone's eye out. Holy fuck it's big." icon_state = "carptooth" + icon_angle = -45 ///carp brain. you need to occasionally go to a new zlevel. think of it as... walking your dog! /obj/item/organ/brain/carp diff --git a/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm b/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm index 23f9a377ab65..23cc79c26c35 100644 --- a/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/fly_organs.dm @@ -61,12 +61,10 @@ ) // NOVA EDIT ADDITION END -/obj/item/organ/tongue/fly/New(class, timer, datum/mutation/human/copymut) - . = ..() - AddComponent(/datum/component/speechmod, replacements = CONFIG_GET(flag/russian_text_formation) ? russian_speech_replacements : speech_replacements, should_modify_speech = CALLBACK(src, PROC_REF(should_modify_speech))) // NOVA EDIT CHANGE - ORIGINAL:AddComponent(/datum/component/speechmod, replacements = speech_replacements, should_modify_speech = CALLBACK(src, PROC_REF(should_modify_speech))) /obj/item/organ/tongue/fly/Initialize(mapload) . = ..() + AddComponent(/datum/component/speechmod, replacements = CONFIG_GET(flag/russian_text_formation) ? russian_speech_replacements : speech_replacements, should_modify_speech = CALLBACK(src, PROC_REF(should_modify_speech))) // NOVA EDIT CHANGE - ORIGINAL:AddComponent(/datum/component/speechmod, replacements = speech_replacements, should_modify_speech = CALLBACK(src, PROC_REF(should_modify_speech))) AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/fly) /obj/item/organ/tongue/fly/get_possible_languages() diff --git a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm index 5a06aa8e8c20..e4315c4a5e24 100644 --- a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm @@ -99,6 +99,7 @@ icon = 'icons/obj/weapons/goliath_hammer.dmi' icon_state = "goliath_hammer" inhand_icon_state = "goliath_hammer" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/weapons/goliath_hammer_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/goliath_hammer_righthand.dmi' item_flags = ABSTRACT | DROPDEL diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 24538d03e5d8..721eeb78d062 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -193,6 +193,8 @@ // Click on the floor to close airlocks AddComponent(/datum/component/redirect_attack_hand_from_turf) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "airlock", TRUE) + RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) @@ -558,7 +560,7 @@ else . += get_airlock_overlay("fill_[frame_state]", icon, src, em_block = TRUE) - if(lights && hasPower()) + if(lights && hasPower() && light_state) . += get_airlock_overlay("lights_[light_state]", overlays_file, src, em_block = FALSE) if(panel_open) @@ -1187,13 +1189,15 @@ return TRUE -/obj/machinery/door/airlock/try_to_crowbar(obj/item/I, mob/living/user, forced = FALSE) - if(I.tool_behaviour == TOOL_CROWBAR && should_try_removing_electronics() && !operating) +/obj/machinery/door/airlock/try_to_crowbar(obj/item/tool, mob/living/user, forced = FALSE) + if(!isnull(tool) && tool.tool_behaviour == TOOL_CROWBAR && should_try_removing_electronics() && !operating) user.visible_message(span_notice("[user] removes the electronics from the airlock assembly."), \ span_notice("You start to remove electronics from the airlock assembly...")) - if(I.use_tool(src, user, 40, volume = 100)) + + if(tool.use_tool(src, user, 40, volume = 100)) deconstruct(TRUE, user) return + if(seal) to_chat(user, span_warning("Remove the seal first!")) return @@ -1203,37 +1207,49 @@ if(welded) to_chat(user, span_warning("It's welded, it won't budge!")) return - if(hasPower()) - if(forced) - var/check_electrified = isElectrified() //setting this so we can check if the mob got shocked during the do_after below - if(check_electrified && shock(user,100)) - return //it's like sticking a fork in a power socket - if(!density)//already open - return + if(!hasPower()) + if(operating) + return - if(!prying_so_hard) - var/time_to_open = 50 - playsound(src, 'sound/machines/airlock/airlock_alien_prying.ogg', 100, TRUE) //is it aliens or just the CE being a dick? - prying_so_hard = TRUE - if(I.use_tool(src, user, time_to_open, volume = 100)) - if(check_electrified && shock(user, 100)) - prying_so_hard = FALSE - return - open(BYPASS_DOOR_CHECKS) - take_damage(25, BRUTE, 0, 0) // Enough to sometimes spark - if(density && !open(BYPASS_DOOR_CHECKS)) - to_chat(user, span_warning("Despite your attempts, [src] refuses to open.")) - prying_so_hard = FALSE - return + if(istype(tool, /obj/item/fireaxe) && !HAS_TRAIT(tool, TRAIT_WIELDED)) //being fireaxe'd + to_chat(user, span_warning("You need to be wielding [tool] to do that!")) + return + + INVOKE_ASYNC(src, density ? PROC_REF(open) : PROC_REF(close), BYPASS_DOOR_CHECKS) + return + + if(!forced) to_chat(user, span_warning("The airlock's motors resist your efforts to force it!")) return - if(!operating) - if(istype(I, /obj/item/fireaxe) && !HAS_TRAIT(I, TRAIT_WIELDED)) //being fireaxe'd - to_chat(user, span_warning("You need to be wielding [I] to do that!")) - return - INVOKE_ASYNC(src, density ? PROC_REF(open) : PROC_REF(close), BYPASS_DOOR_CHECKS) + var/check_electrified = isElectrified() //setting this so we can check if the mob got shocked during the do_after below + if(check_electrified && shock(user,100)) + return //it's like sticking a fork in a power socket + + if(!density)//already open + return + + if(prying_so_hard) + return + + var/time_to_open = 5 SECONDS + playsound(src, 'sound/machines/airlock/airlock_alien_prying.ogg', 100, TRUE) //is it aliens or just the CE being a dick? + prying_so_hard = TRUE + + if(!tool.use_tool(src, user, time_to_open, volume = 100)) + prying_so_hard = FALSE + return + + prying_so_hard = FALSE + + if(check_electrified && shock(user, 100)) + return + + open(BYPASS_DOOR_CHECKS) + take_damage(25, BRUTE, 0, 0) // Enough to sometimes spark + if(density && !open(BYPASS_DOOR_CHECKS)) + to_chat(user, span_warning("Despite your attempts, [src] refuses to open.")) /obj/machinery/door/airlock/open(forced = DEFAULT_DOOR_CHECKS) if(cycle_pump && !operating && !welded && !seal && locked && density) @@ -1354,7 +1370,7 @@ if(air_tight) set_density(TRUE) if(multi_tile) - filler.density = TRUE + filler.set_density(TRUE) flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) var/unpassable_delay = animation_segment_delay(AIRLOCK_CLOSING_UNPASSABLE) @@ -1362,7 +1378,7 @@ if(!air_tight) set_density(TRUE) if(multi_tile) - filler.density = TRUE + filler.set_density(TRUE) flags_1 |= PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, TRUE) var/opaque_delay = animation_segment_delay(AIRLOCK_CLOSING_OPAQUE) - unpassable_delay @@ -1564,6 +1580,7 @@ assembly.previous_assembly = previous_airlock assembly.update_name() assembly.update_appearance() + assembly.dir = dir /obj/machinery/door/airlock/on_deconstruction(disassembled) var/obj/structure/door_assembly/A @@ -2241,7 +2258,7 @@ if(!hasPower()) to_chat(user, span_notice("You begin unlocking the airlock safety mechanism...")) if(do_after(user, 15 SECONDS, target = src)) - try_to_crowbar(src, user, TRUE) + try_to_crowbar(null, user, TRUE) return TRUE else // always open from the space side @@ -2480,6 +2497,10 @@ opacity = FALSE glass = TRUE +/obj/machinery/door/airlock/multi_tile/setDir(newdir) + . = ..() + set_bounds() + /obj/structure/fluff/airlock_filler name = "airlock fluff" desc = "You shouldn't be able to see this fluff!" diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index d58bcbc34fe3..70446401cb9d 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -549,7 +549,7 @@ if(welded || operating) return - var/atom/crowbar_owner = acting_object.loc //catchs mechs and any other non-mob using a crowbar + var/atom/crowbar_owner = acting_object?.loc || user // catches mechs and any other non-mob using a crowbar if(density) being_held_open = TRUE @@ -578,19 +578,23 @@ else close() -/obj/machinery/door/firedoor/proc/handle_held_open_adjacency(mob/user) +/obj/machinery/door/firedoor/proc/handle_held_open_adjacency(atom/crowbar_owner) SIGNAL_HANDLER - var/mob/living/living_user = user - if(!QDELETED(user) && Adjacent(user) && isliving(user) && (living_user.body_position == STANDING_UP)) - return + + if(!QDELETED(crowbar_owner) && crowbar_owner.CanReach(src)) + if(!ismob(crowbar_owner)) + return + var/mob/living/mob_user = crowbar_owner + if(isliving(mob_user) && (mob_user.body_position == STANDING_UP)) + return being_held_open = FALSE correct_state() - UnregisterSignal(user, COMSIG_MOVABLE_MOVED) - UnregisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION) - UnregisterSignal(user, COMSIG_QDELETING) - if(user) - user.balloon_alert_to_viewers("released firelock", "released firelock") + UnregisterSignal(crowbar_owner, COMSIG_MOVABLE_MOVED) + UnregisterSignal(crowbar_owner, COMSIG_LIVING_SET_BODY_POSITION) + UnregisterSignal(crowbar_owner, COMSIG_QDELETING) + if(crowbar_owner) + crowbar_owner.balloon_alert_to_viewers("released firelock", "released firelock") /obj/machinery/door/firedoor/attack_ai(mob/user) add_fingerprint(user) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index dd5df8ef96f4..5dfcf915c80f 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -22,6 +22,12 @@ var/id = 1 /// The sound that plays when the door opens/closes var/animation_sound = 'sound/machines/blastdoor.ogg' + var/show_nav_computer_icon = TRUE + +/obj/machinery/door/poddoor/Initialize(mapload) + . = ..() + if(show_nav_computer_icon) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "airlock", TRUE) /datum/armor/door_poddoor melee = 50 diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 56e2f5a9743b..52c12835c279 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -10,6 +10,7 @@ max_integrity = 100 recipe_type = /datum/crafting_recipe/shutters animation_sound = 'sound/machines/shutter.ogg' + show_nav_computer_icon = FALSE /obj/machinery/door/poddoor/shutters/animation_length(animation) switch(animation) diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 1c7d27e73684..4826fac12df0 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -4,6 +4,7 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.05 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.04 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + mouse_over_pointer = MOUSE_HAND_POINTER var/idSelf /obj/machinery/door_buttons/attackby(obj/O, mob/user) @@ -109,6 +110,7 @@ icon_state = "access_control_standby" base_icon_state = "access_control" interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN|INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_OPEN_SILICON + mouse_over_pointer = MOUSE_HAND_POINTER ///the id of the interior airlock var/idInterior ///the id of the exterior airlock diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index b22959ce461b..4505be8be47e 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -18,6 +18,7 @@ max_integrity = 250 integrity_failure = 0.4 armor_type = /datum/armor/machinery_firealarm + mouse_over_pointer = MOUSE_HAND_POINTER idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.05 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.02 power_channel = AREA_USAGE_ENVIRON diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index 4a0e78f52071..d67517325338 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -326,154 +326,3 @@ return CLICK_ACTION_SUCCESS #undef CREATE_AND_INCREMENT - -/obj/item/flatpack - name = "flatpack" - desc = "A box containing a compactly packed machine. Use multitool to deploy." - icon = 'icons/obj/devices/circuitry_n_data.dmi' - icon_state = "flatpack" - density = TRUE - w_class = WEIGHT_CLASS_HUGE //cart time - throw_range = 2 - item_flags = SLOWS_WHILE_IN_HAND | IMMUTABLE_SLOW - slowdown = 2.5 - drag_slowdown = 3.5 //use the cart stupid - - /// The board we deploy - var/obj/item/circuitboard/machine/board - -/obj/item/flatpack/Initialize(mapload, obj/item/circuitboard/machine/new_board) - if(isnull(board) && isnull(new_board)) - return INITIALIZE_HINT_QDEL //how - - . = ..() - - var/static/list/tool_behaviors = list( - TOOL_MULTITOOL = list( - SCREENTIP_CONTEXT_LMB = "Deploy", - ), - ) - AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) - - board = !isnull(new_board) ? new_board : new board(src) // i got board - if(board.loc != src) - board.forceMove(src) - var/obj/machinery/build = initial(board.build_path) - name += " ([initial(build.name)])" - -/obj/item/flatpack/Destroy() - QDEL_NULL(board) - . = ..() - -/obj/item/flatpack/examine(mob/user) - . = ..() - if(!in_range(user, src) && !isobserver(user)) - return - - if(loc == user) - . += span_warning("You can't deploy while holding it in your hand.") - else if(isturf(loc)) - var/turf/location = loc - if(!isopenturf(location)) - . += span_warning("Can't deploy in this location") - else if(location.is_blocked_turf(source_atom = src)) - . += span_warning("No space for deployment") - -/obj/item/flatpack/multitool_act(mob/living/user, obj/item/tool) - . = NONE - - if(isnull(board)) - return ITEM_INTERACT_BLOCKING - if(loc == user) - balloon_alert(user, "can't deploy in hand") - return ITEM_INTERACT_BLOCKING - else if(isturf(loc)) - var/turf/location = loc - if(!isopenturf(location)) - balloon_alert(user, "can't deploy here") - return ITEM_INTERACT_BLOCKING - else if(location.is_blocked_turf(source_atom = src)) - balloon_alert(user, "no space for deployment") - return ITEM_INTERACT_BLOCKING - balloon_alert_to_viewers("deploying!") - if(!do_after(user, 1 SECONDS, target = src)) - return ITEM_INTERACT_BLOCKING - - new /obj/effect/temp_visual/mook_dust(loc) - var/obj/machinery/new_machine = new board.build_path(loc) - loc.visible_message(span_warning("[src] deploys!")) - playsound(src, 'sound/machines/terminal/terminal_eject.ogg', 70, TRUE) - new_machine.on_construction(user) - qdel(src) - return ITEM_INTERACT_SUCCESS - -///Maximum number of flatpacks in a cart -#define MAX_FLAT_PACKS 3 - -/obj/structure/flatpack_cart - name = "flatpack cart" - desc = "A cart specifically made to hold flatpacks from a flatpacker, evenly distributing weight. Convenient!" - icon = 'icons/obj/structures.dmi' - icon_state = "flatcart" - density = TRUE - opacity = FALSE - -/obj/structure/flatpack_cart/Initialize(mapload) - . = ..() - - register_context() - - AddElement(/datum/element/noisy_movement, volume = 45) // i hate noise - -/obj/structure/flatpack_cart/atom_deconstruct(disassembled) - for(var/atom/movable/content as anything in contents) - content.forceMove(drop_location()) - -/obj/structure/flatpack_cart/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = NONE - if(isnull(held_item)) - return - - if(istype(held_item, /obj/item/flatpack)) - context[SCREENTIP_CONTEXT_LMB] = "Load pack" - return CONTEXTUAL_SCREENTIP_SET - -/obj/structure/flatpack_cart/examine(mob/user) - . = ..() - if(!in_range(user, src) && !isobserver(user)) - return - - . += "From bottom to top, this cart contains:" - for(var/obj/item/flatpack as anything in contents) - . += flatpack.name - -/obj/structure/flatpack_cart/update_overlays() - . = ..() - - var/offset = 0 - for(var/item in contents) - var/mutable_appearance/flatpack_overlay = mutable_appearance(icon, "flatcart_flat", layer = layer + (offset * 0.01)) - flatpack_overlay.pixel_y = offset - offset += 4 - . += flatpack_overlay - -/obj/structure/flatpack_cart/attack_hand(mob/user, list/modifiers) - . = ..() - if(.) - return - user.put_in_hands(contents[length(contents)]) //topmost box - update_appearance(UPDATE_OVERLAYS) - -/obj/structure/flatpack_cart/item_interaction(mob/living/user, obj/item/attacking_item, params) - if(!istype(attacking_item, /obj/item/flatpack) || user.combat_mode || attacking_item.flags_1 & HOLOGRAM_1 || attacking_item.item_flags & ABSTRACT) - return ITEM_INTERACT_SKIP_TO_ATTACK - - if (length(contents) >= MAX_FLAT_PACKS) - balloon_alert(user, "full!") - return ITEM_INTERACT_BLOCKING - if (!user.transferItemToLoc(attacking_item, src)) - return ITEM_INTERACT_BLOCKING - update_appearance(UPDATE_OVERLAYS) - return ITEM_INTERACT_SUCCESS - -#undef MAX_FLAT_PACKS diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 48f0a94385e2..390256aac6be 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -301,9 +301,9 @@ Possible to do for anyone motivated enough: for(var/I in holo_calls) var/datum/holocall/HC = I var/list/call_data = list( - caller = HC.user, - connected = HC.connected_holopad == src ? TRUE : FALSE, - ref = REF(HC) + "caller" = HC.user, + "connected" = HC.connected_holopad == src ? TRUE : FALSE, + "ref" = REF(HC) ) data["holo_calls"] += list(call_data) return data @@ -327,7 +327,7 @@ Possible to do for anyone motivated enough: for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) if(!AI.client) continue - to_chat(AI, span_info("Your presence is requested at \the [area]. Project Hologram?")) + to_chat(AI, span_info("Your presence is requested at \the [area]. Project Hologram?")) return TRUE else to_chat(usr, span_info("A request for AI presence was already sent recently.")) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index f13b1947524f..f8bfeceb69f5 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -225,7 +225,7 @@ to_chat(attached_to, span_userdanger("The IV drip needle is ripped out of you, leaving an open bleeding wound!")) var/list/arm_zones = shuffle(list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM)) var/obj/item/bodypart/chosen_limb = attached_mob.get_bodypart(arm_zones[1]) || attached_mob.get_bodypart(arm_zones[2]) || attached_mob.get_bodypart(BODY_ZONE_CHEST) - chosen_limb.receive_damage(3) + attached_mob.apply_damage(3, BRUTE, chosen_limb, wound_bonus = CANT_WOUND) attached_mob.cause_wound_of_type_and_severity(WOUND_PIERCE, chosen_limb, WOUND_SEVERITY_MODERATE, wound_source = "IV needle") else visible_message(span_warning("[attached_to] is detached from [src].")) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index c3fb9d140549..248159039389 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -7,6 +7,7 @@ desc = "Make dark." power_channel = AREA_USAGE_LIGHT idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.02 + mouse_over_pointer = MOUSE_HAND_POINTER /// Set this to a string, path, or area instance to control that area /// instead of the switch's location. var/area/area = null diff --git a/code/game/machinery/machine_frame.dm b/code/game/machinery/machine_frame.dm index d39d06523242..0f02d2ee3a7e 100644 --- a/code/game/machinery/machine_frame.dm +++ b/code/game/machinery/machine_frame.dm @@ -259,8 +259,7 @@ if(play_sound && !no_sound) replacer.play_rped_sound() - if(replacer.works_from_distance) - user.Beam(src, icon_state = "rped_upgrade", time = 0.5 SECONDS) + return TRUE /obj/structure/frame/machine/can_be_unfasten_wrench(mob/user, silent) diff --git a/code/game/machinery/modular_shield.dm b/code/game/machinery/modular_shield.dm index b4fa6bed17bb..2e8fa632e42b 100644 --- a/code/game/machinery/modular_shield.dm +++ b/code/game/machinery/modular_shield.dm @@ -240,7 +240,7 @@ /obj/machinery/modular_shield_generator/proc/finish_field() for(var/obj/structure/emergency_shield/modular/current_shield in deployed_shields) - current_shield.density = TRUE + current_shield.set_density(TRUE) current_shield.alpha = 255 initiating = FALSE diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 39d6fe7d2ea0..abd481d525d0 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -134,7 +134,7 @@ Buildable meters return ..() /obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from) - p_init_dir = make_from.initialize_directions + p_init_dir = make_from.get_init_directions() setDir(make_from.dir) pipename = make_from.name add_atom_colour(make_from.color, FIXED_COLOUR_PRIORITY) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 32e29a2e5dd0..fd106ce10cdd 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -483,13 +483,17 @@ DEFINE_BITFIELD(turret_flags, list( else if(iscarbon(A)) var/mob/living/carbon/C = A - //If not emagged, only target carbons that can use items - if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || !(C.mobility_flags & MOBILITY_USE))) - continue - - //If emagged, target all but dead carbons - if(mode == TURRET_LETHAL && C.stat == DEAD) - continue + switch(mode) + //If not emagged, only target carbons that can use items + if(TURRET_STUN) + if(!(C.mobility_flags & MOBILITY_USE)) + continue + if(HAS_TRAIT(C, TRAIT_INCAPACITATED)) + continue + //If emagged, target all but dead carbons + if(TURRET_LETHAL) + if(C.stat == DEAD) + continue //if the target is a human and not in our faction, analyze threat level if(ishuman(C) && !in_faction(C)) @@ -726,13 +730,13 @@ DEFINE_BITFIELD(turret_flags, list( remote_controller = null return TRUE -/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/caller, params, atom/A) +/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/clicker, params, atom/A) if(!manual_control) return FALSE - if(!can_interact(caller)) + if(!can_interact(clicker)) remove_control() return FALSE - log_combat(caller,A,"fired with manual turret control at") + log_combat(clicker, A, "fired with manual turret control at") target(A) return TRUE @@ -758,6 +762,7 @@ DEFINE_BITFIELD(turret_flags, list( /obj/machinery/porta_turret/syndicate/Initialize(mapload) . = ..() AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddElement(/datum/element/nav_computer_icon, 'icons/effects/nav_computer_indicators.dmi', "turret", FALSE) /obj/machinery/porta_turret/syndicate/setup() return @@ -840,6 +845,7 @@ DEFINE_BITFIELD(turret_flags, list( return TRUE /obj/machinery/porta_turret/ai + scan_range = /obj/projectile/energy/electrode/ai_turrets::range + 1 turret_flags = TURRET_FLAG_SHOOT_CRIMINALS | TURRET_FLAG_SHOOT_ANOMALOUS | TURRET_FLAG_SHOOT_HEADS /obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 7454f1855115..226e19bfe84f 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -17,6 +17,7 @@ /obj/item/melee/baton/security, /obj/item/ammo_box/magazine/recharge, /obj/item/modular_computer, + /obj/item/gun/ballistic/automatic/battle_rifle, )) /obj/machinery/recharger/RefreshParts() @@ -55,6 +56,11 @@ var/obj/item/ammo_box/magazine/recharge/power_pack = charging . += span_notice("- \The [charging]'s cell is at [PERCENT(power_pack.stored_ammo.len/power_pack.max_ammo)]%.") return + if(istype(charging, /obj/item/gun/ballistic/automatic/battle_rifle)) + var/obj/item/gun/ballistic/automatic/battle_rifle/recalibrating_gun = charging + . += span_notice("- \The [charging]'s system degradation is at stage [recalibrating_gun.degradation_stage] of [recalibrating_gun.degradation_stage_max]%.") + . += span_notice("- \The [charging]'s degradation buffer is at [PERCENT(recalibrating_gun.shots_before_degradation/recalibrating_gun.max_shots_before_degradation)]%.") + return . += span_notice("- \The [charging] is not reporting a power level.") /obj/machinery/recharger/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) @@ -158,6 +164,23 @@ using_power = TRUE update_appearance() return + + if(istype(charging, /obj/item/gun/ballistic/automatic/battle_rifle)) + var/obj/item/gun/ballistic/automatic/battle_rifle/recalibrating_gun = charging + + if(recalibrating_gun.degradation_stage) + recalibrating_gun.attempt_recalibration(FALSE) + use_energy(active_power_usage * recharge_coeff * seconds_per_tick) + using_power = TRUE + + else if(recalibrating_gun.shots_before_degradation < recalibrating_gun.max_shots_before_degradation) + recalibrating_gun.attempt_recalibration(TRUE, 1 * recharge_coeff) + use_energy(active_power_usage * recharge_coeff * seconds_per_tick) + using_power = TRUE + + update_appearance() + return + if(!using_power && !finished_recharging) //Inserted thing is at max charge/ammo, notify those around us finished_recharging = TRUE playsound(src, 'sound/machines/ping.ogg', 30, TRUE) diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 49f00741895f..3e3fc5af3075 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -14,6 +14,9 @@ fair_market_price = 10 payment_department = ACCOUNT_MED interaction_flags_click = ALLOW_SILICON_REACH + use_power = IDLE_POWER_USE + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 3 + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 3 var/stasis_enabled = TRUE var/last_stasis_sound = FALSE var/stasis_can_toggle = 0 @@ -25,6 +28,20 @@ AddElement(/datum/element/elevation, pixel_shift = 6) update_buckle_vars(dir) +/obj/machinery/stasis/RefreshParts() + . = ..() + + var/energy_rating = 0 + for(var/datum/stock_part/part in component_parts) + energy_rating += part.energy_rating() + + for(var/obj/item/stock_parts/part in component_parts) + energy_rating += part.energy_rating + + idle_power_usage = initial(idle_power_usage) / (energy_rating/2) + active_power_usage = initial(active_power_usage) / (energy_rating/2) + update_current_power_usage() + /obj/machinery/stasis/examine(mob/user) . = ..() . += span_notice("Alt-click to [stasis_enabled ? "turn off" : "turn on"] the machine.") diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 9b2e4334581c..bc259d6d4132 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -33,7 +33,7 @@ /obj/machinery/teleport/hub/examine(mob/user) . = ..() if(in_range(user, src) || isobserver(user)) - . += span_notice("The status display reads: Probability of malfunction decreased by [(accuracy*25)-25]%.") + . += span_notice("The status display reads: Success chance is [70 + (accuracy * 10)]%.") /obj/machinery/teleport/hub/proc/link_power_station() if(power_station) diff --git a/code/game/objects/effects/anomalies/_anomalies.dm b/code/game/objects/effects/anomalies/_anomalies.dm index f249d22500c3..035a6e05d904 100644 --- a/code/game/objects/effects/anomalies/_anomalies.dm +++ b/code/game/objects/effects/anomalies/_anomalies.dm @@ -11,10 +11,13 @@ var/obj/item/assembly/signaler/anomaly/anomaly_core = /obj/item/assembly/signaler/anomaly var/area/impact_area + /// How long till we seppuku? Blocked by immortal var/lifespan = ANOMALY_COUNTDOWN_TIMER var/death_time + /// Color of the countdown effect var/countdown_colour + /// Reference to the countdown effect var/obj/effect/countdown/anomaly/countdown /// Do we drop a core when we're neutralized? @@ -129,7 +132,6 @@ to_chat(user, span_notice("Analyzing... [src]'s unstable field is not fluctuating along a stable frequency.")) return ITEM_INTERACT_BLOCKING - ///Stabilize an anomaly, letting it stay around forever or untill destabilizes by a player. An anomaly without a core can't be signalled, but can be destabilized /obj/effect/anomaly/proc/stabilize(anchor = FALSE, has_core = TRUE) immortal = TRUE diff --git a/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm b/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm index d722d90ed117..379143081998 100644 --- a/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm +++ b/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm @@ -3,9 +3,10 @@ name = "bioscrambler anomaly" icon_state = "bioscrambler" anomaly_core = /obj/item/assembly/signaler/anomaly/bioscrambler - immortal = TRUE pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS layer = ABOVE_MOB_LAYER + lifespan = ANOMALY_COUNTDOWN_TIMER * 2 + /// Who are we moving towards? var/datum/weakref/pursuit_target /// Cooldown for every anomaly pulse @@ -80,6 +81,10 @@ /obj/effect/anomaly/bioscrambler/docile/update_target() return +/obj/effect/anomaly/bioscrambler/detonate() + COOLDOWN_RESET(src, pulse_cooldown) + anomalyEffect() + /// Visual effect spawned when the bioscrambler scrambles your bio /obj/effect/temp_visual/circle_wave icon = 'icons/effects/64x64.dmi' diff --git a/code/game/objects/effects/anomalies/anomalies_bluespace.dm b/code/game/objects/effects/anomalies/anomalies_bluespace.dm index cadc0992a630..e8ade1cb9375 100644 --- a/code/game/objects/effects/anomalies/anomalies_bluespace.dm +++ b/code/game/objects/effects/anomalies/anomalies_bluespace.dm @@ -24,6 +24,9 @@ do_teleport(AM, locate(AM.x, AM.y, AM.z), 8, channel = TELEPORT_CHANNEL_BLUESPACE) /obj/effect/anomaly/bluespace/detonate() + new /obj/effect/temp_visual/circle_wave/bluespace(get_turf(src)) + playsound(src, 'sound/effects/magic/cosmic_energy.ogg', vol = 50) + var/turf/T = pick(get_area_turfs(impact_area)) if(!T) return @@ -110,3 +113,8 @@ var/mob/living/living = bumpee living.apply_status_effect(/datum/status_effect/teleport_madness) + +/obj/effect/temp_visual/circle_wave/bluespace + color = COLOR_BLUE_LIGHT + duration = 1 SECONDS + amount_to_scale = 5 diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional.dm b/code/game/objects/effects/anomalies/anomalies_dimensional.dm index 53129c0e9ce3..accbe993ab18 100644 --- a/code/game/objects/effects/anomalies/anomalies_dimensional.dm +++ b/code/game/objects/effects/anomalies/anomalies_dimensional.dm @@ -3,7 +3,7 @@ name = "dimensional anomaly" icon_state = "dimensional" anomaly_core = /obj/item/assembly/signaler/anomaly/dimensional - immortal = TRUE + lifespan = ANOMALY_COUNTDOWN_TIMER * 20 // will generally be killed off by reaching max teleports first move_chance = 0 /// Range of effect, if left alone anomaly will convert a 2(range)+1 squared area. var/range = 3 @@ -13,6 +13,12 @@ var/datum/dimension_theme/theme /// Effect displaying on the anomaly to represent the theme. var/mutable_appearance/theme_icon + /// How many times we can still teleport. Delete self if it hits 0 and we try to teleport. If immortal, will simply stay where it is + var/teleports_left + /// Minimum teleports it will do before going away permanently + var/minimum_teleports = 1 + /// Maximum teleports it will do before going away permanently + var/maximum_teleports = 4 /obj/effect/anomaly/dimensional/Initialize(mapload, new_lifespan, drops_core) . = ..() @@ -21,6 +27,8 @@ animate(src, transform = matrix()*0.85, time = 3, loop = -1) animate(transform = matrix(), time = 3, loop = -1) + teleports_left = rand(minimum_teleports, maximum_teleports) + /obj/effect/anomaly/dimensional/Destroy() theme = null target_turfs = null @@ -37,6 +45,10 @@ if (!theme) prepare_area() if (!target_turfs.len) + if(teleports_left <= 0 && !immortal) + detonate() + return + teleports_left-- relocate() return @@ -80,6 +92,9 @@ src.forceMove(new_turf) prepare_area() +/obj/effect/anomaly/dimensional/detonate() + qdel(src) + /obj/effect/temp_visual/transmute_tile_flash icon = 'icons/effects/effects.dmi' icon_state = "shield-flash" diff --git a/code/game/objects/effects/anomalies/anomalies_gravity.dm b/code/game/objects/effects/anomalies/anomalies_gravity.dm index 82b55542246c..40cdcbcb15e4 100644 --- a/code/game/objects/effects/anomalies/anomalies_gravity.dm +++ b/code/game/objects/effects/anomalies/anomalies_gravity.dm @@ -82,6 +82,10 @@ A.throw_at(target, 5, 1) boing = 0 +/obj/effect/anomaly/grav/detonate() + new /obj/effect/temp_visual/circle_wave/gravity(get_turf(src)) + playsound(src, 'sound/effects/magic/cosmic_energy.ogg', vol = 50) + /obj/effect/anomaly/grav/high var/datum/proximity_monitor/advanced/gravity/grav_field @@ -93,6 +97,7 @@ grav_field = new(src, 7, TRUE, rand(0, 3)) /obj/effect/anomaly/grav/high/detonate() + ..() for(var/obj/machinery/gravity_generator/main/the_generator as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/gravity_generator/main)) if(is_station_level(the_generator.z)) the_generator.blackout() @@ -111,3 +116,6 @@ . = ..() transform *= 3 + +/obj/effect/temp_visual/circle_wave/gravity + color = COLOR_NAVY diff --git a/code/game/objects/effects/anomalies/anomalies_vortex.dm b/code/game/objects/effects/anomalies/anomalies_vortex.dm index 0313f63146b5..4c3a63ae5a64 100644 --- a/code/game/objects/effects/anomalies/anomalies_vortex.dm +++ b/code/game/objects/effects/anomalies/anomalies_vortex.dm @@ -62,3 +62,13 @@ SSexplosions.medturf += T if(EXPLODE_LIGHT) SSexplosions.lowturf += T + +/obj/effect/anomaly/bhole/detonate() + new /obj/effect/temp_visual/circle_wave/vortex(get_turf(src)) + playsound(src, 'sound/effects/hallucinations/far_noise.ogg', vol = 50) + +/obj/effect/temp_visual/circle_wave/vortex + color = COLOR_BLACK + duration = 3 SECONDS + amount_to_scale = 4 + diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 21eff5028b57..14e56b3ed69f 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,6 +1,6 @@ /obj/effect/decal/cleanable gender = PLURAL - layer = FLOOR_CLEAN_LAYER + layer = CLEANABLE_FLOOR_OBJECT_LAYER var/list/random_icon_states = null ///I'm sorry but cleanable/blood code is ass, and so is blood_DNA var/blood_state = "" @@ -15,6 +15,9 @@ var/datum/reagent/decal_reagent ///The amount of reagent this decal holds, if decal_reagent is defined var/reagent_amount = 0 + /// If TRUE, gains TRAIT_MOPABLE on init - thus this cleanable will cleaned if its turf is cleaned + /// Set to FALSE for things that hang high on the walls or things which generally shouldn't be mopped up + var/is_mopped = TRUE /// Creates a cleanable decal on a turf /// Use this if your decal is one of one, and thus we should not spawn it if it's there already @@ -40,6 +43,9 @@ handle_merge_decal(C) return INITIALIZE_HINT_QDEL + if(is_mopped) + ADD_TRAIT(src, TRAIT_MOPABLE, INNATE_TRAIT) + if(LAZYLEN(diseases)) var/list/datum/disease/diseases_to_add = list() for(var/datum/disease/D in diseases) diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index bc7923ac0ed4..f2543f33c867 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -24,10 +24,12 @@ icon = 'icons/effects/blood.dmi' icon_state = "xgib1" plane = GAME_PLANE - layer = BELOW_OBJ_LAYER + layer = GIB_LAYER random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6") mergeable_decal = FALSE + is_mopped = TRUE // probably shouldn't be, but janitor powercreep + /obj/effect/decal/cleanable/xenoblood/xgibs/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_MOVABLE_PIPE_EJECTING, PROC_REF(on_pipe_eject)) diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index fbe1a17cd58f..dd1f02e5b7a3 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -75,6 +75,7 @@ plane = GAME_PLANE vis_flags = VIS_INHERIT_PLANE alpha = 180 + is_mopped = FALSE /obj/effect/decal/cleanable/blood/splatter/over_window/NeverShouldHaveComeHere(turf/here_turf) return isgroundlessturf(here_turf) @@ -111,7 +112,7 @@ desc = "They look bloody and gruesome." icon = 'icons/effects/blood.dmi' icon_state = "gib1" - layer = BELOW_OBJ_LAYER + layer = GIB_LAYER plane = GAME_PLANE random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE @@ -121,6 +122,8 @@ decal_reagent = /datum/reagent/consumable/liquidgibs reagent_amount = 5 + is_mopped = TRUE // probably shouldn't be, but janitor powercreep + /obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases) . = ..() AddElement(/datum/element/squish_sound) @@ -272,9 +275,9 @@ for(var/Ddir in GLOB.cardinals) if(old_entered_dirs & Ddir) - entered_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change) + entered_dirs |= turn_cardinal(Ddir, ang_change) if(old_exited_dirs & Ddir) - exited_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change) + exited_dirs |= turn_cardinal(Ddir, ang_change) update_appearance() return ..() @@ -356,6 +359,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) random_icon_states = list("hitsplatter1", "hitsplatter2", "hitsplatter3") plane = GAME_PLANE layer = ABOVE_WINDOW_LAYER + is_mopped = FALSE /// The turf we just came from, so we can back up when we hit a wall var/turf/prev_loc /// The cached info about the blood diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 4c68e8d9e4e7..aee785b3b7ff 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -11,7 +11,7 @@ icon = 'icons/obj/debris.dmi' icon_state = "ash" plane = GAME_PLANE - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER mergeable_decal = FALSE beauty = -50 decal_reagent = /datum/reagent/ash @@ -154,6 +154,7 @@ resistance_flags = FLAMMABLE beauty = -100 clean_type = CLEAN_TYPE_HARD_DECAL + is_mopped = FALSE /obj/effect/decal/cleanable/cobweb/cobweb2 icon_state = "cobweb2" @@ -165,7 +166,7 @@ icon = 'icons/effects/effects.dmi' icon_state = "molten" plane = GAME_PLANE - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER mergeable_decal = FALSE beauty = -150 clean_type = CLEAN_TYPE_HARD_DECAL @@ -252,7 +253,7 @@ desc = "A pile of chemicals. You can't quite tell what's inside it." gender = NEUTER plane = GAME_PLANE - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER icon = 'icons/obj/debris.dmi' icon_state = "ash" @@ -331,7 +332,7 @@ icon = 'icons/obj/debris.dmi' icon_state = "paper_shreds" plane = GAME_PLANE - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER /obj/effect/decal/cleanable/wrapping/pinata name = "pinata shreds" @@ -350,7 +351,7 @@ icon = 'icons/obj/debris.dmi' icon_state = "garbage" plane = GAME_PLANE - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER beauty = -150 clean_type = CLEAN_TYPE_HARD_DECAL @@ -568,7 +569,9 @@ mergeable_decal = FALSE beauty = -10 plane = GAME_PLANE - layer = BELOW_OBJ_LAYER + layer = GIB_LAYER + clean_type = CLEAN_TYPE_HARD_DECAL + is_mopped = FALSE /obj/effect/decal/cleanable/rubble/Initialize(mapload) . = ..() diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm index 3f2957a9c9e1..7406cd910a1b 100644 --- a/code/game/objects/effects/decals/cleanable/robots.dm +++ b/code/game/objects/effects/decals/cleanable/robots.dm @@ -6,7 +6,7 @@ icon = 'icons/mob/silicon/robots.dmi' icon_state = "gib1" plane = GAME_PLANE - layer = BELOW_OBJ_LAYER + layer = GIB_LAYER random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") blood_state = BLOOD_STATE_OIL bloodiness = BLOOD_AMOUNT_PER_DECAL @@ -14,6 +14,8 @@ beauty = -50 clean_type = CLEAN_TYPE_BLOOD + is_mopped = TRUE // probably shouldn't be, but janitor powercreep + /obj/effect/decal/cleanable/robot_debris/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_MOVABLE_PIPE_EJECTING, PROC_REF(on_pipe_eject)) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index e27e6f91337f..2e60cfb8bda4 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -15,7 +15,7 @@ if(isclosedturf(loc) && loc.density) // allows for wall graffiti to be seen SET_PLANE_IMPLICIT(src, GAME_PLANE) - layer = GAME_CLEAN_LAYER + layer = CLEANABLE_OBJECT_LAYER if(e_name) name = e_name if(desc_override) diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index dc51e5079f4c..bc9f8a0bfd63 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -84,7 +84,7 @@ icon = 'icons/effects/eldritch.dmi' icon_state = "cosmic_carpet" anchored = TRUE - layer = BELOW_OBJ_LAYER + layer = GIB_LAYER density = FALSE can_atmos_pass = ATMOS_PASS_NO initial_duration = 30 SECONDS diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm index f7c07231cf2c..cc4fec358391 100644 --- a/code/game/objects/effects/particles/smoke.dm +++ b/code/game/objects/effects/particles/smoke.dm @@ -107,16 +107,16 @@ "steam_cloud_4" = 1, "steam_cloud_5" = 1, ) - color = "#FFFFFFAA" - count = 6 - spawning = 0.5 + color = "#FFFFFF8A" + count = 5 + spawning = 0.3 lifespan = 3 SECONDS fade = 1.2 SECONDS fadein = 0.4 SECONDS position = generator(GEN_BOX, list(-17,-15,0), list(24,15,0), NORMAL_RAND) scale = generator(GEN_VECTOR, list(0.9,0.9), list(1.1,1.1), NORMAL_RAND) drift = generator(GEN_SPHERE, list(-0.01,0), list(0.01,0.01), UNIFORM_RAND) - spin = generator(GEN_NUM, list(-3,3), NORMAL_RAND) + spin = generator(GEN_NUM, list(-2,2), NORMAL_RAND) gravity = list(0.05, 0.28) friction = 0.3 grow = 0.037 diff --git a/code/game/objects/effects/spawners/random/trash.dm b/code/game/objects/effects/spawners/random/trash.dm index 6f6f5badc8e7..a6d9bfcc45af 100644 --- a/code/game/objects/effects/spawners/random/trash.dm +++ b/code/game/objects/effects/spawners/random/trash.dm @@ -53,6 +53,12 @@ /obj/effect/spawner/random/entertainment/cigar = 1, /obj/item/stack/ore/gold = 1, ) +/obj/effect/spawner/random/trash/deluxe_garbage/Initialize(mapload) + if(mapload) + var/turf/location = get_turf(loc) + if(location.initial_gas_mix != OPENTURF_DEFAULT_ATMOS && location.initial_gas_mix != OPENTURF_DIRTY_ATMOS) + loot -= /mob/living/basic/mouse + return ..() /obj/effect/spawner/random/trash/cigbutt name = "cigarette butt spawner" diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 38e3494b6bb8..d8ce033804a4 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -444,8 +444,7 @@ var/size_matrix = matrix() if(size_calc_target) layer = size_calc_target.layer + 0.01 - var/icon/I = icon(size_calc_target.icon, size_calc_target.icon_state, size_calc_target.dir) - size_matrix = matrix() * (I.Height()/ICON_SIZE_Y) + size_matrix = matrix() * (size_calc_target.get_visual_height() / ICON_SIZE_Y) transform = size_matrix //scale the bleed overlay's size based on the target's icon size var/matrix/M = transform if(shrink) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index dcd4303c4e63..94918ca079f2 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -22,6 +22,9 @@ ///Icon file for right inhand overlays var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' + /// Angle of the icon, used for piercing and slashing attack animations, clockwise from *east-facing* sprites + var/icon_angle = 0 + ///Icon file for mob worn overlays. var/icon/worn_icon ///Icon state for mob worn overlays, if null the normal icon_state will be used. @@ -184,7 +187,7 @@ ///for flags such as [GLASSESCOVERSEYES] var/flags_cover = 0 var/heat = 0 - ///All items with sharpness of SHARP_EDGED or higher will automatically get the butchering component. + /// All items with sharpness of SHARP_EDGED or higher will automatically get the butchering component. var/sharpness = NONE ///How a tool acts when you use it on something, such as wirecutters cutting wires while multitools measure power @@ -791,7 +794,7 @@ if(equip_sound && (slot_flags & slot)) playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE) else if(slot & ITEM_SLOT_HANDS) - playsound(src, pickup_sound, PICKUP_SOUND_VOLUME, ignore_walls = FALSE) + playsound(src, pickup_sound, PICKUP_SOUND_VOLUME, sound_vary, ignore_walls = FALSE) user.update_equipment_speed_mods() /// Gives one of our item actions to a mob, when equipped to a certain slot @@ -1698,44 +1701,162 @@ // This is instant on byond's end, but to our clients this looks like a quick drop animate(src, alpha = old_alpha, pixel_x = old_x, pixel_y = old_y, transform = old_transform, time = 3, easing = CUBIC_EASING) -/atom/movable/proc/do_item_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item) - var/image/attack_image - if(visual_effect_icon) - attack_image = image(icon = 'icons/effects/effects.dmi', icon_state = visual_effect_icon) - else if(used_item) - attack_image = image(icon = used_item) +/atom/movable/proc/do_item_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item, animation_type = ATTACK_ANIMATION_BLUNT) + if (visual_effect_icon) + var/image/attack_image = image(icon = 'icons/effects/effects.dmi', icon_state = visual_effect_icon) attack_image.plane = attacked_atom.plane + 1 - // Scale the icon. attack_image.transform *= 0.4 // The icon should not rotate. attack_image.appearance_flags = APPEARANCE_UI + var/atom/movable/flick_visual/attack = attacked_atom.flick_overlay_view(attack_image, 1 SECONDS) + var/matrix/copy_transform = new(transform) + animate(attack, alpha = 175, transform = copy_transform.Scale(0.75), time = 0.3 SECONDS) + animate(time = 0.1 SECONDS) + animate(alpha = 0, time = 0.3 SECONDS, easing = CIRCULAR_EASING|EASE_OUT) + return - // Set the direction of the icon animation. - var/direction = get_dir(src, attacked_atom) - if(direction & NORTH) - attack_image.pixel_y = -12 - else if(direction & SOUTH) - attack_image.pixel_y = 12 - - if(direction & EAST) - attack_image.pixel_x = -14 - else if(direction & WEST) - attack_image.pixel_x = 14 - - if(!direction) // Attacked self?! - attack_image.pixel_y = 12 - attack_image.pixel_x = 5 * (prob(50) ? 1 : -1) - - if(!attack_image) + if (isnull(used_item)) return + var/image/attack_image = image(icon = used_item) + attack_image.plane = attacked_atom.plane + 1 + // Scale the icon. + attack_image.transform *= 0.5 + // The icon should not rotate. + attack_image.appearance_flags = APPEARANCE_UI + var/atom/movable/flick_visual/attack = attacked_atom.flick_overlay_view(attack_image, 1 SECONDS) var/matrix/copy_transform = new(transform) + var/x_sign = 0 + var/y_sign = 0 + var/direction = get_dir(src, attacked_atom) + if (direction & NORTH) + y_sign = -1 + else if (direction & SOUTH) + y_sign = 1 + + if (direction & EAST) + x_sign = -1 + else if (direction & WEST) + x_sign = 1 + + // Attacking self, or something on the same turf as us + if (!direction) + y_sign = 1 + // Not a fan of this, but its the "cleanest" way to animate this + x_sign = 0.25 * (prob(50) ? 1 : -1) + // For piercing attacks + direction = SOUTH + // And animate the attack! - animate(attack, alpha = 175, transform = copy_transform.Scale(0.75), pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 0.3 SECONDS) - animate(time = 0.1 SECONDS) - animate(alpha = 0, time = 0.3 SECONDS, easing = CIRCULAR_EASING|EASE_OUT) + switch (animation_type) + if (ATTACK_ANIMATION_BLUNT) + attack.pixel_x = 14 * x_sign + attack.pixel_y = 12 * y_sign + animate(attack, alpha = 175, transform = copy_transform.Scale(0.75), pixel_x = 4 * x_sign, pixel_y = 3 * y_sign, time = 0.2 SECONDS) + animate(time = 0.1 SECONDS) + animate(alpha = 0, time = 0.1 SECONDS, easing = CIRCULAR_EASING|EASE_OUT) + + if (ATTACK_ANIMATION_PIERCE) + var/attack_angle = dir2angle(direction) + rand(-7, 7) + // Deducting 90 because we're assuming that icon_angle of 0 means an east-facing sprite + var/anim_angle = attack_angle - 90 - used_item.icon_angle + var/angle_mult = 1 + if (x_sign && y_sign) + angle_mult = 1.4 + attack.pixel_x = 22 * x_sign * angle_mult + attack.pixel_y = 18 * y_sign * angle_mult + attack.transform = attack.transform.Turn(anim_angle) + copy_transform = copy_transform.Turn(anim_angle) + animate( + attack, + pixel_x = (22 * x_sign - 12 * sin(attack_angle)) * angle_mult, + pixel_y = (18 * y_sign - 8 * cos(attack_angle)) * angle_mult, + time = 0.1 SECONDS, + easing = CUBIC_EASING|EASE_IN, + ) + animate( + attack, + alpha = 175, + transform = copy_transform.Scale(0.75), + pixel_x = (22 * x_sign + 26 * sin(attack_angle)) * angle_mult, + pixel_y = (18 * y_sign + 22 * cos(attack_angle)) * angle_mult, + time = 0.3 SECONDS, + easing = CUBIC_EASING|EASE_OUT, + ) + animate( + alpha = 0, + pixel_x = -3 * -(x_sign + sin(attack_angle)), + pixel_y = -2 * -(y_sign + cos(attack_angle)), + time = 0.1 SECONDS, + easing = CIRCULAR_EASING|EASE_OUT + ) + + if (ATTACK_ANIMATION_SLASH) + attack.pixel_x = 18 * x_sign + attack.pixel_y = 14 * y_sign + var/x_rot_sign = 0 + var/y_rot_sign = 0 + var/attack_dir = (prob(50) ? 1 : -1) + var/anim_angle = dir2angle(direction) - 90 - used_item.icon_angle + + if (x_sign) + y_rot_sign = attack_dir + if (y_sign) + x_rot_sign = attack_dir + + // Animations are flipped, so flip us too! + if (x_sign > 0 || y_sign < 0) + attack_dir *= -1 + + // We're swinging diagonally, use separate logic + var/anim_dir = attack_dir + if (x_sign && y_sign) + if (attack_dir < 0) + x_rot_sign = -x_sign * 1.4 + y_rot_sign = 0 + else + x_rot_sign = 0 + y_rot_sign = -y_sign * 1.4 + + // Flip us if we've been flipped *unless* we're flipped due to both axis + if ((x_sign < 0 && y_sign > 0) || (x_sign > 0 && y_sign < 0)) + anim_dir *= -1 + + attack.pixel_x += 10 * x_rot_sign + attack.pixel_y += 8 * y_rot_sign + attack.transform = attack.transform.Turn(anim_angle - 45 * anim_dir) + copy_transform = copy_transform.Scale(0.75) + animate(attack, alpha = 175, time = 0.3 SECONDS, flags = ANIMATION_PARALLEL) + animate(time = 0.1 SECONDS) + animate(alpha = 0, time = 0.1 SECONDS, easing = CIRCULAR_EASING|EASE_OUT) + + animate(attack, transform = copy_transform.Turn(anim_angle + 45 * anim_dir), time = 0.3 SECONDS, flags = ANIMATION_PARALLEL) + + var/x_return = 10 * -x_rot_sign + var/y_return = 8 * -y_rot_sign + + if (!x_rot_sign) + x_return = 18 * x_sign + if (!y_rot_sign) + y_return = 14 * y_sign + + var/angle_mult = 1 + if (x_sign && y_sign) + angle_mult = 1.4 + if (attack_dir > 0) + x_return = 8 * x_sign + y_return = 14 * y_sign + else + x_return = 18 * x_sign + y_return = 6 * y_sign + + animate(attack, pixel_x = 4 * x_sign * angle_mult, time = 0.2 SECONDS, easing = CIRCULAR_EASING | EASE_IN, flags = ANIMATION_PARALLEL) + animate(pixel_x = x_return, time = 0.2 SECONDS, easing = CIRCULAR_EASING | EASE_OUT) + + animate(attack, pixel_y = 3 * y_sign * angle_mult, time = 0.2 SECONDS, easing = CIRCULAR_EASING | EASE_IN, flags = ANIMATION_PARALLEL) + animate(pixel_y = y_return, time = 0.2 SECONDS, easing = CIRCULAR_EASING | EASE_OUT) /// Common proc used by painting tools like spraycans and palettes that can access the entire 24 bits color space. /obj/item/proc/pick_painting_tool_color(mob/user, default_color) @@ -2026,9 +2147,9 @@ . = ..() . += {"
- DAMTYPE: [uppertext(damtype)] - FORCE: [force] - WOUND: [wound_bonus] - BARE WOUND: [bare_wound_bonus] + DAMTYPE: [uppertext(damtype)] + FORCE: [force] + WOUND: [wound_bonus] + BARE WOUND: [bare_wound_bonus] "} diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index a0a1e0bd3f41..23c3c894e428 100644 --- a/code/game/objects/items/AI_modules/_AI_modules.dm +++ b/code/game/objects/items/AI_modules/_AI_modules.dm @@ -36,7 +36,7 @@ /obj/item/ai_module/attack_self(mob/user as mob) ..() - to_chat(user, examine_block(display_laws())) + to_chat(user, boxed_message(display_laws())) /// Returns a text display of the laws for the module. /obj/item/ai_module/proc/display_laws() diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index d11c6e21d698..a1f0001f651f 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -239,10 +239,11 @@ /obj/item/blueprints/slime/edit_area(mob/user) . = ..() var/area/area = get_area(src) + var/list/turf_matrix = color_transition_filter("#2956B2") for(var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) for(var/turf/area_turf as anything in zlevel_turfs) area_turf.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - area_turf.add_atom_colour("#2956B2", FIXED_COLOUR_PRIORITY) + area_turf.add_atom_colour(turf_matrix, FIXED_COLOUR_PRIORITY) area.area_flags |= XENOBIOLOGY_COMPATIBLE qdel(src) diff --git a/code/game/objects/items/boxcutter.dm b/code/game/objects/items/boxcutter.dm index 58be269bacdd..5452cd013fb8 100644 --- a/code/game/objects/items/boxcutter.dm +++ b/code/game/objects/items/boxcutter.dm @@ -5,6 +5,7 @@ icon_state = "boxcutter" inhand_icon_state = "boxcutter" base_icon_state = "boxcutter" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/equipment/boxcutter_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/boxcutter_righthand.dmi' inhand_icon_state = null diff --git a/code/game/objects/items/broom.dm b/code/game/objects/items/broom.dm index 32636b1a99c8..a48dfa1b94c1 100644 --- a/code/game/objects/items/broom.dm +++ b/code/game/objects/items/broom.dm @@ -7,6 +7,7 @@ icon = 'icons/obj/service/janitor.dmi' icon_state = "broom0" base_icon_state = "broom" + icon_angle = 135 lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 8 diff --git a/code/game/objects/items/chainsaw.dm b/code/game/objects/items/chainsaw.dm index 8045646b075c..509a3a638560 100644 --- a/code/game/objects/items/chainsaw.dm +++ b/code/game/objects/items/chainsaw.dm @@ -5,6 +5,7 @@ desc = "A versatile power tool. Useful for limbing trees and delimbing humans." icon = 'icons/obj/weapons/chainsaw.dmi' icon_state = "chainsaw" + icon_angle = 180 lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/charter.dm index 6b4ae0f91839..6f8ad945621e 100644 --- a/code/game/objects/items/charter.dm +++ b/code/game/objects/items/charter.dm @@ -57,7 +57,9 @@ to_chat(user, span_notice("Your name has been sent to your employers for approval.")) // Autoapproves after a certain time response_timer_id = addtimer(CALLBACK(src, PROC_REF(rename_station), new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE) - to_chat(GLOB.admins, span_adminnotice("CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]")) + to_chat(GLOB.admins, + span_adminnotice("CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [DisplayTimeText(approval_time)]). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]"), + type = MESSAGE_TYPE_PRAYER) for(var/client/admin_client in GLOB.admins) if(admin_client.prefs.toggles & SOUND_ADMINHELP) window_flash(admin_client, ignorepref = TRUE) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index bbf91b6243bd..59f3cecdc2ae 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1472,6 +1472,16 @@ /datum/stock_part/scanning_module = 1, /datum/stock_part/card_reader = 1) +/obj/item/circuitboard/machine/mailsorter + name = "Mail Sorter" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/mailsorter + req_components = list( + /obj/item/stack/sheet/glass = 1, + /datum/stock_part/matter_bin = 2, + /datum/stock_part/scanning_module = 1) + needs_anchored = TRUE + //Tram /obj/item/circuitboard/machine/crossing_signal name = "Crossing Signal" diff --git a/code/game/objects/items/courtroom.dm b/code/game/objects/items/courtroom.dm index 8baba2843143..c8907cbe9366 100644 --- a/code/game/objects/items/courtroom.dm +++ b/code/game/objects/items/courtroom.dm @@ -7,6 +7,7 @@ desc = "Order, order! No bombs in my courthouse." icon = 'icons/obj/weapons/hammer.dmi' icon_state = "gavelhammer" + icon_angle = -135 force = 5 throwforce = 6 w_class = WEIGHT_CLASS_SMALL diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 0338acdddd22..838c60e7f15e 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -202,7 +202,7 @@ /obj/item/toy/crayon/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!")) - user.add_atom_colour(paint_color, ADMIN_COLOUR_PRIORITY) + user.add_atom_colour(color_transition_filter(paint_color, SATURATION_OVERRIDE), ADMIN_COLOUR_PRIORITY) return (BRUTELOSS|OXYLOSS) /obj/item/toy/crayon/Initialize(mapload) @@ -435,7 +435,7 @@ if(!isValidSurface(target)) target.balloon_alert(user, "can't use there!") - return + return ITEM_INTERACT_BLOCKING var/drawing = drawtype switch(drawtype) @@ -471,7 +471,7 @@ if (istagger) cost *= 0.5 if(check_empty(user, cost)) - return + return ITEM_INTERACT_BLOCKING var/temp = "rune" var/ascii = (length(drawing) == 1) @@ -521,10 +521,10 @@ wait_time *= 0.5 if(!instant && !do_after(user, wait_time, target = target, max_interact_count = 4)) - return + return ITEM_INTERACT_BLOCKING if(!use_charges(user, cost)) - return + return ITEM_INTERACT_BLOCKING if(length(text_buffer)) drawing = text_buffer[1] @@ -548,7 +548,7 @@ affected_turfs += right else balloon_alert(user, "no room!") - return + return ITEM_INTERACT_BLOCKING created_art.add_hiddenprint(user) if(istagger) created_art.AddElement(/datum/element/art, GOOD_ART) @@ -575,15 +575,14 @@ for(var/turf/draw_turf as anything in affected_turfs) reagents.expose(draw_turf, methods = TOUCH, volume_modifier = volume_multiplier) check_empty(user) - return + return ITEM_INTERACT_SUCCESS /obj/item/toy/crayon/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if (!check_allowed_items(interacting_with)) return NONE if(can_use_on(interacting_with, user, modifiers)) - use_on(interacting_with, user, modifiers) - return ITEM_INTERACT_BLOCKING + return use_on(interacting_with, user, modifiers) return NONE /obj/item/toy/crayon/get_writing_implement_details() @@ -790,6 +789,12 @@ post_noise = FALSE interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING + /// Types which use their color var for additional logic, so we need to avoid using transition filters on them. + var/static/list/direct_color_types = typecacheof(list( + /obj/item/paper, // Uses color for TGUI backgrounds, doesn't look very good either + /obj/item/fish, // Used for aquarium sprites + )) + /obj/item/toy/crayon/spraycan/Initialize(mapload) . = ..() var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/improvised_coolant) @@ -819,13 +824,12 @@ return . context[SCREENTIP_CONTEXT_LMB] = "Paint" + context[SCREENTIP_CONTEXT_RMB] = "Coat with paint" if(isbodypart(target)) var/obj/item/bodypart/limb = target if(IS_ROBOTIC_LIMB(limb)) - context[SCREENTIP_CONTEXT_RMB] = "Restyle robotic limb" - else - context[SCREENTIP_CONTEXT_RMB] = "Copy color" + context[SCREENTIP_CONTEXT_LMB] = "Restyle robotic limb" return CONTEXTUAL_SCREENTIP_SET @@ -883,10 +887,14 @@ /obj/item/toy/crayon/spraycan/use_on(atom/target, mob/user, list/modifiers) if(is_capped) balloon_alert(user, "take the cap off first!") - return + return ITEM_INTERACT_BLOCKING if(check_empty(user)) - return + return ITEM_INTERACT_BLOCKING + + if (isbodypart(target)) + if (color_limb(target, user)) + return ITEM_INTERACT_SUCCESS if(iscarbon(target)) if(pre_noise || post_noise) @@ -912,11 +920,15 @@ else if(actually_paints && target.is_atom_colour(paint_color, min_priority_index = WASHABLE_COLOUR_PRIORITY)) balloon_alert(user, "[target.p_theyre()] already that color!") - return + return ITEM_INTERACT_BLOCKING + + var/saturation_mode = SATURATION_MULTIPLY + if (LAZYACCESS(modifiers, RIGHT_CLICK)) + saturation_mode = SATURATION_OVERRIDE if(ismob(target) && (HAS_TRAIT(target, TRAIT_SPRAY_PAINTABLE))) if(actually_paints) - target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY) + target.add_atom_colour(color_transition_filter(paint_color, saturation_mode), WASHABLE_COLOUR_PRIORITY) SEND_SIGNAL(target, COMSIG_LIVING_MOB_PAINTED) use_charges(user, 2, requires_full = FALSE) reagents.trans_to(target, ., volume_multiplier, transferred_by = user, methods = VAPOR) @@ -924,45 +936,13 @@ if(pre_noise || post_noise) playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5) user.visible_message(span_notice("[user] coats [target] with spray paint!"), span_notice("You coat [target] with spray paint.")) - return + return ITEM_INTERACT_SUCCESS - if(isobj(target) && !(target.flags_1 & UNPAINTABLE_1)) - var/color_is_dark = FALSE - if(actually_paints) - color_is_dark = is_color_dark(paint_color) - - if (color_is_dark && !(target.flags_1 & ALLOW_DARK_PAINTS_1)) - to_chat(user, span_warning("A color that dark on an object like this? Surely not...")) - return - - if(istype(target, /obj/item/pipe)) - if(GLOB.pipe_color_name.Find(paint_color)) - var/obj/item/pipe/target_pipe = target - target_pipe.pipe_color = paint_color - target.add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) - balloon_alert(user, "painted in [GLOB.pipe_color_name[paint_color]] color") - else - balloon_alert(user, "invalid pipe color!") - return - else if(istype(target, /obj/machinery/atmospherics)) - if(GLOB.pipe_color_name.Find(paint_color)) - var/obj/machinery/atmospherics/target_pipe = target - target_pipe.paint(paint_color) - balloon_alert(user, "painted in [GLOB.pipe_color_name[paint_color]] color") - else - balloon_alert(user, "invalid pipe color!") - return - else - target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY) - - if(isitem(target) && isliving(target.loc)) - var/obj/item/target_item = target - var/mob/living/holder = target.loc - if(holder.is_holding(target_item)) - holder.update_held_items() - else - holder.update_clothing(target_item.slot_flags) + if(!isobj(target) || (target.flags_1 & UNPAINTABLE_1)) + return ..() + var/color_is_dark = is_color_dark(paint_color) + if(!actually_paints) if(!(SEND_SIGNAL(target, COMSIG_OBJ_PAINTED, user, src, color_is_dark) & DONT_USE_SPRAYCAN_CHARGES)) use_charges(user, 2, requires_full = FALSE) reagents.trans_to(target, ., volume_multiplier, transferred_by = user, methods = VAPOR) @@ -970,43 +950,73 @@ if(pre_noise || post_noise) playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5) user.visible_message(span_notice("[user] coats [target] with spray paint!"), span_notice("You coat [target] with spray paint.")) - return - - return ..() + return ITEM_INTERACT_SUCCESS -/obj/item/toy/crayon/spraycan/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) - if(is_capped) - if(!interacting_with.color) - // let's be generous and assume if they're trying to match something with no color, while capped, - // we shouldn't be blocking further interactions - return NONE - balloon_alert(user, "take the cap off first!") - return ITEM_INTERACT_BLOCKING - if(check_empty(user)) + if (color_is_dark && saturation_mode == SATURATION_OVERRIDE && !(target.flags_1 & ALLOW_DARK_PAINTS_1)) + to_chat(user, span_warning("A color that dark on an object like this? Surely not...")) return ITEM_INTERACT_BLOCKING - if(isbodypart(interacting_with) && actually_paints) - var/obj/item/bodypart/limb = interacting_with - if(IS_ROBOTIC_LIMB(limb)) - var/list/skins = list() - var/static/list/style_list_icons = GLOB.robotic_styles_list //NOVA EDIT CHANGE - Original: var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', "security" = 'icons/mob/augmentation/augments_security.dmi', "mining" = 'icons/mob/augmentation/augments_mining.dmi') - for(var/skin_option in style_list_icons) - var/image/part_image = image(icon = style_list_icons[skin_option], icon_state = "[limb.limb_id]_[limb.body_zone]") - if(limb.aux_zone) //Hands - part_image.overlays += image(icon = style_list_icons[skin_option], icon_state = "[limb.limb_id]_[limb.aux_zone]") - skins += list("[skin_option]" = part_image) - var/choice = show_radial_menu(user, src, skins, require_near = TRUE, radius = 48) //NOVA EDIT CHANGE - Increases the radius. Default is 32. - if(choice && (use_charges(user, 5, requires_full = FALSE))) - playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5) - limb.change_appearance(style_list_icons[choice], greyscale = FALSE) - return ITEM_INTERACT_SUCCESS - if(interacting_with.color) - paint_color = interacting_with.color - balloon_alert(user, "matched colour of target") - update_appearance() - return ITEM_INTERACT_BLOCKING - balloon_alert(user, "can't match those colours!") - return ITEM_INTERACT_BLOCKING + if(istype(target, /obj/item/pipe)) + if(!GLOB.pipe_color_name.Find(paint_color)) + balloon_alert(user, "invalid pipe color!") + return ITEM_INTERACT_BLOCKING + var/obj/item/pipe/target_pipe = target + target_pipe.pipe_color = paint_color + target.add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) + balloon_alert(user, "painted in [GLOB.pipe_color_name[paint_color]] color") + else if(istype(target, /obj/machinery/atmospherics)) + if(!GLOB.pipe_color_name.Find(paint_color)) + balloon_alert(user, "invalid pipe color!") + return ITEM_INTERACT_BLOCKING + var/obj/machinery/atmospherics/target_pipe = target + target_pipe.paint(paint_color) + balloon_alert(user, "painted in [GLOB.pipe_color_name[paint_color]] color") + else if (is_type_in_typecache(target, direct_color_types)) + target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY) + else + target.add_atom_colour(color_transition_filter(paint_color, saturation_mode), WASHABLE_COLOUR_PRIORITY) + + if(isitem(target) && isliving(target.loc)) + var/obj/item/target_item = target + var/mob/living/holder = target.loc + if(holder.is_holding(target_item)) + holder.update_held_items() + else + holder.update_clothing(target_item.slot_flags) + + if(!(SEND_SIGNAL(target, COMSIG_OBJ_PAINTED, user, src, color_is_dark) & DONT_USE_SPRAYCAN_CHARGES)) + use_charges(user, 2, requires_full = FALSE) + reagents.trans_to(target, ., volume_multiplier, transferred_by = user, methods = VAPOR) + + if(pre_noise || post_noise) + playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5) + user.visible_message(span_notice("[user] coats [target] with spray paint!"), span_notice("You coat [target] with spray paint.")) + return ITEM_INTERACT_SUCCESS + +/obj/item/toy/crayon/spraycan/proc/color_limb(obj/item/bodypart/limb, mob/living/user) + if(!IS_ROBOTIC_LIMB(limb)) + return FALSE + + var/list/skins = list() + /* var/static/list/style_list_icons = list( // NOVA EDIT REMOVAL START + "standard" = 'icons/mob/augmentation/augments.dmi', + "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', + "security" = 'icons/mob/augmentation/augments_security.dmi', + "mining" = 'icons/mob/augmentation/augments_mining.dmi', + ) + */ // NOVA EDIT REMOVAL END + var/static/list/style_list_icons = GLOB.robotic_styles_list //NOVA EDIT ADDITION + + for(var/skin_option in style_list_icons) + var/image/part_image = image(icon = style_list_icons[skin_option], icon_state = "[limb.limb_id]_[limb.body_zone]") + if(limb.aux_zone) //Hands + part_image.overlays += image(icon = style_list_icons[skin_option], icon_state = "[limb.limb_id]_[limb.aux_zone]") + skins += list("[skin_option]" = part_image) + var/choice = show_radial_menu(user, src, skins, require_near = TRUE) + if(choice && (use_charges(user, 5, requires_full = FALSE))) + playsound(user.loc, 'sound/effects/spray.ogg', 5, TRUE, 5) + limb.change_appearance(style_list_icons[choice], greyscale = FALSE) + return TRUE /obj/item/toy/crayon/spraycan/click_alt(mob/user) if(!has_cap) diff --git a/code/game/objects/items/debug_items.dm b/code/game/objects/items/debug_items.dm index fb6400fc7b36..9af69c33d7fa 100644 --- a/code/game/objects/items/debug_items.dm +++ b/code/game/objects/items/debug_items.dm @@ -34,6 +34,7 @@ icon = 'icons/obj/weapons/club.dmi' icon_state = "hypertool" inhand_icon_state = "hypertool" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' toolspeed = 0.1 diff --git a/code/game/objects/items/devices/broadcast_camera.dm b/code/game/objects/items/devices/broadcast_camera.dm index 40f8fe0a8715..1a7ba3ed1c4c 100644 --- a/code/game/objects/items/devices/broadcast_camera.dm +++ b/code/game/objects/items/devices/broadcast_camera.dm @@ -41,11 +41,10 @@ /obj/item/broadcast_camera/Destroy(force) QDEL_NULL(internal_radio) QDEL_NULL(internal_camera) - return ..() /obj/item/broadcast_camera/update_icon_state() - icon_state = "[base_icon_state]0" + icon_state = "[base_icon_state][active]" return ..() /obj/item/broadcast_camera/attack_self(mob/user, modifiers) @@ -80,7 +79,7 @@ if(!iscarbon(loc)) return active = TRUE - icon_state = "[base_icon_state][active]" + update_icon_state() /// The carbon who wielded the camera, allegedly var/mob/living/carbon/wielding_carbon = loc @@ -103,7 +102,7 @@ /// When deactivating the camera /obj/item/broadcast_camera/proc/on_deactivating() active = FALSE - icon_state = "[base_icon_state][active]" + update_icon_state() QDEL_NULL(internal_camera) QDEL_NULL(internal_radio) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 94b7e14fe80f..943896f29f4b 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -267,7 +267,7 @@ if(length(render_list)) //display our packaged information in an examine block for easy reading - to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) + to_chat(user, boxed_message(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) return ITEM_INTERACT_SUCCESS return ITEM_INTERACT_BLOCKING diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index fe3914171831..4a0fee53f96a 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -16,6 +16,7 @@ icon = 'icons/obj/devices/tool.dmi' icon_state = "multitool" inhand_icon_state = "multitool" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' force = 5 @@ -294,6 +295,7 @@ desc = "Optimised version of a regular multitool. Streamlines processes handled by its internal microchip." icon = 'icons/obj/items_cyborg.dmi' icon_state = "toolkit_engiborg_multitool" + icon_angle = 0 toolspeed = 0.5 #undef PROXIMITY_NEAR diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 364550f062aa..c6aa10784eee 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -151,7 +151,7 @@ air_update_turf(FALSE, FALSE) if(warning_given && internal_heat < max_heat * 0.75) warning_given = FALSE - message_admins("Power sink at ([x],[y],[z] - JMP) has cooled down and will not explode.") + message_admins("Power sink at ([x],[y],[z] - JMP) has cooled down and will not explode.") if(mode != OPERATING && internal_heat < MINIMUM_HEAT) internal_heat = 0 STOP_PROCESSING(SSobj, src) @@ -188,7 +188,7 @@ if(internal_heat > max_heat * ALERT / 100) if (!warning_given) warning_given = TRUE - message_admins("Power sink at ([x],[y],[z] - JMP) has reached [ALERT]% of max heat. Explosion imminent.") + message_admins("Power sink at ([x],[y],[z] - JMP) has reached [ALERT]% of max heat. Explosion imminent.") notify_ghosts( "[src] is about to reach critical heat capacity!", source = src, diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 0d57ce78e64a..4cb03972de8c 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -120,6 +120,8 @@ if(type != /obj/item/radio) return AddElement(/datum/element/slapcrafting, string_list(list(/datum/crafting_recipe/improv_explosive))) + if(prob(check_holidays(APRIL_FOOLS) ? 50 : 0.5)) // Extremely rare chance to replace a normal radio with a toy one, because it's funny + make_silly() /obj/item/radio/Destroy() remove_radio_all(src) //Just to be sure @@ -578,6 +580,15 @@ set_on(TRUE) return TRUE +/obj/item/radio/proc/make_silly() + name = "\improper Little-Crew: Assistant's First Radio" + icon_state = "walkieian" + desc = "A Little-Crew branded toy radio in the shape of a lovable pet. After Little-Crew HQ was hit with a Donksoft Nuke, these have become collector's items!" + overlay_speaker_idle = null + overlay_speaker_active = null + overlay_mic_idle = null + overlay_mic_active = null + /////////////////////////////// //////////Borg Radios////////// /////////////////////////////// @@ -706,4 +717,9 @@ inhand_icon_state = "microphone" canhear_range = 3 +// In case you want to map it in/spawn it for some reason +/obj/item/radio/toy/Initialize(mapload) + . = ..() + make_silly() + #undef FREQ_LISTENING diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index c209454e92fa..aca694c9e4b5 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -220,7 +220,7 @@ message += span_notice("Volume: [volume] L") // don't want to change the order volume appears in, suck it // we let the join apply newlines so we do need handholding - to_chat(user, examine_block(jointext(message, "\n")), type = MESSAGE_TYPE_INFO) + to_chat(user, boxed_message(jointext(message, "\n")), type = MESSAGE_TYPE_INFO) return TRUE /obj/item/analyzer/ranged diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index cd21a8f45d23..6f8f22f0f39b 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -81,7 +81,7 @@ floor_text += "Body temperature: [scan_turf?.return_air()?.return_temperature() || "???"]
" if(user.can_read(src) && !user.is_blind()) - to_chat(user, examine_block(floor_text)) + to_chat(user, custom_boxed_message("blue_box", floor_text)) last_scan_text = floor_text return @@ -428,7 +428,7 @@ . = jointext(render_list, "") if(tochat) - to_chat(user, examine_block(.), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", .), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) return . /obj/item/healthanalyzer/click_ctrl_shift(mob/user) @@ -525,7 +525,7 @@ render_list += "[allergies]
" // we handled the last
so we don't need handholding - to_chat(user, examine_block(jointext(render_list, "")), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", jointext(render_list, "")), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) /obj/item/healthanalyzer/click_alt(mob/user) if(mode == SCANNER_NO_MODE) @@ -576,7 +576,7 @@ simple_scanner.show_emotion(AID_EMOTION_HAPPY) to_chat(user, "No wounds detected in subject.") else - to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) + to_chat(user, custom_boxed_message("blue_box", jointext(render_list, "")), type = MESSAGE_TYPE_INFO) if(simple_scan) var/obj/item/healthanalyzer/simple/simple_scanner = scanner simple_scanner.show_emotion(AID_EMOTION_WARN) diff --git a/code/game/objects/items/devices/scanners/scanner_wand.dm b/code/game/objects/items/devices/scanners/scanner_wand.dm index 18dfc8200398..bba046bd2fec 100644 --- a/code/game/objects/items/devices/scanners/scanner_wand.dm +++ b/code/game/objects/items/devices/scanners/scanner_wand.dm @@ -3,6 +3,7 @@ icon = 'icons/obj/devices/scanner.dmi' icon_state = "scanner_wand" inhand_icon_state = "healthanalyzer" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' desc = "A wand that medically scans people. Inserting it into a medical kiosk makes it able to perform a health scan on the patient." diff --git a/code/game/objects/items/devices/scanners/slime_scanner.dm b/code/game/objects/items/devices/scanners/slime_scanner.dm index c730783882e6..c1d4b26d3c18 100644 --- a/code/game/objects/items/devices/scanners/slime_scanner.dm +++ b/code/game/objects/items/devices/scanners/slime_scanner.dm @@ -57,4 +57,4 @@ to_render += "\n[span_notice("Core mutation in progress: [scanned_slime.crossbreed_modification]")]\ \n[span_notice("Progress in core mutation: [scanned_slime.applied_crossbreed_amount] / [SLIME_EXTRACT_CROSSING_REQUIRED]")]" - to_chat(user, examine_block(jointext(to_render,""))) + to_chat(user, boxed_message(jointext(to_render,""))) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index d8b7c1999aea..341231d767a1 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -329,7 +329,7 @@ effective or pretty fucking useless. /obj/item/jammer name = "radio jammer" - desc = "Device used to disrupt nearby radio communication. Alternate function creates a powerful distruptor wave which disables all nearby listening devices." + desc = "Device used to disrupt nearby radio communication. Alternate function creates a powerful disruptor wave which disables all nearby listening devices." icon = 'icons/obj/devices/syndie_gadget.dmi' icon_state = "jammer" var/active = FALSE @@ -342,7 +342,7 @@ effective or pretty fucking useless. register_context() /obj/item/jammer/add_context(atom/source, list/context, obj/item/held_item, mob/user) - context[SCREENTIP_CONTEXT_LMB] = "Release distruptor wave" + context[SCREENTIP_CONTEXT_LMB] = "Release disruptor wave" context[SCREENTIP_CONTEXT_RMB] = "Toggle" return CONTEXTUAL_SCREENTIP_SET @@ -352,8 +352,8 @@ effective or pretty fucking useless. user.balloon_alert(user, "on cooldown!") return - user.balloon_alert(user, "distruptor wave released!") - to_chat(user, span_notice("You release a distruptor wave, disabling all nearby radio devices.")) + user.balloon_alert(user, "disruptor wave released!") + to_chat(user, span_notice("You release a disruptor wave, disabling all nearby radio devices.")) for (var/atom/potential_owner in view(7, user)) disable_radios_on(potential_owner) COOLDOWN_START(src, jam_cooldown, jam_cooldown_duration) @@ -379,8 +379,8 @@ effective or pretty fucking useless. user.balloon_alert(user, "out of reach!") return - interacting_with.balloon_alert(user, "radio distrupted!") - to_chat(user, span_notice("You release a directed distruptor wave, disabling all radio devices on [interacting_with].")) + interacting_with.balloon_alert(user, "radio disrupted!") + to_chat(user, span_notice("You release a directed disruptor wave, disabling all radio devices on [interacting_with].")) disable_radios_on(interacting_with) return ITEM_INTERACT_SUCCESS diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 4f0c0a84aa31..ffa172707bc7 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -245,7 +245,7 @@ if(attached_device) if(issignaler(attached_device)) var/obj/item/assembly/signaler/attached_signaller = attached_device - attachment = "[attached_signaller]" + attachment = "[attached_signaller]" attachment_signal_log = attached_signaller.last_receive_signal_log ? "The following log entry is the last one associated with the attached signaller
[attached_signaller.last_receive_signal_log]" : "There is no signal log entry." else attachment = attached_device diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index aa98d325a7d4..ef1e4ebdee47 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -89,6 +89,7 @@ result = rigged_value . = result + playsound(src, 'sound/items/dice_roll.ogg', 50, TRUE) var/fake_result = roll(sides)//Daredevil isn't as good as he used to be var/comment = "" diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index 1f428236e822..d0a58909233d 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -2,13 +2,14 @@ * Double-Bladed Energy Swords - Cheridan */ /obj/item/dualsaber + name = "double-bladed energy sword" + desc = "Handle with care." icon = 'icons/obj/weapons/transforming_energy.dmi' icon_state = "dualsaber0" inhand_icon_state = "dualsaber0" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - name = "double-bladed energy sword" - desc = "Handle with care." force = 3 throwforce = 5 throw_speed = 3 @@ -75,7 +76,9 @@ set_light_on(FALSE) /obj/item/dualsaber/get_sharpness() - return HAS_TRAIT(src, TRAIT_WIELDED) && sharpness + if (!HAS_TRAIT(src, TRAIT_WIELDED)) + return NONE + return ..() /obj/item/dualsaber/update_icon_state() icon_state = inhand_icon_state = HAS_TRAIT(src, TRAIT_WIELDED) ? "dualsaber[saber_color][HAS_TRAIT(src, TRAIT_WIELDED)]" : "dualsaber0" diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 881798feb6b1..880ce6cce51c 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -5,6 +5,7 @@ icon_state = "fire_extinguisher0" worn_icon_state = "fire_extinguisher" inhand_icon_state = "fire_extinguisher" + icon_angle = 90 hitsound = 'sound/items/weapons/smash.ogg' pickup_sound = 'sound/items/handling/gas_tank/gas_tank_pick_up.ogg' drop_sound = 'sound/items/handling/gas_tank/gas_tank_drop.ogg' diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index 20bd7689f206..70330904ed70 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -4,13 +4,13 @@ GLOBAL_DATUM(bridge_axe, /obj/item/fireaxe) * Fireaxe */ /obj/item/fireaxe // DEM AXES MAN, marker -Agouri + name = "fire axe" + desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?" icon = 'icons/obj/weapons/fireaxe.dmi' icon_state = "fireaxe0" base_icon_state = "fireaxe" lefthand_file = 'icons/mob/inhands/weapons/axes_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/axes_righthand.dmi' - name = "fire axe" - desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?" force = 5 throwforce = 15 demolition_mod = 1.25 @@ -74,10 +74,11 @@ GLOBAL_DATUM(bridge_axe, /obj/item/fireaxe) * Bone Axe */ /obj/item/fireaxe/boneaxe // Blatant imitation of the fireaxe, but made out of bone. - icon_state = "bone_axe0" - base_icon_state = "bone_axe" name = "bone axe" desc = "A large, vicious axe crafted out of several sharpened bone plates and crudely tied together. Made of monsters, by killing monsters, for killing monsters." + icon_state = "bone_axe0" + base_icon_state = "bone_axe" + icon_angle = 180 force_unwielded = 5 force_wielded = 23 @@ -85,10 +86,11 @@ GLOBAL_DATUM(bridge_axe, /obj/item/fireaxe) * Metal Hydrogen Axe */ /obj/item/fireaxe/metal_h2_axe - icon_state = "metalh2_axe0" - base_icon_state = "metalh2_axe" name = "metallic hydrogen axe" desc = "A lightweight crowbar with an extreme sharp fire axe head attached. It trades its heft as a weapon by making it easier to carry around when holstered to suits without having to sacrifice your backpack." + icon_state = "metalh2_axe0" + base_icon_state = "metalh2_axe" + icon_angle = -45 force_unwielded = 5 force_wielded = 15 demolition_mod = 2 @@ -98,10 +100,10 @@ GLOBAL_DATUM(bridge_axe, /obj/item/fireaxe) //boarding axe /obj/item/fireaxe/boardingaxe - icon_state = "boarding_axe0" - base_icon_state = "boarding_axe" name = "boarding axe" desc = "A hulking cleaver that feels like a burden just looking at it. Seems excellent at halving obstacles like windows, airlocks, barricades and people." + icon_state = "boarding_axe0" + base_icon_state = "boarding_axe" force_unwielded = 5 force_wielded = 30 demolition_mod = 3 diff --git a/code/game/objects/items/flatpacks.dm b/code/game/objects/items/flatpacks.dm new file mode 100644 index 000000000000..054d51e6c154 --- /dev/null +++ b/code/game/objects/items/flatpacks.dm @@ -0,0 +1,165 @@ +/obj/item/flatpack + name = "flatpack" + desc = "A box containing a compactly packed machine. Use multitool to deploy." + icon = 'icons/obj/devices/circuitry_n_data.dmi' + icon_state = "flatpack" + density = TRUE + w_class = WEIGHT_CLASS_HUGE //cart time + throw_range = 2 + item_flags = SLOWS_WHILE_IN_HAND | IMMUTABLE_SLOW + slowdown = 2.5 + drag_slowdown = 3.5 //use the cart stupid + custom_premium_price = PAYCHECK_COMMAND * 1.5 + + /// The board we deploy + var/obj/item/circuitboard/machine/board + +/obj/item/flatpack/Initialize(mapload, obj/item/circuitboard/machine/new_board) + if(isnull(board) && isnull(new_board)) + return INITIALIZE_HINT_QDEL //how + + . = ..() + + var/static/list/tool_behaviors = list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Deploy", + ), + ) + AddElement(/datum/element/contextual_screentip_tools, tool_behaviors) + + board = !isnull(new_board) ? new_board : new board(src) // i got board + if(board.loc != src) + board.forceMove(src) + var/obj/machinery/build = initial(board.build_path) + name = "flatpack ([initial(build.name)])" + +/obj/item/flatpack/Destroy() + QDEL_NULL(board) + . = ..() + +/obj/item/flatpack/examine(mob/user) + . = ..() + if(!in_range(user, src) && !isobserver(user)) + return + + if(loc == user) + . += span_warning("You can't deploy while holding it in your hand.") + else if(isturf(loc)) + var/turf/location = loc + if(!isopenturf(location)) + . += span_warning("Can't deploy in this location") + else if(location.is_blocked_turf(source_atom = src)) + . += span_warning("No space for deployment") + +/obj/item/flatpack/multitool_act(mob/living/user, obj/item/tool) + . = NONE + + if(isnull(board)) + return ITEM_INTERACT_BLOCKING + if(loc == user) + balloon_alert(user, "can't deploy in hand") + return ITEM_INTERACT_BLOCKING + else if(isturf(loc)) + var/turf/location = loc + if(!isopenturf(location)) + balloon_alert(user, "can't deploy here") + return ITEM_INTERACT_BLOCKING + else if(location.is_blocked_turf(source_atom = src)) + balloon_alert(user, "no space for deployment") + return ITEM_INTERACT_BLOCKING + balloon_alert_to_viewers("deploying!") + if(!do_after(user, 1 SECONDS, target = src)) + return ITEM_INTERACT_BLOCKING + + new /obj/effect/temp_visual/mook_dust(loc) + var/obj/machinery/new_machine = new board.build_path(loc) + loc.visible_message(span_warning("[src] deploys!")) + playsound(src, 'sound/machines/terminal/terminal_eject.ogg', 70, TRUE) + new_machine.on_construction(user) + qdel(src) + return ITEM_INTERACT_SUCCESS + +///Maximum number of flatpacks in a cart +#define MAX_FLAT_PACKS 3 + +/obj/structure/flatpack_cart + name = "flatpack cart" + desc = "A cart specifically made to hold flatpacks from a flatpacker, evenly distributing weight. Convenient!" + icon = 'icons/obj/structures.dmi' + icon_state = "flatcart" + density = TRUE + opacity = FALSE + +/obj/structure/flatpack_cart/Initialize(mapload) + . = ..() + + register_context() + + AddElement(/datum/element/noisy_movement, volume = 45) // i hate noise + +/obj/structure/flatpack_cart/atom_deconstruct(disassembled) + for(var/atom/movable/content as anything in contents) + content.forceMove(drop_location()) + +/obj/structure/flatpack_cart/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(isnull(held_item)) + return + + if(istype(held_item, /obj/item/flatpack)) + context[SCREENTIP_CONTEXT_LMB] = "Load pack" + return CONTEXTUAL_SCREENTIP_SET + +/obj/structure/flatpack_cart/examine(mob/user) + . = ..() + if(!in_range(user, src) && !isobserver(user)) + return + + . += "From bottom to top, this cart contains:" + for(var/obj/item/flatpack as anything in contents) + . += flatpack.name + +/obj/structure/flatpack_cart/update_overlays() + . = ..() + + var/offset = 0 + for(var/item in contents) + var/mutable_appearance/flatpack_overlay = mutable_appearance(icon, "flatcart_flat", layer = layer + (offset * 0.01)) + flatpack_overlay.pixel_y = offset + offset += 4 + . += flatpack_overlay + +/obj/structure/flatpack_cart/attack_hand(mob/user, list/modifiers) + . = ..() + if(.) + return + user.put_in_hands(contents[length(contents)]) //topmost box + update_appearance(UPDATE_OVERLAYS) + +/obj/structure/flatpack_cart/item_interaction(mob/living/user, obj/item/attacking_item, params) + if(!istype(attacking_item, /obj/item/flatpack) || user.combat_mode || attacking_item.flags_1 & HOLOGRAM_1 || attacking_item.item_flags & ABSTRACT) + return ITEM_INTERACT_SKIP_TO_ATTACK + + if (length(contents) >= MAX_FLAT_PACKS) + balloon_alert(user, "full!") + return ITEM_INTERACT_BLOCKING + if (!user.transferItemToLoc(attacking_item, src)) + return ITEM_INTERACT_BLOCKING + update_appearance(UPDATE_OVERLAYS) + return ITEM_INTERACT_SUCCESS + +#undef MAX_FLAT_PACKS + +// Engineering flatpacks + +/obj/item/flatpack/flatpacker // a roundstart flatpacker is NICE you can gahdamn tell the time and everythin' + name = "flatpacker" + board = /obj/item/circuitboard/machine/flatpacker + custom_premium_price = PAYCHECK_COMMAND + +// Cargo flatpacks + +/obj/item/flatpack/mailsorter // to have a roundstart mail sorter at cargo + name = "mail sorter" + board = /obj/item/circuitboard/machine/mailsorter + custom_premium_price = PAYCHECK_CREW * 1.5 diff --git a/code/game/objects/items/food/bread.dm b/code/game/objects/items/food/bread.dm index 48e7a2a21b1a..3a41514413c6 100644 --- a/code/game/objects/items/food/bread.dm +++ b/code/game/objects/items/food/bread.dm @@ -420,6 +420,7 @@ /obj/item/food/baguette/combat block_sound = 'sound/items/weapons/parry.ogg' sharpness = SHARP_EDGED + icon_angle = -45 /// Force when wielded as a sword by a mime var/active_force = 20 /// Block chance when wielded as a sword by a mime diff --git a/code/game/objects/items/forensicsspoofer.dm b/code/game/objects/items/forensicsspoofer.dm new file mode 100644 index 000000000000..b2384d2dda23 --- /dev/null +++ b/code/game/objects/items/forensicsspoofer.dm @@ -0,0 +1,198 @@ +/obj/item/forensics_spoofer + name = /obj/item/detective_scanner::name + desc = "Used to adjacently scan objects and biomass for fibers and fingerprints. Can replicate the findings." + icon = /obj/item/detective_scanner::icon + icon_state = /obj/item/detective_scanner::icon_state + w_class = WEIGHT_CLASS_SMALL + inhand_icon_state = /obj/item/detective_scanner::inhand_icon_state + worn_icon_state = /obj/item/detective_scanner::worn_icon_state + lefthand_file = /obj/item/detective_scanner::lefthand_file + righthand_file = /obj/item/detective_scanner::righthand_file + obj_flags = CONDUCTS_ELECTRICITY + item_flags = NOBLUDGEON + slot_flags = ITEM_SLOT_BELT + /// stored fibers in memory + var/list/fibers = list() + /// stored fingerprints in memory + var/list/fingerprints = list() + /// chosen fiber to add to target + var/chosen_fiber + /// chosen fingerprint to add to target + var/chosen_fingerprint + /// max storage for fibers/fingerprints seperate for each + var/max_storage = 5 + /// do we scan for new material? if false will tamper + var/scan_mode = TRUE + /// do we make forensics scanner messages and sounds + var/silent_mode = FALSE + /// tamper cooldown time so people dont spam it on every single wall and thing ever + var/tamper_cooldown_time = 1 SECONDS + COOLDOWN_DECLARE(tamper_cooldown) + +/obj/item/forensics_spoofer/Initialize(mapload) + . = ..() + // most things have add_fingerprint in their item interaction because lol lmao + // tl;dr cut off the chain before anything fires so we dont add user fingerprints to target + RegisterSignal(src, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(do_interact)) + +/obj/item/forensics_spoofer/attack_self_secondary(mob/user, modifiers) + . = ..() + if(.) + return + scan_mode = !scan_mode + balloon_alert(user, "now [scan_mode ? "scanning" : "applying"]") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +// ok due to shenanigans basically every item interact adds your fingerprints to it which isnt ideal so we have this +/obj/item/forensics_spoofer/proc/do_interact(datum/source, mob/living/user, atom/interacting_with, list/modifiers) + SIGNAL_HANDLER + if(scan_mode) + INVOKE_ASYNC(src, PROC_REF(scan), interacting_with, user) + else + tamper(interacting_with, user, do_fibers = !isnull(chosen_fiber)) + return ITEM_INTERACT_SUCCESS + +/obj/item/forensics_spoofer/proc/do_fake_scan(atom/target, mob/user) + if(silent_mode) + return + playsound(src, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE) + user.visible_message( + span_notice("\The [user] points the [name] at \the [target] and performs a forensic scan.") + ) + +/obj/item/forensics_spoofer/proc/clear_values(list/the_list) + for(var/key in the_list) + the_list[key] = "" + +/obj/item/forensics_spoofer/proc/scan(atom/target, mob/living/user) + do_fake_scan(target, user) + if(isnull(target.forensics)) + target.balloon_alert(user, "nothing!") + return ITEM_INTERACT_FAILURE + var/list/new_fibers = LAZYCOPY(target.forensics.fibers) - fibers + var/list/new_prints = LAZYCOPY(target.forensics.fingerprints) - fingerprints + var/new_len = length(new_fibers) + length(new_prints) + balloon_alert(user, "[new_len ? new_len : "no"] new prints/fibers") + if(new_len) + var/list/message = list(span_bold("Scan results (Unstored Only):")) + for(var/text in new_fibers) + message += span_notice("Fiber: [text]") + if(length(fibers) > max_storage) + message += span_boldwarning("Fiber storage full.") + for(var/text in new_prints) + message += span_notice("Fingerprint: [text]") + if(length(fingerprints) > max_storage) + message += span_boldwarning("Fingerprint storage full.") + to_chat(user, boxed_message(jointext(message, "\n")), type = MESSAGE_TYPE_INFO) + if(length(fingerprints) < max_storage) + while(length(fingerprints) + length(new_prints) > max_storage) + var/to_remove = tgui_input_list(user, "Too many prints, cancel to discard all", "What to discard", new_fibers) + if(isnull(to_remove)) + return ITEM_INTERACT_FAILURE + new_prints -= to_remove + clear_values(new_prints) + fingerprints += new_prints + for(var/fingerprint in fingerprints) + fingerprints[fingerprint] = get_name_from_fingerprint(fingerprint) + if(length(fibers) < max_storage) + while(length(fibers) + length(new_fibers) > max_storage) + var/to_remove = tgui_input_list(user, "Too many prints, cancel to discard all", "What to discard", new_fibers) + if(isnull(to_remove)) + return ITEM_INTERACT_FAILURE + new_fibers -= to_remove + clear_values(new_fibers) + fibers += new_fibers + return ITEM_INTERACT_SUCCESS + +/obj/item/forensics_spoofer/proc/tamper(atom/target, mob/living/user, do_fibers = FALSE) + do_fake_scan(target, user) + if((!do_fibers && isnull(chosen_fingerprint)) || (do_fibers && isnull(chosen_fiber))) + balloon_alert(user, "no [do_fibers ? "fiber" : "fingerprint"] selected!") // we CAN automatically select it but if they dont have it selected then they likely didnt know of it in the first place so they learn it now + return ITEM_INTERACT_FAILURE + if(!COOLDOWN_FINISHED(src, tamper_cooldown)) + balloon_alert(user, "please wait!") + return ITEM_INTERACT_FAILURE + if(!isnull(target.forensics) && LAZYFIND(do_fibers ? target.forensics.fibers : target.forensics.fingerprints, do_fibers ? chosen_fiber : chosen_fingerprint)) + balloon_alert(user, "already present!") + return ITEM_INTERACT_FAILURE + + if(do_fibers) + target.add_fiber_list(list(chosen_fiber)) + user.log_message("has tampered with the fingerprints/fibers of [src]. Added [chosen_fiber]", LOG_ATTACK) + else + target.add_fingerprint_list(list(chosen_fingerprint)) + user.log_message("has tampered with the fingerprints/fibers of [src]. Added [chosen_fingerprint]", LOG_ATTACK) + + target.balloon_alert(user, "[do_fibers ? "fiber" : "fingerprint"] added") + target.add_hiddenprint(user) + COOLDOWN_START(src, tamper_cooldown, tamper_cooldown_time) + + return ITEM_INTERACT_SUCCESS + +/obj/item/forensics_spoofer/proc/get_name_from_fingerprint(fingerprint) + . = "Unknown" + for(var/datum/record/crew/player_record as anything in GLOB.manifest.general) + if(player_record.fingerprint != fingerprint) + continue + return player_record.name + +/obj/item/forensics_spoofer/ui_state(mob/user) + return GLOB.hands_state + +/obj/item/forensics_spoofer/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ForensicsSpoofer", name) + ui.open() + +/obj/item/forensics_spoofer/ui_static_data(mob/user) + . = list( + "max_storage" = max_storage, + ) + +/obj/item/forensics_spoofer/ui_data(mob/user) + return list( + "scanmode" = scan_mode, + "silent" = silent_mode, + "fibers" = fibers, + "fingerprints" = fingerprints, + "chosen_fiber" = chosen_fiber, + "chosen_fingerprint" = chosen_fingerprint, + ) + +/obj/item/forensics_spoofer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + if(!isnull(params["chosen"])) //fiber/print actions + var/chosen = params["chosen"] + switch(action) + if("delete") + if(chosen in fibers) + if(chosen_fiber == chosen) + chosen_fiber = null + fibers -= chosen + else + if(chosen_fingerprint == chosen) + chosen_fingerprint = null + fingerprints -= chosen + return TRUE + if("choose") + var/is_fiber = !!(chosen in fibers) + chosen_fiber = is_fiber ? chosen : null + chosen_fingerprint = is_fiber ? null : chosen + return TRUE + if("make_note") + if(chosen in fibers) + fibers[chosen] = params["note"] + else + fingerprints[chosen] = params["note"] + return TRUE + else + switch(action) + if("scanmode") + scan_mode = !scan_mode + return TRUE + if("stealth") + silent_mode = !silent_mode + return TRUE diff --git a/code/game/objects/items/grenades/_grenade.dm b/code/game/objects/items/grenades/_grenade.dm index 780311fa4d14..664a31c22620 100644 --- a/code/game/objects/items/grenades/_grenade.dm +++ b/code/game/objects/items/grenades/_grenade.dm @@ -159,7 +159,7 @@ if(istype(user)) user.add_mob_memory(/datum/memory/bomb_planted, antagonist = src) active = TRUE - icon_state = initial(icon_state) + "_active" + icon_state = (base_icon_state || initial(icon_state)) + "_active" SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time, delayoverride) addtimer(CALLBACK(src, PROC_REF(detonate)), isnull(delayoverride)? det_time : delayoverride) @@ -255,7 +255,7 @@ if(det_time == 0) det_time = "Instant" else - det_time = num2text(det_time * 0.1) + det_time = num2text(det_time * 0.1) var/old_selection = possible_fuse_time.Find(det_time) //Position of det_time in the list if(old_selection >= possible_fuse_time.len) diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index 40d09e604d50..fd07b5a6dba9 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -55,6 +55,7 @@ /obj/item/grenade/stingbang name = "stingbang" icon_state = "timeg_locked" + base_icon_state = "timeg" inhand_icon_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' @@ -65,6 +66,8 @@ /obj/item/grenade/stingbang/mega name = "mega stingbang" + icon_state = "timeg_mega_locked" + base_icon_state = "timeg_mega" shrapnel_type = /obj/projectile/bullet/pellet/stingball/mega shrapnel_radius = 12 @@ -123,6 +126,7 @@ name = "rotfrag grenade" desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases shrapnel shards." icon_state = "timeg_locked" + base_icon_state = "timeg" inhand_icon_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' diff --git a/code/game/objects/items/hand_items.dm b/code/game/objects/items/hand_items.dm index 169ad9b47358..f56200f1a45f 100644 --- a/code/game/objects/items/hand_items.dm +++ b/code/game/objects/items/hand_items.dm @@ -515,7 +515,7 @@ to_chat(taker, span_nicegreen("[offerer] gives you \a [blown_kiss][cheek_kiss ? " on the cheek" : ""]!")) offerer.face_atom(taker) taker.face_atom(offerer) - offerer.do_item_attack_animation(taker, used_item=src) + offerer.do_item_attack_animation(taker, used_item = src) //We're still firing a shot here because I don't want to deal with some weird edgecase where direct impacting them with the projectile causes it to freak out because there's no angle or something blown_kiss.original = taker blown_kiss.fired_from = offerer @@ -539,6 +539,12 @@ color = COLOR_SYNDIE_RED kiss_type = /obj/projectile/kiss/syndie +/obj/item/hand_item/kisser/ink + name = "ink kiss" + desc = "Is that a blot of ink in your pocket or are you just happy to see me?" + color = COLOR_ALMOST_BLACK + kiss_type = /obj/projectile/kiss/ink + /obj/projectile/kiss name = "kiss" icon = 'icons/mob/simple/animal.dmi' @@ -639,6 +645,22 @@ var/obj/item/organ/heart/dont_go_breakin_my_heart = heartbreakee.get_organ_slot(ORGAN_SLOT_HEART) dont_go_breakin_my_heart.apply_organ_damage(999) +/obj/projectile/kiss/ink + name = "ink kiss" + color = COLOR_ALMOST_BLACK + damage = /obj/projectile/ink_spit::damage + damage_type = /obj/projectile/ink_spit::damage_type + armor_flag = /obj/projectile/ink_spit::armor_flag + armour_penetration = /obj/projectile/ink_spit::armour_penetration + impact_effect_type = /obj/projectile/ink_spit::impact_effect_type + hitsound = /obj/projectile/ink_spit::hitsound + hitsound_wall = /obj/projectile/ink_spit::hitsound_wall + +/obj/projectile/kiss/ink/on_hit(atom/target, blocked, pierce_hit) + . = ..() + var/obj/projectile/ink_spit/ink_spit = new (target) + ink_spit.on_hit(target) + // Based on energy gun characteristics /obj/projectile/kiss/syndie name = "syndie kiss" diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index 0e430589981e..948606d6d406 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -61,6 +61,20 @@ /obj/item/inducer/examine(mob/living/user) . = ..() + . += examine_hints(user) + +/** + * Gives description for this inducer + * Arguments + * + * * mob/living/user - the mob we are returning the description to + */ +/obj/item/inducer/proc/examine_hints(mob/living/user) + PROTECTED_PROC(TRUE) + SHOULD_BE_PURE(TRUE) + + . = list() + var/obj/item/stock_parts/power_store/our_cell = get_cell(src, user) if(!QDELETED(our_cell)) . += span_notice("Its display shows: [display_energy(our_cell.charge)].") @@ -231,3 +245,24 @@ desc = "A tool for inductively charging internal power cells. This one has a suspicious colour scheme, and seems to be rigged to transfer charge at a much faster rate." power_transfer_multiplier = 2 // 2x the base speed powerdevice = /obj/item/stock_parts/power_store/battery/super + +/obj/item/inducer/cyborg + name = "internal inducer" + icon = 'icons/obj/tools.dmi' + icon_state = "inducer-engi" + powerdevice = null + +/obj/item/inducer/cyborg/add_context(atom/source, list/context, obj/item/held_item, mob/user) + return NONE + +/obj/item/inducer/cyborg/examine_hints(mob/living/user) + return list() + +/obj/item/inducer/cyborg/get_cell(atom/movable/interface, mob/living/silicon/robot/silicon_friend) + return istype(silicon_friend) ? silicon_friend.cell : null + +/obj/item/inducer/cyborg/screwdriver_act(mob/living/user, obj/item/tool) + return ITEM_INTERACT_FAILURE + +/obj/item/inducer/cyborg/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + return ITEM_INTERACT_FAILURE diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm index 7783dcff072b..d1092c343266 100644 --- a/code/game/objects/items/inspector.dm +++ b/code/game/objects/items/inspector.dm @@ -8,7 +8,9 @@ */ /obj/item/inspector name = "\improper N-spect scanner" - desc = "Central Command standard issue inspection device. Can perform either wide area scans that central command can use to verify the security of the station, or detailed scan. Can scan people for contraband on their person or items being contraband." + desc = "Central Command standard issue inspection device. \ + Performs wide area scan reports for inspectors to use to verify the security and integrity of the station. \ + Can additionally be used for precision scans to determine if an item contains, or is itself, contraband." icon = 'icons/obj/devices/scanner.dmi' icon_state = "inspector" worn_icon_state = "salestagger" @@ -88,14 +90,16 @@ /obj/item/inspector/examine(mob/user) . = ..() + . += span_info("Use in-hand to scan the local area, creating an encrypted security inspection.") + . += span_info("Use on an item to scan if it contains, or is, contraband.") if(!cell_cover_open) - . += "Its cell cover is closed. It looks like it could be pried out, but doing so would require an appropriate tool." + . += span_notice("Its cell cover is closed. It looks like it could be pried out, but doing so would require an appropriate tool.") return - . += "Its cell cover is open, exposing the cell slot. It looks like it could be pried in, but doing so would require an appropriate tool." + . += span_notice("Its cell cover is open, exposing the cell slot. It looks like it could be pried in, but doing so would require an appropriate tool.") if(!cell) - . += "The slot for a cell is empty." + . += span_notice("The slot for a cell is empty.") else - . += "\The [cell] is firmly in place. [span_info("Ctrl-click with an empty hand to remove it.")]" + . += span_notice("\The [cell] is firmly in place. Ctrl-click with an empty hand to remove it.") /obj/item/inspector/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!user.Adjacent(interacting_with)) diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index edfb98e7ed79..696c29bef775 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -22,6 +22,7 @@ name = "fork" desc = "Pointy." icon_state = "fork" + icon_angle = -90 force = 4 w_class = WEIGHT_CLASS_TINY throwforce = 0 @@ -107,6 +108,7 @@ name = "Kitchen Toolset" icon = 'icons/obj/items_cyborg.dmi' icon_state = "sili_knife" + icon_angle = 0 desc = "A breakthrough in synthetic engineering, this tool is a knife programmed to dull when not used for cooking purposes, and can exchange the blade for a rolling pin" force = 0 throwforce = 0 @@ -152,6 +154,7 @@ icon_state = "rolling_pin" worn_icon_state = "rolling_pin" inhand_icon_state = "rolling_pin" + icon_angle = -45 force = 8 throwforce = 5 throw_speed = 3 @@ -186,6 +189,7 @@ desc = "Just be careful your food doesn't melt the spoon first." icon_state = "spoon" base_icon_state = "spoon" + icon_angle = -90 w_class = WEIGHT_CLASS_TINY obj_flags = CONDUCTS_ELECTRICITY force = 2 @@ -327,6 +331,7 @@ icon_state = "ladle" base_icon_state = "ladle" inhand_icon_state = "spoon" + icon_angle = 90 custom_price = PAYCHECK_LOWER * 4 spoon_sip_size = 3 // just a taste diff --git a/code/game/objects/items/knives.dm b/code/game/objects/items/knives.dm index 9ba10c4f0a49..4d1d6df3b7fc 100644 --- a/code/game/objects/items/knives.dm +++ b/code/game/objects/items/knives.dm @@ -7,6 +7,7 @@ righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' inhand_icon_state = "knife" worn_icon_state = "knife" + icon_angle = -90 desc = "The original knife, it is said that all other knives are only copies of this one." obj_flags = CONDUCTS_ELECTRICITY force = 10 @@ -17,13 +18,15 @@ throw_speed = 3 throw_range = 6 custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 6) - attack_verb_continuous = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("slash", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED armor_type = /datum/armor/item_knife wound_bonus = 5 bare_wound_bonus = 15 tool_behaviour = TOOL_KNIFE + var/list/alt_continuous = list("stabs", "pierces", "shanks") + var/list/alt_simple = list("stab", "pierce", "shank") /datum/armor/item_knife fire = 50 @@ -33,6 +36,9 @@ . = ..() AddElement(/datum/element/eyestab) set_butchering() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + make_stabby() ///Adds the butchering component, used to override stats for special cases /obj/item/knife/proc/set_butchering() @@ -44,6 +50,10 @@ // IRIS EDIT: Originally 8 SECONDS //bonus chance increases depending on force +///Adds alt sharpness component, used for overrides +/obj/item/knife/proc/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple) + /obj/item/knife/suicide_act(mob/living/user) user.visible_message(pick(span_suicide("[user] is slitting [user.p_their()] wrists with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide."), \ span_suicide("[user] is slitting [user.p_their()] throat with the [src.name]! It looks like [user.p_theyre()] trying to commit suicide."), \ @@ -57,6 +67,7 @@ icon_state = "bone_blade" inhand_icon_state = "bone_blade" worn_icon_state = "bone_blade" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' inhand_x_dimension = 64 @@ -73,6 +84,7 @@ icon = 'icons/obj/weapons/khopesh.dmi' icon_state = "bloodletter" worn_icon_state = "render" + icon_angle = -45 w_class = WEIGHT_CLASS_NORMAL /// Bleed stacks applied when an organic mob target is hit var/bleed_stacks_per_hit = 3 @@ -91,9 +103,10 @@ /obj/item/knife/butcher name = "butcher's cleaver" + desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown by-products." icon_state = "butch" inhand_icon_state = "butch" - desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown by-products." + icon_angle = -45 obj_flags = CONDUCTS_ELECTRICITY force = 15 throwforce = 10 @@ -104,12 +117,16 @@ custom_price = PAYCHECK_CREW * 5 wound_bonus = 15 +/obj/item/knife/butcher/make_stabby() + return + /obj/item/knife/hunting name = "hunting knife" - icon = 'icons/obj/weapons/stabby.dmi' desc = "Despite its name, it's mainly used for cutting meat from dead prey rather than actual hunting." + icon = 'icons/obj/weapons/stabby.dmi' inhand_icon_state = "huntingknife" icon_state = "huntingknife" + icon_angle = 180 wound_bonus = 10 /obj/item/knife/hunting/set_butchering() @@ -120,12 +137,16 @@ ) // IRIS EDIT: Originally 8 SECONDS +/obj/item/knife/hunting/make_stabby() + return + /obj/item/knife/combat name = "combat knife" + desc = "A military combat utility survival knife." icon = 'icons/obj/weapons/stabby.dmi' icon_state = "buckknife" worn_icon_state = "buckknife" - desc = "A military combat utility survival knife." + icon_angle = -45 embed_type = /datum/embed_data/combat_knife force = 20 throwforce = 20 @@ -143,6 +164,9 @@ . = ..() AddComponent(/datum/component/knockoff, 90, list(BODY_ZONE_PRECISE_MOUTH), slot_flags) //90% to knock off when wearing a mask +/obj/item/knife/combat/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5) + /obj/item/knife/combat/dropped(mob/living/user, slot) . = ..() if(user.get_item_by_slot(ITEM_SLOT_MASK) == src && !user.has_status_effect(/datum/status_effect/choke) && prob(20)) @@ -160,36 +184,33 @@ /obj/item/knife/combat/survival name = "survival knife" - icon = 'icons/obj/weapons/stabby.dmi' + desc = "A hunting grade survival knife." icon_state = "survivalknife" worn_icon_state = "survivalknife" embed_type = /datum/embed_data/combat_knife/weak - desc = "A hunting grade survival knife." force = 15 throwforce = 15 /obj/item/knife/combat/root name = "cahn'root dagger" - icon = 'icons/obj/weapons/stabby.dmi' + desc = "A root dagger, deceptively sharp. Perfect to hide and stab someone with, or make a couple and throw them at enemies." icon_state = "rootdagger" worn_icon_state = "root_dagger" lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' inhand_icon_state = "rootshiv" embed_type = /datum/embed_data/combat_knife/weak - desc = "A root dagger, deceptively sharp. Perfect to hide and stab someone with, or make a couple and throw them at enemies." force = 15 throwforce = 15 /obj/item/knife/combat/bone name = "bone dagger" + desc = "A sharpened bone. The bare minimum in survival." inhand_icon_state = "bone_dagger" - icon = 'icons/obj/weapons/stabby.dmi' icon_state = "bone_dagger" worn_icon_state = "bone_dagger" lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - desc = "A sharpened bone. The bare minimum in survival." embed_type = /datum/embed_data/combat_knife/weak obj_flags = parent_type::obj_flags & ~CONDUCTS_ELECTRICITY force = 15 @@ -201,20 +222,21 @@ /obj/item/knife/combat/cyborg name = "cyborg knife" + desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." icon = 'icons/obj/items_cyborg.dmi' icon_state = "knife_cyborg" worn_icon_state = "knife_cyborg" //error sprite - this shouldn't have been dropped - desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." slot_flags = NONE //you can't put this in your mouth /obj/item/knife/shiv name = "glass shiv" + desc = "A makeshift glass shiv." icon = 'icons/obj/weapons/stabby.dmi' icon_state = "shiv" inhand_icon_state = "shiv" + icon_angle = -65 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - desc = "A makeshift glass shiv." obj_flags = parent_type::obj_flags & ~CONDUCTS_ELECTRICITY force = 8 throwforce = 12 @@ -223,11 +245,14 @@ armor_type = /datum/armor/none custom_materials = list(/datum/material/glass = SMALL_MATERIAL_AMOUNT * 4) +/obj/item/knife/shiv/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -3) + /obj/item/knife/shiv/plasma name = "plasma shiv" + desc = "A makeshift plasma glass shiv." icon_state = "plasmashiv" inhand_icon_state = "plasmashiv" - desc = "A makeshift plasma glass shiv." force = 9 throwforce = 13 armor_type = /datum/armor/shiv_plasma @@ -244,9 +269,9 @@ /obj/item/knife/shiv/titanium name = "titanium shiv" + desc = "A makeshift titanium-infused glass shiv." icon_state = "titaniumshiv" inhand_icon_state = "titaniumshiv" - desc = "A makeshift titanium-infused glass shiv." throwforce = 14 throw_range = 7 wound_bonus = 10 @@ -264,9 +289,9 @@ /obj/item/knife/shiv/plastitanium name = "plastitanium shiv" + desc = "A makeshift titanium-infused plasma glass shiv." icon_state = "plastitaniumshiv" inhand_icon_state = "plastitaniumshiv" - desc = "A makeshift titanium-infused plasma glass shiv." force = 10 throwforce = 15 throw_speed = 4 @@ -287,9 +312,10 @@ /obj/item/knife/shiv/carrot name = "carrot shiv" + desc = "Unlike other carrots, you should probably keep this far away from your eyes." icon_state = "carrotshiv" inhand_icon_state = "carrotshiv" - desc = "Unlike other carrots, you should probably keep this far away from your eyes." + icon_angle = -45 custom_materials = null /obj/item/knife/shiv/carrot/suicide_act(mob/living/carbon/user) @@ -298,15 +324,17 @@ /obj/item/knife/shiv/parsnip name = "parsnip shiv" + desc = "Truly putting 'snip' in the 'parsnip', and it's not sub-par either!" icon_state = "parsnipshiv" inhand_icon_state = "parsnipshiv" - desc = "Truly putting 'snip' in the 'parsnip', and it's not sub-par either!" + icon_angle = -45 custom_materials = null /obj/item/knife/shiv/root name = "cahn'root shiv" + desc = "A root sharpened into a shiv. A root source of someone's stab wounds soon, most likely." icon_state = "rootshiv" inhand_icon_state = "rootshiv" - desc = "A root sharpened into a shiv. A root source of someone's stab wounds soon, most likely." + icon_angle = -45 custom_materials = null diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm index 56d5d44a9a44..f051d670b525 100644 --- a/code/game/objects/items/mail.dm +++ b/code/game/objects/items/mail.dm @@ -344,6 +344,7 @@ icon_state = "mailbag" worn_icon_state = "mailbag" resistance_flags = FLAMMABLE + custom_premium_price = PAYCHECK_LOWER /obj/item/storage/bag/mail/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/maintenance_loot.dm b/code/game/objects/items/maintenance_loot.dm index 9d1c4fe676b8..5389f7723b98 100644 --- a/code/game/objects/items/maintenance_loot.dm +++ b/code/game/objects/items/maintenance_loot.dm @@ -8,6 +8,7 @@ icon = 'icons/obj/maintenance_loot.dmi' icon_state = "lead_pipe" inhand_icon_state = "lead_pipe" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' //wow, lore @@ -32,19 +33,19 @@ desc = "A primitive battery. It is quite large and feels unexpectedly heavy." icon = 'icons/obj/maintenance_loot.dmi' icon_state = "lead_battery" + force = 10 // double the force of a normal cell throwforce = 10 - maxcharge = STANDARD_BATTERY_VALUE //decent max charge - chargerate = STANDARD_BATTERY_RATE * 0.3 //charging is about 70% less efficient than lithium batteries. + w_class = WEIGHT_CLASS_NORMAL + maxcharge = STANDARD_CELL_CHARGE * 60 // initial charge reduced on init + chargerate = STANDARD_CELL_RATE * 0.3 //charging is about 70% less efficient than lithium batteries. charge_light_type = null connector_type = "leadacid" - rating = 2 //Kind of a mid-tier battery - w_class = WEIGHT_CLASS_NORMAL grind_results = list(/datum/reagent/lead = 15, /datum/reagent/toxin/acid = 15, /datum/reagent/water = 20) //starts partially discharged /obj/item/stock_parts/power_store/cell/lead/Initialize(mapload) AddElement(/datum/element/update_icon_blocker) . = ..() - var/initial_percent = rand(20, 80) / 100 + var/initial_percent = rand(40, 60) / 100 // 250kJ to 350kJ charge = initial_percent * maxcharge ADD_TRAIT(src, TRAIT_FISHING_BAIT, INNATE_TRAIT) diff --git a/code/game/objects/items/melee/baton.dm b/code/game/objects/items/melee/baton.dm index b87bf0f593ec..fb4da8cfd655 100644 --- a/code/game/objects/items/melee/baton.dm +++ b/code/game/objects/items/melee/baton.dm @@ -6,6 +6,7 @@ icon_state = "classic_baton" inhand_icon_state = "classic_baton" worn_icon_state = "classic_baton" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' slot_flags = ITEM_SLOT_BELT @@ -307,6 +308,7 @@ desc = "A compact yet robust personal defense weapon. Can be concealed when folded." icon = 'icons/obj/weapons/baton.dmi' icon_state = "telebaton" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' inhand_icon_state = null @@ -397,6 +399,7 @@ icon = 'icons/obj/weapons/baton.dmi' icon_state = "contractor_baton" worn_icon_state = "contractor_baton" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' slot_flags = ITEM_SLOT_BELT @@ -432,6 +435,7 @@ icon_state = "stunbaton" inhand_icon_state = "baton" worn_icon_state = "baton" + icon_angle = -45 force = 10 wound_bonus = 0 attack_verb_continuous = list("beats") @@ -725,6 +729,7 @@ icon_state = "stunprod" inhand_icon_state = "prod" worn_icon_state = null + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' w_class = WEIGHT_CLASS_HUGE diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index f78eec389879..a386375b8277 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -1,5 +1,6 @@ /obj/item/melee/energy icon = 'icons/obj/weapons/transforming_energy.dmi' + icon_angle = -45 max_integrity = 200 armor_type = /datum/armor/melee_energy attack_verb_continuous = list("hits", "taps", "pokes") @@ -63,8 +64,8 @@ sharpness_on = active_sharpness, \ hitsound_on = active_hitsound, \ w_class_on = active_w_class, \ - attack_verb_continuous_on = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \ - attack_verb_simple_on = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut"), \ + attack_verb_continuous_on = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \ + attack_verb_simple_on = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut"), \ ) RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) @@ -190,6 +191,14 @@ block_chance = 50 block_sound = 'sound/items/weapons/block_blade.ogg' embed_type = /datum/embed_data/esword + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") + +/obj/item/melee/energy/sword/Initialize(mapload) + . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -10, TRAIT_TRANSFORM_ACTIVE) /obj/item/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) if(!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) @@ -322,8 +331,8 @@ lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' hitsound = 'sound/items/weapons/blade1.ogg' - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut") force = 30 throwforce = 1 // Throwing or dropping the item deletes it. throw_speed = 3 @@ -333,10 +342,15 @@ w_class = WEIGHT_CLASS_BULKY /// Our linked spark system that emits from our sword. var/datum/effect_system/spark_spread/spark_system + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") //Most of the other special functions are handled in their own files. aka special snowflake code so kewl /obj/item/melee/energy/blade/Initialize(mapload) . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -10) spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) @@ -356,3 +370,4 @@ icon_state = "lightblade" inhand_icon_state = "lightblade" base_icon_state = "lightblade" + icon_angle = 0 diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index e396c609eb25..4200fd142d35 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -9,6 +9,7 @@ icon_state = "chain" inhand_icon_state = "chain" worn_icon_state = "whip" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY @@ -34,18 +35,24 @@ icon = 'icons/obj/weapons/changeling_items.dmi' icon_state = "arm_blade" inhand_icon_state = "arm_blade" + icon_angle = 180 lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' w_class = WEIGHT_CLASS_HUGE force = 20 throwforce = 10 hitsound = 'sound/items/weapons/bladeslice.ogg' - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut") sharpness = SHARP_EDGED + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") /obj/item/melee/synthetic_arm_blade/Initialize(mapload) . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5) AddComponent(/datum/component/butchering, \ speed = 6 SECONDS, \ effectiveness = 80, \ @@ -58,6 +65,7 @@ icon = 'icons/obj/weapons/sword.dmi' icon_state = "sabre" inhand_icon_state = "sabre" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY | UNIQUE_RENAME @@ -171,6 +179,7 @@ icon = 'icons/obj/weapons/sword.dmi' icon_state = "parsnip_sabre" inhand_icon_state = "parsnip_sabre" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' force = 15 @@ -212,6 +221,7 @@ icon_state = "beesword" inhand_icon_state = "stinger" worn_icon_state = "stinger" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' slot_flags = ITEM_SLOT_BELT @@ -248,6 +258,7 @@ icon = 'icons/obj/weapons/sword.dmi' icon_state = "supermatter_sword_balanced" inhand_icon_state = "supermatter_sword" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' slot_flags = null @@ -304,6 +315,7 @@ ..() balanced = 0 icon_state = "supermatter_sword" + icon_angle = -45 /obj/item/melee/supermatter_sword/ex_act(severity, target) visible_message( @@ -361,6 +373,7 @@ icon = 'icons/obj/weapons/whip.dmi' icon_state = "whip" inhand_icon_state = "chain" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' worn_icon_state = "whip" @@ -385,6 +398,7 @@ icon_state = "roastingstick" inhand_icon_state = null worn_icon_state = "tele_baton" + icon_angle = -45 slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_SMALL item_flags = NONE @@ -510,6 +524,7 @@ icon_state = "default" inhand_icon_state = "default" worn_icon_state = "default_worn" + icon_angle = -45 greyscale_config = /datum/greyscale_config/cleric_mace greyscale_config_inhand_left = /datum/greyscale_config/cleric_mace_lefthand diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 2afc31d599e6..dab7644d5d55 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/service/janitor.dmi' icon_state = "mop" inhand_icon_state = "mop" + icon_angle = 135 lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 8 diff --git a/code/game/objects/items/paint.dm b/code/game/objects/items/paint.dm index 66e0b15e99fd..7d5cc7eabe8f 100644 --- a/code/game/objects/items/paint.dm +++ b/code/game/objects/items/paint.dm @@ -118,7 +118,10 @@ if(paintleft <= 0) return NONE paintleft-- - interacting_with.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY) + var/color_type = SATURATION_MULTIPLY + if (LAZYACCESS(modifiers, RIGHT_CLICK)) + color_type = SATURATION_OVERRIDE + interacting_with.add_atom_colour(color_transition_filter(paint_color, color_type), WASHABLE_COLOUR_PRIORITY) if(paintleft <= 0) icon_state = "paint_empty" return ITEM_INTERACT_SUCCESS diff --git a/code/game/objects/items/pitchfork.dm b/code/game/objects/items/pitchfork.dm index 1ece740d4a6d..99f714f09f3b 100644 --- a/code/game/objects/items/pitchfork.dm +++ b/code/game/objects/items/pitchfork.dm @@ -8,6 +8,7 @@ icon = 'icons/obj/weapons/spear.dmi' icon_state = "pitchfork0" base_icon_state = "pitchfork" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' name = "pitchfork" diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index 77810ff3a89b..871a6d2d3b28 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -12,6 +12,7 @@ icon = 'icons/obj/antags/syndicate_tools.dmi' icon_state = "powerfist" inhand_icon_state = "powerfist" + icon_angle = 180 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 60f84e14651b..3dab53cb8ff2 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -565,6 +565,18 @@ return owner.ui_status(user) return UI_CLOSE +/obj/item/construction/rcd/exosuit/build_delay(mob/user, delay, atom/target) + if(delay <= 0) + return TRUE + + var/obj/item/mecha_parts/mecha_equipment/rcd/module = loc + + //deconstruction can't be cancelled by ui changes + if(mode != RCD_DECONSTRUCT) + blueprint_changed = FALSE + + return module.do_after_mecha(target, user, delay) + /obj/item/construction/rcd/exosuit/get_matter(mob/user) if(silo_link) return ..() diff --git a/code/game/objects/items/rcd/RHD.dm b/code/game/objects/items/rcd/RHD.dm index ce9f211b6942..85cdc21947b6 100644 --- a/code/game/objects/items/rcd/RHD.dm +++ b/code/game/objects/items/rcd/RHD.dm @@ -63,6 +63,8 @@ return do_after(user, delay, target, extra_checks = CALLBACK(src, PROC_REF(blueprint_change))) /obj/item/construction/proc/blueprint_change() + PRIVATE_PROC(TRUE) + return !blueprint_changed ///used for examining the RCD and for its UI diff --git a/code/game/objects/items/rcd/RPD.dm b/code/game/objects/items/rcd/RPD.dm index 07db9978e3e0..933f8c1c6487 100644 --- a/code/game/objects/items/rcd/RPD.dm +++ b/code/game/objects/items/rcd/RPD.dm @@ -9,164 +9,15 @@ #define DESTROY_MODE (1<<2) #define REPROGRAM_MODE (1<<3) -#define PIPE_LAYER(num) (1<<(num-1)) +///Maximum number of pipe layers the RPD can support +#define MAX_PIPE_LAYERS 5 + +///Converts the pipe layer into a bitflag so we can append multiple layers into 1 bitfield +#define PIPE_LAYER(num) (1 << (num - 1)) ///Sound to make when we use the item to build/destroy something #define RPD_USE_SOUND 'sound/items/deconstruct.ogg' -GLOBAL_LIST_INIT(atmos_pipe_recipes, list( - "Pipes" = list( - new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/smart, TRUE), - new /datum/pipe_info/pipe("Layer Adapter", /obj/machinery/atmospherics/pipe/layer_manifold, TRUE), - new /datum/pipe_info/pipe("Color Adapter", /obj/machinery/atmospherics/pipe/color_adapter, TRUE), - new /datum/pipe_info/pipe("Bridge Pipe", /obj/machinery/atmospherics/pipe/bridge_pipe, TRUE), - new /datum/pipe_info/pipe("Multi-Deck Adapter", /obj/machinery/atmospherics/pipe/multiz, FALSE), - ), - "Binary" = list( - new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve, TRUE), - new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital, TRUE), - new /datum/pipe_info/pipe("Gas Pump", /obj/machinery/atmospherics/components/binary/pump, TRUE), - new /datum/pipe_info/pipe("Volume Pump", /obj/machinery/atmospherics/components/binary/volume_pump, TRUE), - new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate, TRUE), - new /datum/pipe_info/pipe("Pressure Valve", /obj/machinery/atmospherics/components/binary/pressure_valve, TRUE), - new /datum/pipe_info/pipe("Temperature Gate", /obj/machinery/atmospherics/components/binary/temperature_gate, TRUE), - new /datum/pipe_info/pipe("Temperature Pump", /obj/machinery/atmospherics/components/binary/temperature_pump, TRUE), - ), - "Devices" = list( - new /datum/pipe_info/pipe("Gas Filter", /obj/machinery/atmospherics/components/trinary/filter, TRUE), - new /datum/pipe_info/pipe("Gas Mixer", /obj/machinery/atmospherics/components/trinary/mixer, TRUE), - new /datum/pipe_info/pipe("Connector", /obj/machinery/atmospherics/components/unary/portables_connector, TRUE), - new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector, TRUE), - new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber, TRUE), - new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump, TRUE), - new /datum/pipe_info/pipe("Passive Vent", /obj/machinery/atmospherics/components/unary/passive_vent, TRUE), - new /datum/pipe_info/meter("Meter"), - ), - "Heat Exchange" = list( - new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/heat_exchanging/simple, FALSE), - new /datum/pipe_info/pipe("Manifold", /obj/machinery/atmospherics/pipe/heat_exchanging/manifold, FALSE), - new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w, FALSE), - new /datum/pipe_info/pipe("Junction", /obj/machinery/atmospherics/pipe/heat_exchanging/junction, FALSE), - new /datum/pipe_info/pipe("Heat Exchanger", /obj/machinery/atmospherics/components/unary/heat_exchanger, FALSE), - ) -)) - -GLOBAL_LIST_INIT(disposal_pipe_recipes, list( - "Disposal Pipes" = list( - new /datum/pipe_info/disposal("Pipe", /obj/structure/disposalpipe/segment, PIPE_BENDABLE), - new /datum/pipe_info/disposal("Junction", /obj/structure/disposalpipe/junction, PIPE_TRIN_M), - new /datum/pipe_info/disposal("Y-Junction", /obj/structure/disposalpipe/junction/yjunction), - new /datum/pipe_info/disposal("Sort Junction", /obj/structure/disposalpipe/sorting/mail, PIPE_TRIN_M), - new /datum/pipe_info/disposal("Rotator", /obj/structure/disposalpipe/rotator, PIPE_ONEDIR_FLIPPABLE), - new /datum/pipe_info/disposal("Trunk", /obj/structure/disposalpipe/trunk), - new /datum/pipe_info/disposal("Down Turn", /obj/structure/disposalpipe/trunk/multiz/down), - new /datum/pipe_info/disposal("Up Turn", /obj/structure/disposalpipe/trunk/multiz), - new /datum/pipe_info/disposal("Bin", /obj/machinery/disposal/bin, PIPE_ONEDIR), - new /datum/pipe_info/disposal("Outlet", /obj/structure/disposaloutlet), - new /datum/pipe_info/disposal("Chute", /obj/machinery/disposal/delivery_chute), - ) -)) - -GLOBAL_LIST_INIT(transit_tube_recipes, list( - "Transit Tubes" = list( - new /datum/pipe_info/transit("Straight Tube", /obj/structure/c_transit_tube, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Straight Tube with Crossing", /obj/structure/c_transit_tube/crossing, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Curved Tube", /obj/structure/c_transit_tube/curved, PIPE_UNARY_FLIPPABLE), - new /datum/pipe_info/transit("Diagonal Tube", /obj/structure/c_transit_tube/diagonal, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Diagonal Tube with Crossing", /obj/structure/c_transit_tube/diagonal/crossing, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Junction", /obj/structure/c_transit_tube/junction, PIPE_UNARY_FLIPPABLE), - ), - "Station Equipment" = list( - new /datum/pipe_info/transit("Through Tube Station", /obj/structure/c_transit_tube/station, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Terminus Tube Station", /obj/structure/c_transit_tube/station/reverse, PIPE_UNARY_FLIPPABLE), - new /datum/pipe_info/transit("Through Tube Dispenser Station", /obj/structure/c_transit_tube/station/dispenser, PIPE_STRAIGHT), - new /datum/pipe_info/transit("Terminus Tube Dispenser Station", /obj/structure/c_transit_tube/station/dispenser/reverse, PIPE_UNARY_FLIPPABLE), - new /datum/pipe_info/transit("Transit Tube Pod", /obj/structure/c_transit_tube_pod, PIPE_ONEDIR), - ) -)) - -/datum/pipe_info - var/name - var/icon_state - var/id = -1 - var/dirtype = PIPE_BENDABLE - var/all_layers - -/datum/pipe_info/proc/get_preview(selected_dir, selected = FALSE) - var/list/dirs - switch(dirtype) - if(PIPE_STRAIGHT, PIPE_BENDABLE) - dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal") - if(dirtype == PIPE_BENDABLE) - dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East", - "[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South") - if(PIPE_TRINARY) - dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West", - "[EAST]" = "North West South", "[WEST]" = "South East North") - if(PIPE_TRIN_M) - dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South", - "[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North", - "[WEST]" = "West North East", "[SOUTHEAST]" = "West South East", - "[NORTHWEST]" = "East North West", "[EAST]" = "East South West",) - if(PIPE_UNARY) - dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East") - if(PIPE_ONEDIR) - dirs = list("[SOUTH]" = name) - if(PIPE_UNARY_FLIPPABLE) - dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West", - "[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped") - if(PIPE_ONEDIR_FLIPPABLE) - dirs = list("[SOUTH]" = name, "[SOUTHEAST]" = "[name] Flipped") - - var/list/rows = list() - for(var/dir in dirs) - var/numdir = text2num(dir) - var/flipped = ((dirtype == PIPE_TRIN_M) || (dirtype == PIPE_UNARY_FLIPPABLE) || (dirtype == PIPE_ONEDIR_FLIPPABLE)) && (ISDIAGONALDIR(numdir)) - var/is_variant_selected = selected && (!selected_dir ? FALSE : (dirtype == PIPE_ONEDIR ? TRUE : (numdir == selected_dir))) - rows += list(list( - "selected" = is_variant_selected, - "dir" = dir2text(numdir), - "dir_name" = dirs[dir], - "icon_state" = icon_state, - "flipped" = flipped, - )) - - return rows - -/datum/pipe_info/pipe/New(label, obj/machinery/atmospherics/path, use_five_layers) - name = label - id = path - all_layers = use_five_layers - icon_state = initial(path.pipe_state) - var/obj/item/pipe/c = initial(path.construction_type) - dirtype = initial(c.RPD_type) - -/datum/pipe_info/meter - icon_state = "meter" - dirtype = PIPE_ONEDIR - all_layers = TRUE - -/datum/pipe_info/meter/New(label) - name = label - -/datum/pipe_info/disposal/New(label, obj/path, dt=PIPE_UNARY) - name = label - id = path - - icon_state = initial(path.icon_state) - if(ispath(path, /obj/structure/disposalpipe)) - icon_state = "con[icon_state]" - - dirtype = dt - -/datum/pipe_info/transit/New(label, obj/path, dt=PIPE_UNARY) - name = label - id = path - dirtype = dt - icon_state = initial(path.icon_state) - if(dt == PIPE_UNARY_FLIPPABLE) - icon_state = "[icon_state]_preview" - /obj/item/pipe_dispenser name = "rapid pipe dispenser" desc = "A device used to rapidly pipe things." @@ -210,8 +61,6 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/pipe_layers = PIPE_LAYER(3) ///Are we laying multiple layers per click var/multi_layer = FALSE - ///Layer for disposal ducts - var/ducting_layer = DUCT_LAYER_DEFAULT ///Stores the current device to spawn var/datum/pipe_info/recipe ///Stores the first atmos device @@ -245,8 +94,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( register_item_context() /obj/item/pipe_dispenser/Destroy() - qdel(spark_system) - spark_system = null + QDEL_NULL(spark_system) return ..() /obj/item/pipe_dispenser/examine(mob/user) @@ -254,6 +102,15 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( . += span_notice("You can scroll your mouse wheel to change the piping layer.") . += span_notice("You can right click a pipe to set the RPD to its color and layer.") +/obj/item/pipe_dispenser/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + . = NONE + + if(istype(target, /obj/machinery/atmospherics)) + var/obj/machinery/atmospherics/atmos_target = target + if(atmos_target.pipe_color && atmos_target.piping_layer) + context[SCREENTIP_CONTEXT_RMB] = "Copy piping color and layer" + return CONTEXTUAL_SCREENTIP_SET + /obj/item/pipe_dispenser/equipped(mob/user, slot, initial) . = ..() if(slot & ITEM_SLOT_HANDS) @@ -265,13 +122,6 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( UnregisterSignal(user, COMSIG_MOUSE_SCROLL_ON) return ..() -/obj/item/pipe_dispenser/proc/get_active_pipe_layers() - var/list/layer_nums = list() - for(var/pipe_layer_number in 1 to 5) - if(PIPE_LAYER(pipe_layer_number) & pipe_layers) - layer_nums += pipe_layer_number - return layer_nums - /obj/item/pipe_dispenser/cyborg_unequip(mob/user) UnregisterSignal(user, COMSIG_MOUSE_SCROLL_ON) return ..() @@ -279,30 +129,23 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( /obj/item/pipe_dispenser/attack_self(mob/user) ui_interact(user) -/obj/item/pipe_dispenser/pre_attack_secondary(obj/machinery/atmospherics/target, mob/user, params) - if(!istype(target, /obj/machinery/atmospherics)) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(target.pipe_color && target.piping_layer) - paint_color = GLOB.pipe_color_name[target.pipe_color] - pipe_layers = PIPE_LAYER(target.piping_layer) - balloon_alert(user, "color/layer copied") - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - -/obj/item/pipe_dispenser/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) - . = ..() - if(istype(target, /obj/machinery/atmospherics)) - var/obj/machinery/atmospherics/atmos_target = target - if(atmos_target.pipe_color && atmos_target.piping_layer) - context[SCREENTIP_CONTEXT_RMB] = "Copy piping color and layer" - return CONTEXTUAL_SCREENTIP_SET - - /obj/item/pipe_dispenser/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] points the end of the RPD down [user.p_their()] throat and presses a button! It looks like [user.p_theyre()] trying to commit suicide...")) playsound(get_turf(user), SFX_TOOL_SWITCH, 20, TRUE) playsound(get_turf(user), RPD_USE_SOUND, 50, TRUE) return BRUTELOSS +///Converts pipe_layers bitflag into its corresponding list of actual pipe layers +/obj/item/pipe_dispenser/proc/get_active_pipe_layers() + PRIVATE_PROC(TRUE) + RETURN_TYPE(/list) + + var/list/layer_nums = list() + for(var/pipe_layer_number in 1 to MAX_PIPE_LAYERS) + if(PIPE_LAYER(pipe_layer_number) & pipe_layers) + layer_nums += pipe_layer_number + return layer_nums + /obj/item/pipe_dispenser/ui_assets(mob/user) return list( get_asset_datum(/datum/asset/spritesheet/pipes), @@ -315,15 +158,16 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( ui.open() /obj/item/pipe_dispenser/ui_static_data(mob/user) - var/list/data = list("paint_colors" = GLOB.pipe_paint_colors) - return data + return list( + "paint_colors" = GLOB.pipe_paint_colors, + "max_pipe_layers" = MAX_PIPE_LAYERS, + ) /obj/item/pipe_dispenser/ui_data(mob/user) var/list/data = list( "category" = category, "multi_layer" = multi_layer, "pipe_layers" = pipe_layers, - "ducting_layer" = ducting_layer, "categories" = list(), "selected_recipe" = recipe.name, "selected_color" = paint_color, @@ -370,10 +214,11 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( playsound(src, SFX_TOOL_SWITCH, 20, TRUE) - var/playeffect = TRUE switch(action) if("color") paint_color = params["paint_color"] + return TRUE + if("category") category = text2num(params["category"]) switch(category) @@ -384,66 +229,87 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( if(TRANSIT_CATEGORY) recipe = first_transit p_dir = NORTH - playeffect = FALSE + return TRUE + if("pipe_layers") var/selected_layers = text2num(params["pipe_layers"]) + + //is valid var/valid_layer = FALSE - for(var/pipe_layer_number in 1 to 5) + for(var/pipe_layer_number in 1 to MAX_PIPE_LAYERS) if(!(PIPE_LAYER(pipe_layer_number) & selected_layers)) continue valid_layer = TRUE + break if(!valid_layer) - return + return FALSE + + //append or set the layer if(multi_layer) if(pipe_layers != selected_layers) pipe_layers ^= selected_layers else pipe_layers = selected_layers - playeffect = FALSE + + return TRUE + if("toggle_multi_layer") if(multi_layer) pipe_layers = PIPE_LAYER(max(get_active_pipe_layers())) multi_layer = !multi_layer - if("ducting_layer") - ducting_layer = text2num(params["ducting_layer"]) - playeffect = FALSE + if("pipe_type") var/static/list/recipes if(!recipes) recipes = GLOB.disposal_pipe_recipes + GLOB.atmos_pipe_recipes + GLOB.transit_tube_recipes recipe = recipes[params["category"]][text2num(params["pipe_type"])] p_dir = NORTH + if("setdir") p_dir = text2dir(params["dir"]) p_flipped = text2num(params["flipped"]) - playeffect = FALSE + return TRUE + if("mode") var/selected_mode = text2num(params["mode"]) mode ^= selected_mode + if("init_dir_setting") var/target_dir = p_init_dir ^ text2dir(params["dir_flag"]) // Refuse to create a smart pipe that can only connect in one direction (it would act weirdly and lack an icon) if (ISNOTSTUB(target_dir)) p_init_dir = target_dir else - to_chat(usr, span_warning("\The [src]'s screen flashes a warning: Can't configure a pipe to only connect in one direction.")) - playeffect = FALSE + to_chat(ui.user, span_warning("\The [src]'s screen flashes a warning: Can't configure a pipe to only connect in one direction.")) + return FALSE + if("init_reset") p_init_dir = ALL_CARDINALS - if(playeffect) - spark_system.start() - playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE) + + spark_system.start() + playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE) return TRUE -/obj/item/pipe_dispenser/pre_attack(atom/atom_to_attack, mob/user, params) - if(!ISADVANCEDTOOLUSER(user) || istype(atom_to_attack, /turf/open/space/transit)) - return ..() +/obj/item/pipe_dispenser/interact_with_atom(atom/attack_target, mob/living/user, list/modifiers) + . = NONE - if(istype(atom_to_attack, /obj/item/rpd_upgrade)) - install_upgrade(atom_to_attack, user) - return TRUE + if(!ISADVANCEDTOOLUSER(user) || HAS_TRAIT(attack_target, TRAIT_COMBAT_MODE_SKIP_INTERACTION) || istype(attack_target, /turf/open/space/transit)) + return - var/atom/attack_target = atom_to_attack + if(istype(attack_target, /obj/item/rpd_upgrade)) + var/obj/item/rpd_upgrade/rpd_disk = attack_target + + // Check if the upgrade's already present + if(rpd_disk.upgrade_flags & upgrade_flags) + balloon_alert(user, "already installed!") + return ITEM_INTERACT_BLOCKING + + // Adds the upgrade from the disk and then deletes the disk + upgrade_flags |= rpd_disk.upgrade_flags + playsound(loc, 'sound/machines/click.ogg', 50, vary = TRUE) + balloon_alert(user, "upgrade installed") + qdel(rpd_disk) + return ITEM_INTERACT_SUCCESS //So that changing the menu settings doesn't affect the pipes already being built. var/queued_pipe_type = recipe.id @@ -454,20 +320,29 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( if((mode & DESTROY_MODE) && (upgrade_flags & RPD_UPGRADE_UNWRENCH) && istype(attack_target, /obj/machinery/atmospherics) && !(DOING_INTERACTION_WITH_TARGET(user, attack_target))) attack_target = attack_target.wrench_act(user, src) if(!isatom(attack_target)) //can return null, FALSE if do_after() fails see /obj/machinery/atmospherics/wrench_act() - return TRUE + return ITEM_INTERACT_FAILURE if(istype(attack_target, /obj/machinery/atmospherics) && (mode & BUILD_MODE)) attack_target = get_turf(attack_target) - var/can_make_pipe = check_can_make_pipe(attack_target) - - . = TRUE - - if((mode & DESTROY_MODE) && istype(attack_target, /obj/item/pipe) || istype(attack_target, /obj/structure/disposalconstruct) || istype(attack_target, /obj/structure/c_transit_tube) || istype(attack_target, /obj/structure/c_transit_tube_pod) || istype(attack_target, /obj/item/pipe_meter) || istype(attack_target, /obj/structure/disposalpipe/broken)) - playsound(get_turf(src), SFX_TOOL_SWITCH, 20, TRUE) - playsound(get_turf(src), RPD_USE_SOUND, 50, TRUE) + var/can_destroy = FALSE + if((mode & DESTROY_MODE) && istype(attack_target, /obj/item/pipe)) + can_destroy = TRUE + if(!can_destroy) + var/static/list/destroyables = list( + /obj/structure/disposalconstruct, + /obj/structure/c_transit_tube, + /obj/structure/c_transit_tube_pod, + /obj/item/pipe_meter, + /obj/structure/disposalpipe/broken + ) + can_destroy = is_type_in_list(attack_target, destroyables) + if(can_destroy) + var/turf/ground = get_turf(src) + playsound(ground, SFX_TOOL_SWITCH, 20, TRUE) + playsound(ground, RPD_USE_SOUND, 50, TRUE) qdel(attack_target) - return + return ITEM_INTERACT_SUCCESS if(mode & REPROGRAM_MODE) // If this is a placed smart pipe, try to reprogram it @@ -475,16 +350,16 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( if(istype(target_smart_pipe)) if(target_smart_pipe.dir == ALL_CARDINALS) balloon_alert(user, "has no unconnected directions!") - return + return ITEM_INTERACT_FAILURE var/old_init_dir = target_smart_pipe.get_init_directions() if(old_init_dir == p_init_dir) balloon_alert(user, "already configured!") - return + return ITEM_INTERACT_FAILURE // Check for differences in unconnected directions var/target_differences = (p_init_dir ^ old_init_dir) & ~target_smart_pipe.connections if(!target_differences) balloon_alert(user, "already configured for its directions!") - return + return ITEM_INTERACT_FAILURE playsound(get_turf(src), SFX_TOOL_SWITCH, 20, TRUE) @@ -494,7 +369,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( // Double check to make sure that nothing has changed. If anything we were about to change was connected during do_after, abort if(target_differences & target_smart_pipe.connections) balloon_alert(user, "can't configure for its direction!") - return + return ITEM_INTERACT_FAILURE // Grab the current initializable directions, which may differ from old_init_dir if someone else was working on the same pipe at the same time var/current_init_dir = target_smart_pipe.get_init_directions() // Access p_init_dir directly. The RPD can change target layer and initializable directions (though not pipe type or dir) while working to dispense and connect a component, @@ -503,7 +378,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( // Don't make a smart pipe with only one connection if(ISSTUB(new_init_dir)) balloon_alert(user, "no one directional pipes allowed!") - return + return ITEM_INTERACT_FAILURE target_smart_pipe.set_init_directions(new_init_dir) // We're now reconfigured. // We can never disconnect from existing connections, but we can connect to previously unconnected directions, and should immediately do so @@ -529,108 +404,146 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( // Finally, update our internal state - update_pipe_icon also updates dir and connections target_smart_pipe.update_pipe_icon() user.visible_message(span_notice("[user] reprograms \the [target_smart_pipe]."), span_notice("You reprogram \the [target_smart_pipe].")) - return + return ITEM_INTERACT_SUCCESS + // If this is an unplaced smart pipe, try to reprogram it var/obj/item/pipe/quaternary/target_unsecured_pipe = attack_target if(istype(target_unsecured_pipe) && ispath(target_unsecured_pipe.pipe_type, /obj/machinery/atmospherics/pipe/smart)) // An unplaced pipe never has any existing connections, so just directly assign the new configuration target_unsecured_pipe.p_init_dir = p_init_dir target_unsecured_pipe.update() + return ITEM_INTERACT_SUCCESS if(mode & BUILD_MODE) switch(category) //if we've gotten this var, the target is valid if(ATMOS_CATEGORY) //Making pipes - if(!do_pipe_build(attack_target, user, params)) - return ..() + return do_pipe_build(attack_target, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_FAILURE if(DISPOSALS_CATEGORY) //Making disposals pipes - if(!can_make_pipe) - return ..() + if(!check_can_make_pipe(attack_target)) + return ITEM_INTERACT_FAILURE attack_target = get_turf(attack_target) if(isclosedturf(attack_target)) balloon_alert(user, "target is blocked!") - return + return ITEM_INTERACT_FAILURE playsound(get_turf(src), SFX_TOOL_SWITCH, 20, TRUE) - if(do_after(user, disposal_build_speed, target = attack_target)) - var/obj/structure/disposalconstruct/new_disposals_segment = new (attack_target, queued_pipe_type, queued_pipe_dir, queued_pipe_flipped) - if(!new_disposals_segment.can_place()) - balloon_alert(user, "not enough room!") - qdel(new_disposals_segment) - return + if(!do_after(user, disposal_build_speed, target = attack_target)) + return ITEM_INTERACT_FAILURE - playsound(get_turf(src), RPD_USE_SOUND, 50, TRUE) + var/obj/structure/disposalconstruct/new_disposals_segment = new (attack_target, queued_pipe_type, queued_pipe_dir, queued_pipe_flipped) - new_disposals_segment.add_fingerprint(usr) - new_disposals_segment.update_appearance() - if(mode & WRENCH_MODE) - new_disposals_segment.wrench_act(user, src) - return + if(!new_disposals_segment.can_place()) + balloon_alert(user, "not enough room!") + qdel(new_disposals_segment) + return ITEM_INTERACT_FAILURE + + playsound(get_turf(src), RPD_USE_SOUND, 50, TRUE) + + new_disposals_segment.add_fingerprint(user) + new_disposals_segment.update_appearance() + if(mode & WRENCH_MODE) + new_disposals_segment.wrench_act(user, src) + return ITEM_INTERACT_SUCCESS if(TRANSIT_CATEGORY) //Making transit tubes - if(!can_make_pipe) - return ..() + if(!check_can_make_pipe(attack_target)) + return ITEM_INTERACT_FAILURE attack_target = get_turf(attack_target) if(isclosedturf(attack_target)) balloon_alert(user, "something in the way!") - return + return ITEM_INTERACT_FAILURE var/turf/target_turf = get_turf(attack_target) if(target_turf.is_blocked_turf(exclude_mobs = TRUE)) balloon_alert(user, "something in the way!") - return + return ITEM_INTERACT_FAILURE playsound(get_turf(src), SFX_TOOL_SWITCH, 20, TRUE) - if(do_after(user, transit_build_speed, target = attack_target)) - playsound(get_turf(src), RPD_USE_SOUND, 50, TRUE) - if(queued_pipe_type == /obj/structure/c_transit_tube_pod) - var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(attack_target) - pod.add_fingerprint(usr) - if(mode & WRENCH_MODE) - pod.wrench_act(user, src) - - else - var/obj/structure/c_transit_tube/tube = new queued_pipe_type(attack_target) - tube.setDir(queued_pipe_dir) - - if(queued_pipe_flipped) - tube.setDir(turn(queued_pipe_dir, 45 + ROTATION_FLIP)) - tube.post_rotation(user, ROTATION_FLIP) - - tube.add_fingerprint(usr) - if(mode & WRENCH_MODE) - tube.wrench_act(user, src) - return - else - return ..() + if(!do_after(user, transit_build_speed, target = attack_target)) + return ITEM_INTERACT_FAILURE + + playsound(get_turf(src), RPD_USE_SOUND, 50, TRUE) + if(queued_pipe_type == /obj/structure/c_transit_tube_pod) + var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(attack_target) + pod.add_fingerprint(user) + if(mode & WRENCH_MODE) + pod.wrench_act(user, src) + + else + var/obj/structure/c_transit_tube/tube = new queued_pipe_type(attack_target) + tube.setDir(queued_pipe_dir) + if(queued_pipe_flipped) + tube.setDir(turn(queued_pipe_dir, 45 + ROTATION_FLIP)) + tube.post_rotation(user, ROTATION_FLIP) + + tube.add_fingerprint(user) + if(mode & WRENCH_MODE) + tube.wrench_act(user, src) + return ITEM_INTERACT_SUCCESS + +/obj/item/pipe_dispenser/interact_with_atom_secondary(obj/machinery/atmospherics/target, mob/living/user, list/modifiers) + . = NONE + + if(!istype(target)) + return + + if(target.pipe_color && target.piping_layer) + paint_color = GLOB.pipe_color_name[target.pipe_color] + pipe_layers = PIPE_LAYER(target.piping_layer) + balloon_alert(user, "color/layer copied") + return ITEM_INTERACT_SUCCESS + +/** + * Can we make a pipe on the target + * Arguments + * + * * atom/target_of_attack - the target we are trying to build a pipe on + */ /obj/item/pipe_dispenser/proc/check_can_make_pipe(atom/target_of_attack) + PRIVATE_PROC(TRUE) + SHOULD_BE_PURE(TRUE) + + if(isturf(target_of_attack)) + return TRUE + //make sure what we're clicking is valid for the current category - var/static/list/make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille)) - var/can_we_make_pipe = (isturf(target_of_attack) || is_type_in_typecache(target_of_attack, make_pipe_whitelist)) - return can_we_make_pipe + var/static/list/make_pipe_whitelist = typecacheof( + list( + /obj/structure/lattice, + /obj/structure/girder, + /obj/item/pipe, + /obj/structure/window, + /obj/structure/grille + ) + ) + return is_type_in_typecache(target_of_attack, make_pipe_whitelist) + +/** + * Build pipe on the target + * Arguments + * + * * atom/atom_to_target - the target we are trying to build the pipe on + * * mob/user - mob performing the action + */ +/obj/item/pipe_dispenser/proc/do_pipe_build(atom/atom_to_target, mob/user) + PRIVATE_PROC(TRUE) + + if(!check_can_make_pipe(atom_to_target)) + return FALSE -/obj/item/pipe_dispenser/proc/do_pipe_build(atom/atom_to_target, mob/user, params) //So that changing the menu settings doesn't affect the pipes already being built. var/queued_pipe_type = recipe.id var/queued_pipe_dir = p_dir var/queued_pipe_flipped = p_flipped - var/can_make_pipe = check_can_make_pipe(atom_to_target) var/list/pipe_layer_numbers = get_active_pipe_layers() - var/continued_build = FALSE - for(var/pipe_layer_num in 1 to length(pipe_layer_numbers)) - var/layer_to_build = pipe_layer_numbers[pipe_layer_num] - if(layer_to_build != pipe_layer_numbers[1]) - continued_build = TRUE - if(!layer_to_build) - return FALSE - if(!can_make_pipe) - return FALSE + for(var/layer_to_build in pipe_layer_numbers) playsound(get_turf(src), SFX_TOOL_SWITCH, 20, vary = TRUE) - if(!continued_build && !do_after(user, atmos_build_speed, target = atom_to_target)) + if(!do_after(user, atmos_build_speed, target = atom_to_target)) return FALSE - if(!recipe.all_layers && (layer_to_build == 1 || layer_to_build == 5)) + if(!recipe.all_layers && (layer_to_build == 1 || layer_to_build == MAX_PIPE_LAYERS)) balloon_alert(user, "can't build on layer [layer_to_build]!") if(multi_layer) continue @@ -657,7 +570,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( new_flippable_pipe.flipped = queued_pipe_flipped pipe_type.update() - pipe_type.add_fingerprint(usr) + pipe_type.add_fingerprint(user) pipe_type.set_piping_layer(layer_to_build) if(ispath(queued_pipe_type, /obj/machinery/atmospherics) && !ispath(queued_pipe_type, /obj/machinery/atmospherics/pipe/color_adapter)) pipe_type.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY) @@ -665,24 +578,6 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( pipe_type.wrench_act(user, src) return TRUE -/obj/item/pipe_dispenser/attackby(obj/item/item, mob/user, params) - if(istype(item, /obj/item/rpd_upgrade)) - install_upgrade(item, user) - return TRUE - return ..() - -/// Installs an upgrade into the RPD after checking if it is already installed -/obj/item/pipe_dispenser/proc/install_upgrade(obj/item/rpd_upgrade/rpd_disk, mob/user) - // Check if the upgrade's already present - if(rpd_disk.upgrade_flags & upgrade_flags) - balloon_alert(user, "already installed!") - return - // Adds the upgrade from the disk and then deletes the disk - upgrade_flags |= rpd_disk.upgrade_flags - playsound(loc, 'sound/machines/click.ogg', 50, vary = TRUE) - balloon_alert(user, "upgrade installed") - qdel(rpd_disk) - ///Changes the piping layer when the mousewheel is scrolled up or down. /obj/item/pipe_dispenser/proc/mouse_wheeled(mob/source_mob, atom/A, delta_x, delta_y, params) SIGNAL_HANDLER @@ -695,7 +590,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( return if(delta_y < 0) - pipe_layers = min(PIPE_LAYER(5), pipe_layers << 1) + pipe_layers = min(PIPE_LAYER(MAX_PIPE_LAYERS), pipe_layers << 1) else if(delta_y > 0) pipe_layers = max(PIPE_LAYER(1), pipe_layers >> 1) else //mice with side-scrolling wheels are apparently a thing and fuck this up @@ -730,3 +625,4 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( #undef PIPE_LAYER #undef RPD_USE_SOUND +#undef MAX_PIPE_LAYERS diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index 889654ba60c9..971f36ca3ec0 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -337,6 +337,7 @@ desc = "It's a stick..?" icon = 'icons/obj/weapons/staff.dmi' icon_state = "godstaff-red" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' var/conversion_color = "#ffffff" @@ -427,8 +428,14 @@ force = 24 armour_penetration = 10 +/obj/item/claymore/weak/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -9) + /obj/item/claymore/weak/ceremonial desc = "A rusted claymore, once at the heart of a powerful scottish clan struck down and oppressed by tyrants, it has been passed down the ages as a symbol of defiance." force = 15 block_chance = 30 armour_penetration = 5 + +/obj/item/claymore/weak/ceremonial/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index e6dde4750879..dd19c40eb1a6 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -654,27 +654,8 @@ require_model = TRUE model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur) model_flags = BORG_MODEL_ENGINEERING - items_to_add = list(/obj/item/inducer/cyborg) -/obj/item/inducer/cyborg - name = "Internal inducer" - icon = 'icons/obj/tools.dmi' - icon_state = "inducer-engi" - powerdevice = null - -/obj/item/inducer/cyborg/get_cell() - var/obj/item/robot_model/possible_model = loc - var/mob/living/silicon/robot/silicon_friend = istype(possible_model) ? possible_model.robot : possible_model - if(istype(silicon_friend)) - . = silicon_friend.cell - -/obj/item/inducer/cyborg/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/item/inducer/cyborg/item_interaction(mob/living/user, obj/item/tool, list/modifiers) - return ITEM_INTERACT_FAILURE - /obj/item/borg/upgrade/pinpointer name = "medical cyborg crew pinpointer" desc = "A crew pinpointer module for the medical cyborg. Permits remote access to the crew monitor." diff --git a/code/game/objects/items/rollertable_dock.dm b/code/game/objects/items/rollertable_dock.dm index d0067e8c6759..9b2c34bc61b4 100644 --- a/code/game/objects/items/rollertable_dock.dm +++ b/code/game/objects/items/rollertable_dock.dm @@ -9,23 +9,6 @@ . = ..() loaded = new(src) -/obj/structure/table/rolling/attackby(obj/item/wtable, mob/user, params) - if(!istype(wtable, /obj/item/rolling_table_dock)) - return ..() - var/obj/item/rolling_table_dock/rable = wtable - var/turf/target_table = get_turf(src) - if(rable.loaded) - to_chat(user, span_warning("You already have a roller table docked!")) - return - if(locate(/mob/living) in target_table) - to_chat(user, span_warning("You can't collect the table with that much on top!")) - return - else - rable.loaded = src - forceMove(rable) - user.visible_message(span_notice("[user] collects [src]."), balloon_alert(user, "you collect the [src].")) - return TRUE - /obj/item/rolling_table_dock/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) var/turf/target_turf = get_turf(interacting_with) if(target_turf.is_blocked_turf(TRUE) || (locate(/mob/living) in target_turf)) diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm index 701a0a819d00..a4adc353db3f 100644 --- a/code/game/objects/items/shrapnel.dm +++ b/code/game/objects/items/shrapnel.dm @@ -4,6 +4,7 @@ weak_against_armour = TRUE icon = 'icons/obj/debris.dmi' icon_state = "large" + icon_angle = -45 w_class = WEIGHT_CLASS_TINY item_flags = DROPDEL sharpness = SHARP_EDGED diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index ef21692371c4..4fa7b7d1d21d 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -1,11 +1,12 @@ //spears /obj/item/spear + name = "spear" + desc = "A haphazardly-constructed yet still deadly weapon of ancient design." icon = 'icons/obj/weapons/spear.dmi' icon_state = "spearglass0" lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' - name = "spear" - desc = "A haphazardly-constructed yet still deadly weapon of ancient design." + icon_angle = -45 force = 10 w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK @@ -18,7 +19,7 @@ hitsound = 'sound/items/weapons/bladeslice.ogg' attack_verb_continuous = list("attacks", "pokes", "jabs", "tears", "lacerates", "gores") attack_verb_simple = list("attack", "poke", "jab", "tear", "lacerate", "gore") - sharpness = SHARP_EDGED // i know the whole point of spears is that they're pointy, but edged is more devastating at the moment so + sharpness = SHARP_POINTY max_integrity = 200 armor_type = /datum/armor/item_spear wound_bonus = -15 diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index cb3bb78f6568..e5514380bf8a 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -32,16 +32,39 @@ var/sanitization /// How much we add to flesh_healing for burn wounds on application var/flesh_regeneration - /// Time it takes to assess injuries when looping healing - var/assessing_injury_delay = 1 SECONDS + /// Verb used when applying this object to someone + var/apply_verb = "treating" + /// Whether this item can be used on dead bodies + var/works_on_dead = FALSE /obj/item/stack/medical/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!isliving(interacting_with)) return NONE - if(!begin_heal_loop(interacting_with, user)) + if(!begin_heal_loop(interacting_with, user, auto_change_zone = TRUE)) return NONE // [ITEM_INTERACT_BLOCKING] would be redundant as we are nobludgeon return ITEM_INTERACT_SUCCESS +/obj/item/stack/medical/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) + if(!isliving(interacting_with)) + return NONE + if(!begin_heal_loop(interacting_with, user, auto_change_zone = FALSE)) + return NONE // see above + return ITEM_INTERACT_SUCCESS + +/obj/item/stack/medical/Initialize(mapload, new_amount, merge, list/mat_override, mat_amt) + . = ..() + register_item_context() + +/obj/item/stack/medical/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + if(!isliving(target)) + return NONE + if(iscarbon(target)) + context[SCREENTIP_CONTEXT_LMB] = "Auto Heal" + context[SCREENTIP_CONTEXT_RMB] = "Manual Heal" + else + context[SCREENTIP_CONTEXT_LMB] = "Heal" + return CONTEXTUAL_SCREENTIP_SET + /obj/item/stack/medical/apply_fantasy_bonuses(bonus) . = ..() if(heal_brute) @@ -65,134 +88,253 @@ /// Used to begin the recursive healing loop. /// Returns TRUE if we entered the loop, FALSE if we didn't -/obj/item/stack/medical/proc/begin_heal_loop(mob/living/patient, mob/user) - if(!can_heal(patient, user)) +/obj/item/stack/medical/proc/begin_heal_loop(mob/living/patient, mob/living/user, auto_change_zone = TRUE) + if(DOING_INTERACTION_WITH_TARGET(user, patient)) return FALSE - - INVOKE_ASYNC(src, PROC_REF(try_heal), patient, user) + var/heal_zone = check_zone(user.zone_selected) + if(!try_heal_checks(patient, user, heal_zone)) + return FALSE + SSblackbox.record_feedback("nested tally", "medical_item_used", 1, list("[auto_change_zone ? "auto" : "manual"]", "[type]")) + patient.balloon_alert(user, "[apply_verb] [parse_zone(heal_zone)]...") + INVOKE_ASYNC(src, PROC_REF(try_heal), patient, user, heal_zone, FALSE, iscarbon(patient) && auto_change_zone) // auto change is useless for non-carbons return TRUE -/// Checks if the passed patient can be healed by the passed user -/obj/item/stack/medical/proc/can_heal(mob/living/patient, mob/user) - return patient.try_inject(user, injection_flags = INJECT_TRY_SHOW_ERROR_MESSAGE) - -/// In which we print the message that we're starting to heal someone, then we try healing them. Does the do_after whether or not it can actually succeed on a targeted mob -/obj/item/stack/medical/proc/try_heal(mob/living/patient, mob/user, silent = FALSE, looping = FALSE) - if(!try_heal_checks(patient, user, heal_brute, heal_burn, looping)) - return - var/new_self_delay = self_delay - var/new_other_delay = other_delay - if(iscarbon(patient)) - new_self_delay = looping ? clamp((self_delay - assessing_injury_delay), 0, self_delay) : self_delay - new_other_delay = looping ? clamp((other_delay - assessing_injury_delay), 0, other_delay) : other_delay +/** + * What actually handles printing the message that we're starting to heal someone, and trying to heal them + * + * This proc is recursively called until we run out of charges OR until the patient is fully healed + * OR until the target zone is fully healed (if auto_change_zone is FALSE) + * + * * patient - The mob we're trying to heal + * * user - The mob that's trying to heal the patient + * * healed_zone - The zone we're trying to heal on the patient + * Disregarded if auto_change_zone is TRUE + * * silent - If we should not print the message that we're starting to heal the patient + * Used so looping the proc doesn't spam messages + * * auto_change_zone - Handles the behavior when we finish healing a zone + * If auto_change_zone is set to TRUE, it picks the next most damaged zone to heal + * If auto_change_zone is set to FALSE, it'll give the user a chance to pick a new zone to heal + */ +/obj/item/stack/medical/proc/try_heal(mob/living/patient, mob/living/user, healed_zone, silent = FALSE, auto_change_zone = TRUE) if(patient == user) if(!silent) user.visible_message( span_notice("[user] starts to apply [src] on [user.p_them()]self..."), span_notice("You begin applying [src] on yourself..."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) if(!do_after( user, - new_self_delay, + self_delay * (auto_change_zone ? 1 : 0.9), patient, - extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user), + extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user, healed_zone), )) return + if(!auto_change_zone) + healed_zone = check_zone(user.zone_selected) + if(!try_heal_checks(patient, user, healed_zone)) + return else if(other_delay) if(!silent) user.visible_message( span_notice("[user] starts to apply [src] on [patient]."), span_notice("You begin applying [src] on [patient]..."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) if(!do_after( user, - new_other_delay, + other_delay * (auto_change_zone ? 1 : 0.9), patient, - extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user), + extra_checks = CALLBACK(src, PROC_REF(can_heal), patient, user, healed_zone), )) return + if(!auto_change_zone) + healed_zone = check_zone(user.zone_selected) + if(!try_heal_checks(patient, user, healed_zone)) + return - if(!heal(patient, user)) - return - log_combat(user, patient, "healed", name) + else + if(!silent) + user.visible_message( + span_notice("[user] applies [src] on [patient]."), + span_notice("You apply [src] on [patient]."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + + if(iscarbon(patient)) + if(!heal_carbon(patient, user, healed_zone)) + return + else if(isanimal_or_basicmob(patient)) + if(!heal_simplemob(patient, user)) + return + else + CRASH("Stack medical item healing a non-carbon, non-animal mob [patient] ([patient.type])") + + log_combat(user, patient, "healed", src) if(!use(1) || !repeating || amount <= 0) + var/atom/alert_loc = QDELETED(src) ? user : src + alert_loc.balloon_alert(user, repeating ? "all used up!" : "treated [parse_zone(healed_zone)]") + return + + // first, just try looping + // 1. we can keep healing the current target + // 2. the user's changed their target (and thus we should heal that limb instead) + var/preferred_target = check_zone(user.zone_selected) + if(try_heal_checks(patient, user, preferred_target, silent = TRUE)) + if(preferred_target != healed_zone) + patient.balloon_alert(user, "[apply_verb] [parse_zone(preferred_target)]...") + try_heal(patient, user, preferred_target, TRUE, auto_change_zone) return - if(!can_heal(patient, user)) + + // second, handle what happens otherwise + if(!iscarbon(patient)) + // behavior 0: non-carbons have no limbs so we can assume they are fully healed + patient.balloon_alert(user, "fully treated") + else if(auto_change_zone) + // behavior 1: automatically pick another zone to heal + try_heal_auto_change_zone(patient, user, preferred_target, healed_zone) + else + // behavior 2: assess injury, giving the user time to manually pick another zone + try_heal_manual_target(patient, user) + +/obj/item/stack/medical/proc/try_heal_auto_change_zone(mob/living/carbon/patient, mob/living/user, preferred_target, last_zone) + PRIVATE_PROC(TRUE) + + var/list/other_affected_limbs = list() + for(var/obj/item/bodypart/limb as anything in patient.bodyparts) + if(!try_heal_checks(patient, user, limb.body_zone, silent = TRUE)) + continue + other_affected_limbs += limb.body_zone + + if(!length(other_affected_limbs)) + patient.balloon_alert(user, "fully treated") return - try_heal(patient, user, silent = TRUE, looping = TRUE) -/// Apply the actual effects of the healing if it's a simple animal, goes to [/obj/item/stack/medical/proc/heal_carbon] if it's a carbon, returns TRUE if it works, FALSE if it doesn't -/obj/item/stack/medical/proc/heal(mob/living/patient, mob/user) - if(patient.stat == DEAD) - patient.balloon_alert(user, "they're dead!") + var/next_picked = (preferred_target in other_affected_limbs) ? preferred_target : other_affected_limbs[1] + if(next_picked != last_zone) + patient.balloon_alert(user, "[apply_verb] [parse_zone(next_picked)]...") + try_heal(patient, user, next_picked, silent = TRUE, auto_change_zone = TRUE) + +/obj/item/stack/medical/proc/try_heal_manual_target(mob/living/carbon/patient, mob/living/user) + PRIVATE_PROC(TRUE) + + patient.balloon_alert(user, "assessing injury...") + if(!do_after(user, 1 SECONDS, patient)) + return + var/new_zone = check_zone(user.zone_selected) + if(!try_heal_checks(patient, user, new_zone)) + return + patient.balloon_alert(user, "[apply_verb] [parse_zone(new_zone)]...") + try_heal(patient, user, new_zone, silent = TRUE, auto_change_zone = FALSE) + +/// Checks if the passed patient can be healed by the passed user +/obj/item/stack/medical/proc/can_heal(mob/living/patient, mob/living/user, healed_zone, silent = FALSE) + return patient.try_inject(user, healed_zone, injection_flags = silent ? NONE : INJECT_TRY_SHOW_ERROR_MESSAGE) + +/// Checks a bunch of stuff to see if we can heal the patient, including can_heal +/// Gives a feedback if we can't ultimatly heal the patient (unless silent is TRUE) +/obj/item/stack/medical/proc/try_heal_checks(mob/living/patient, mob/living/user, healed_zone, silent = FALSE) + if(!(healed_zone in GLOB.all_body_zones)) + stack_trace("Invalid zone ([healed_zone || "null"]) passed to try_heal_checks.") + healed_zone = BODY_ZONE_CHEST + + if(!can_heal(patient, user, healed_zone, silent)) + // has its own feedback + return FALSE + if(!works_on_dead && patient.stat == DEAD) + if(!silent) + patient.balloon_alert(user, "[patient.p_theyre()] dead!") return FALSE - if(iscarbon(patient)) - return heal_carbon(patient, user, heal_brute, heal_burn) - else if(isanimal_or_basicmob(patient)) - if(!try_heal_checks(patient, user, heal_brute, heal_burn)) - return FALSE - if(patient.heal_bodypart_damage((heal_brute * patient.maxHealth/100))) - user.visible_message(span_infoplain(span_green("[user] applies [src] on [patient].")), span_infoplain(span_green("You apply [src] on [patient]."))) - return TRUE - patient.balloon_alert(user, "can't heal [patient]!") - return FALSE -/obj/item/stack/medical/proc/try_heal_checks(mob/living/patient, mob/user, brute, burn, looping = FALSE) if(iscarbon(patient)) - if(looping) - balloon_alert(user, "assessing injuries...") - if(!do_after(user, assessing_injury_delay, patient)) - return FALSE var/mob/living/carbon/carbon_patient = patient - var/obj/item/bodypart/affecting = carbon_patient.get_bodypart(check_zone(user.zone_selected)) + var/obj/item/bodypart/affecting = carbon_patient.get_bodypart(healed_zone) if(!affecting) //Missing limb? - carbon_patient.balloon_alert(user, "no [parse_zone(user.zone_selected)]!") + if(!silent) + carbon_patient.balloon_alert(user, "no [parse_zone(healed_zone)]!") return FALSE if(!IS_ORGANIC_LIMB(affecting)) //Limb must be organic to be healed - RR - carbon_patient.balloon_alert(user, "[affecting.plaintext_zone] is not organic!") + if(!silent) + carbon_patient.balloon_alert(user, "[affecting.plaintext_zone] is not organic!") return FALSE - if(!(affecting.brute_dam && brute) && !(affecting.burn_dam && burn)) - if(!affecting.brute_dam && !affecting.burn_dam) - if(patient != user || !looping) + + var/datum/wound/burn/flesh/any_burn_wound = locate() in affecting.wounds + var/can_heal_burn_wounds = (flesh_regeneration || sanitization) && any_burn_wound?.can_be_ointmented_or_meshed() + var/can_suture_bleeding = stop_bleeding && affecting.get_modified_bleed_rate() > 0 + var/brute_to_heal = heal_brute && affecting.brute_dam > 0 + var/burn_to_heal = heal_burn && affecting.burn_dam > 0 + + if(!brute_to_heal && !burn_to_heal && !can_heal_burn_wounds && !can_suture_bleeding) + if(!silent) + if(!brute_to_heal && stop_bleeding) // no brute, no bleeding + carbon_patient.balloon_alert(user, "[affecting.plaintext_zone] is not bleeding or bruised!") + else if(!burn_to_heal && (flesh_regeneration || sanitization) && any_burn_wound) // no burns, existing burn wounds are treated + carbon_patient.balloon_alert(user, "[affecting.plaintext_zone] has been fully treated!") + else if(!affecting.brute_dam && !affecting.burn_dam) // not hurt at all carbon_patient.balloon_alert(user, "[affecting.plaintext_zone] is not hurt!") - else - carbon_patient.balloon_alert(user, "can't heal [affecting.plaintext_zone] with [name]!") + else // probably hurt in some way but we are not the right item for this + carbon_patient.balloon_alert(user, "can't heal [affecting.plaintext_zone] with [name]!") return FALSE return TRUE + if(isanimal_or_basicmob(patient)) - if(patient.stat == DEAD) - patient.balloon_alert(user, "they're dead!") - return FALSE if(!heal_brute) // only brute can heal - patient.balloon_alert(user, "can't heal with [name]!") + if(!silent) + patient.balloon_alert(user, "can't heal with [name]!") return FALSE if(!(patient.mob_biotypes & MOB_ORGANIC)) - patient.balloon_alert(user, "no organic tissue!") + if(!silent) + patient.balloon_alert(user, "no organic tissue!") return FALSE if(patient.health == patient.maxHealth) - patient.balloon_alert(user, "not hurt!") + if(!silent) + patient.balloon_alert(user, "not hurt!") return FALSE return TRUE + return FALSE -/// The healing effects on a carbon patient. Since we have extra details for dealing with bodyparts, we get our own fancy proc. Still returns TRUE on success and FALSE on fail -/obj/item/stack/medical/proc/heal_carbon(mob/living/carbon/patient, mob/user, brute, burn) - var/obj/item/bodypart/affecting = patient.get_bodypart(check_zone(user.zone_selected)) - if(!try_heal_checks(patient, user, brute, burn)) - return FALSE +/// The healing effects on a carbon patient. +/// Since we have extra details for dealing with bodyparts, we get our own fancy proc. +/// Still returns TRUE on success and FALSE on fail +/obj/item/stack/medical/proc/heal_carbon(mob/living/carbon/patient, mob/living/user, healed_zone) + var/obj/item/bodypart/affecting = patient.get_bodypart(healed_zone) user.visible_message( - span_infoplain(span_green("[user] applies [src] on [patient]'s [affecting.plaintext_zone].")), - span_infoplain(span_green("You apply [src] on [patient]'s [affecting.plaintext_zone].")) + span_green("[user] applies [src] on [patient]'s [affecting.plaintext_zone]."), + span_green("You apply [src] on [patient]'s [affecting.plaintext_zone]."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) var/previous_damage = affecting.get_damage() - if(affecting.heal_damage(brute, burn)) + if(affecting.heal_damage(heal_brute, heal_burn)) patient.update_damage_overlays() + if(stop_bleeding) + for(var/datum/wound/wound as anything in affecting.wounds) + if(wound.blood_flow) + wound.adjust_blood_flow(-1 * stop_bleeding * (user == patient ? 0.7 : 1)) + break // one at a time + affecting.adjustBleedStacks(-1 * stop_bleeding, 0) + if(flesh_regeneration || sanitization) + for(var/datum/wound/burn/flesh/wound as anything in affecting.wounds) + if(wound.can_be_ointmented_or_meshed()) + wound.flesh_healing += flesh_regeneration + wound.sanitization += sanitization + break // one at a time post_heal_effects(max(previous_damage - affecting.get_damage(), 0), patient, user) return TRUE -///Override this proc for special post heal effects. -/obj/item/stack/medical/proc/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/user) +/// Healing a simple mob, just an adjustbruteloss call +/obj/item/stack/medical/proc/heal_simplemob(mob/living/patient, mob/living/user) + patient.adjustBruteLoss(-1 * (heal_brute * patient.maxHealth / 100)) + user.visible_message( + span_green("[user] applies [src] on [patient]."), + span_green("You apply [src] on [patient]."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) + return TRUE + +///Override this proc for special post heal effects. Only called for carbon patients. +/obj/item/stack/medical/proc/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/living/user) return /obj/item/stack/medical/bruise_pack @@ -207,6 +349,7 @@ other_delay = 2 SECONDS grind_results = list(/datum/reagent/medicine/c2/libital = 10) merge_type = /obj/item/stack/medical/bruise_pack + apply_verb = "applying to" /obj/item/stack/medical/bruise_pack/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -229,6 +372,8 @@ splint_factor = 0.7 burn_cleanliness_bonus = 0.35 merge_type = /obj/item/stack/medical/gauze + apply_verb = "wrapping" + works_on_dead = TRUE var/obj/item/bodypart/gauzed_bodypart /obj/item/stack/medical/gauze/Destroy(force) @@ -239,47 +384,77 @@ SEND_SIGNAL(gauzed_bodypart, COMSIG_BODYPART_UNGAUZED, src) gauzed_bodypart = null -// gauze is only relevant for wounds, which are handled in the wounds themselves -/obj/item/stack/medical/gauze/try_heal(mob/living/patient, mob/user, silent, looping) - - var/treatment_delay = (user == patient ? self_delay : other_delay) +/obj/item/stack/medical/gauze/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + if(iscarbon(target)) + context[SCREENTIP_CONTEXT_LMB] = "Apply Gauze" + return CONTEXTUAL_SCREENTIP_SET + return NONE - var/obj/item/bodypart/limb = patient.get_bodypart(check_zone(user.zone_selected)) - if(!limb) - patient.balloon_alert(user, "missing limb!") - return +/obj/item/stack/medical/gauze/try_heal_checks(mob/living/patient, mob/living/user, healed_zone, silent = FALSE) + var/obj/item/bodypart/limb = patient.get_bodypart(healed_zone) + if(isnull(limb)) + if(!silent) + patient.balloon_alert(user, "no [parse_zone(healed_zone)]!") + return FALSE if(!LAZYLEN(limb.wounds)) - patient.balloon_alert(user, "no wounds!") // good problem to have imo - return - - var/gauzeable_wound = FALSE - var/datum/wound/woundies - for(var/i in limb.wounds) - woundies = i + if(!silent) + patient.balloon_alert(user, "no wounds!") // good problem to have imo + return FALSE + if(limb.current_gauze && (limb.current_gauze.absorption_capacity * 1.2 > absorption_capacity)) // ignore if our new wrap is < 20% better than the current one, so someone doesn't bandage it 5 times in a row + if(!silent) + patient.balloon_alert(user, pick("already bandaged!", "bandage is clean!")) // good enough + return FALSE + for(var/datum/wound/woundies as anything in limb.wounds) if(woundies.wound_flags & ACCEPTS_GAUZE) - gauzeable_wound = TRUE - break - if(!gauzeable_wound) - patient.balloon_alert(user, "can't heal those!") - return + return TRUE + if(!silent) + patient.balloon_alert(user, "can't gauze!") + return FALSE - if(limb.current_gauze && (limb.current_gauze.absorption_capacity * 1.2 > absorption_capacity)) // ignore if our new wrap is < 20% better than the current one, so someone doesn't bandage it 5 times in a row - patient.balloon_alert(user, pick("already bandaged!", "bandage is clean!")) // good enough - return +// gauze is only relevant for wounds, which are handled in the wounds themselves +/obj/item/stack/medical/gauze/try_heal(mob/living/patient, mob/living/user, healed_zone, silent, auto_change_zone) + var/obj/item/bodypart/limb = patient.get_bodypart(healed_zone) + var/treatment_delay = (user == patient ? self_delay : other_delay) + var/any_scanned = FALSE + for(var/datum/wound/woundies as anything in limb.wounds) + if(HAS_TRAIT(woundies, TRAIT_WOUND_SCANNED)) + any_scanned = TRUE + break - if(HAS_TRAIT(woundies, TRAIT_WOUND_SCANNED)) + if(any_scanned) treatment_delay *= 0.5 if(user == patient) - to_chat(user, span_notice("You keep in mind the indications from the holo-image about your injury, and expertly begin wrapping your wounds with [src].")) + if(!silent) + user.visible_message( + span_warning("[user] begins expertly wrapping the wounds on [p_their()]'s [limb.plaintext_zone] with [src]..."), + span_warning("You begin quickly wrapping the wounds on your [limb.plaintext_zone] with [src], keeping the holo-image indications in mind..."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) else - user.visible_message(span_warning("[user] begins expertly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), span_warning("You begin quickly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src], keeping the holo-image indications in mind...")) + if(!silent) + user.visible_message( + span_warning("[user] begins expertly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), + span_warning("You begin quickly wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src], keeping the holo-image indications in mind..."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) else - user.visible_message(span_warning("[user] begins wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), span_warning("You begin wrapping the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]...")) + if(!silent) + user.visible_message( + span_warning("[user] begins wrapping the wounds on [patient]'s [limb.plaintext_zone] with [src]..."), + span_warning("You begin wrapping the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone] with [src]..."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) if(!do_after(user, treatment_delay, target = patient)) return - user.visible_message(span_infoplain(span_green("[user] applies [src] to [patient]'s [limb.plaintext_zone].")), span_infoplain(span_green("You bandage the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone]."))) + if(!silent) + patient.balloon_alert(user, "wrapped [parse_zone(healed_zone)]") + user.visible_message( + span_green("[user] applies [src] to [patient]'s [limb.plaintext_zone]."), + span_green("You bandage the wounds on [user == patient ? "your" : "[patient]'s"] [limb.plaintext_zone]."), + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, + ) limb.apply_gauze(src) /obj/item/stack/medical/gauze/twelve @@ -342,6 +517,7 @@ stop_bleeding = 0.6 grind_results = list(/datum/reagent/medicine/spaceacillin = 2) merge_type = /obj/item/stack/medical/suture + apply_verb = "suturing" /obj/item/stack/medical/suture/emergency name = "emergency suture" @@ -378,6 +554,7 @@ sanitization = 0.25 grind_results = list(/datum/reagent/medicine/c2/lenturi = 10) merge_type = /obj/item/stack/medical/ointment + apply_verb = "applying to" /obj/item/stack/medical/ointment/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is squeezing [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?")) @@ -413,10 +590,11 @@ return ..() icon_state = "regen_mesh_closed" -/obj/item/stack/medical/mesh/try_heal(mob/living/patient, mob/user, silent = FALSE, looping) +/obj/item/stack/medical/mesh/try_heal_checks(mob/living/patient, mob/living/user, healed_zone, silent = FALSE) if(!is_open) - balloon_alert(user, "open it first!") - return + if(!silent) + balloon_alert(user, "open it first!") + return FALSE return ..() /obj/item/stack/medical/mesh/click_alt(mob/living/user) @@ -474,6 +652,11 @@ heal_burn = 3 grind_results = list(/datum/reagent/consumable/aloejuice = 1) merge_type = /obj/item/stack/medical/aloe + apply_verb = "applying to" + +/obj/item/stack/medical/aloe/Initialize(mapload, new_amount, merge, list/mat_override, mat_amt) + . = ..() + AddComponent(/datum/component/bakeable, /obj/item/food/badrecipe, rand(10 SECONDS, 15 SECONDS), FALSE) /obj/item/stack/medical/aloe/fresh amount = 2 @@ -494,6 +677,7 @@ grind_results = list(/datum/reagent/bone_dust = 10, /datum/reagent/carbon = 10) novariants = TRUE merge_type = /obj/item/stack/medical/bone_gel + apply_verb = "applying to" /obj/item/stack/medical/bone_gel/get_surgery_tool_overlay(tray_extended) return "gel" + (tray_extended ? "" : "_out") @@ -512,16 +696,14 @@ return BRUTELOSS patient.emote("scream") - for(var/i in patient.bodyparts) - var/obj/item/bodypart/bone = i // fine to just, use these raw, its a meme anyway + for(var/obj/item/bodypart/bone as anything in patient.bodyparts) + // fine to just, use these raw, its a meme anyway var/datum/wound/blunt/bone/severe/oof_ouch = new oof_ouch.apply_wound(bone, wound_source = "bone gel") var/datum/wound/blunt/bone/critical/oof_OUCH = new oof_OUCH.apply_wound(bone, wound_source = "bone gel") - - for(var/i in patient.bodyparts) - var/obj/item/bodypart/bone = i - bone.receive_damage(brute=60) + for(var/zone in GLOB.all_body_zones) + patient.apply_damage(60, BRUTE, zone) use(1) return BRUTELOSS @@ -531,7 +713,11 @@ /obj/item/stack/medical/poultice name = "mourning poultices" singular_name = "mourning poultice" - desc = "A type of primitive herbal poultice.\nWhile traditionally used to prepare corpses for the mourning feast, it can also treat scrapes and burns on the living, however, it is liable to cause shortness of breath when employed in this manner.\nIt is imbued with ancient wisdom." + desc = "A type of primitive herbal poultice.\n\ + While traditionally used to prepare corpses for the mourning feast, \ + it can also treat scrapes and burns on the living, however, \ + it is liable to cause shortness of breath when employed in this manner.\n\ + It is imbued with ancient wisdom." icon_state = "poultice" amount = 15 max_amount = 15 @@ -544,15 +730,12 @@ mob_throw_hit_sound = 'sound/misc/moist_impact.ogg' hitsound = 'sound/misc/moist_impact.ogg' merge_type = /obj/item/stack/medical/poultice + apply_verb = "applying to" + works_on_dead = TRUE -/obj/item/stack/medical/poultice/heal(mob/living/patient, mob/user) - if(iscarbon(patient)) - playsound(src, 'sound/misc/soggy.ogg', 30, TRUE) - return heal_carbon(patient, user, heal_brute, heal_burn) - return ..() - -/obj/item/stack/medical/poultice/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/user) +/obj/item/stack/medical/poultice/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/living/user) . = ..() + playsound(src, 'sound/misc/soggy.ogg', 30, TRUE) healed_mob.adjustOxyLoss(amount_healed) /obj/item/stack/medical/bandage @@ -570,6 +753,7 @@ self_delay = 3 SECONDS other_delay = 1 SECONDS grind_results = list(/datum/reagent/medicine/c2/libital = 2) + apply_verb = "applying to" /obj/item/stack/medical/bandage/makeshift name = "makeshift bandage" diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 8415ffa3f407..a3340fbd43a9 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -287,6 +287,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( desc = "A nasty looking shard of glass." icon = 'icons/obj/debris.dmi' icon_state = "large" + icon_angle = -45 w_class = WEIGHT_CLASS_TINY force = 5 throwforce = 10 diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 0451cd9834b6..ce33ab856fa4 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -353,6 +353,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("bonfire", /obj/structure/bonfire, 10, time = 6 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_TOOLS), \ new/datum/stack_recipe("easel", /obj/structure/easel, 5, time = 1 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_ENTERTAINMENT), \ new/datum/stack_recipe("noticeboard", /obj/item/wallframe/noticeboard, 1, time = 1 SECONDS, crafting_flags = NONE, category = CAT_FURNITURE), \ + new/datum/stack_recipe("fish mount", /obj/item/wallframe/fish, 2, time = 3 SECONDS, crafting_flags = NONE, category = CAT_FURNITURE),\ new/datum/stack_recipe("test tube rack", /obj/item/storage/test_tube_rack, 1, time = 1 SECONDS, crafting_flags = NONE, category = CAT_CHEMISTRY), \ null, \ new/datum/stack_recipe_list("pews", list( diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 3235a0e7c053..da8e93fa09c3 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -469,6 +469,7 @@ /obj/item/reagent_containers/medigel, /obj/item/reagent_containers/pill, /obj/item/reagent_containers/syringe, + /obj/item/reagent_containers/cup/vial, // NOVA EDIT ADDITION )) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 07a5579241e8..6e1f7348e8a7 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -46,35 +46,9 @@ . = ..() atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL atom_storage.max_total_storage = 21 - atom_storage.set_holdable(list( - /obj/item/airlock_painter, - /obj/item/analyzer, - /obj/item/assembly/signaler, + atom_storage.set_holdable(GLOB.tool_items + list( /obj/item/clothing/gloves, - /obj/item/construction/rcd, - /obj/item/construction/rld, - /obj/item/construction/rtd, - /obj/item/crowbar, - /obj/item/extinguisher/mini, - /obj/item/flashlight, - /obj/item/forcefield_projector, - /obj/item/geiger_counter, - /obj/item/holosign_creator/atmos, - /obj/item/holosign_creator/engineering, - /obj/item/inducer, - /obj/item/lightreplacer, - /obj/item/multitool, - /obj/item/pipe_dispenser, - /obj/item/pipe_painter, - /obj/item/plunger, /obj/item/radio, - /obj/item/screwdriver, - /obj/item/stack/cable_coil, - /obj/item/t_scanner, - /obj/item/weldingtool, - /obj/item/wirecutters, - /obj/item/wrench, - /obj/item/spess_knife, /obj/item/melee/sickly_blade/lock, /obj/item/reagent_containers/cup/soda_cans, /obj/item/construction/plumbing, // NOVA EDIT ADDITION @@ -756,7 +730,7 @@ atom_storage.set_holdable(list( /obj/item/ammo_casing/strilka310, /obj/item/ammo_casing/shotgun, - /obj/item/ammo_casing/a357, + /obj/item/ammo_casing/c357, /obj/item/ammo_casing/junk, )) diff --git a/code/game/objects/items/storage/boxes/engineering_boxes.dm b/code/game/objects/items/storage/boxes/engineering_boxes.dm index 09f641ec3152..b30aaed9f682 100644 --- a/code/game/objects/items/storage/boxes/engineering_boxes.dm +++ b/code/game/objects/items/storage/boxes/engineering_boxes.dm @@ -82,6 +82,7 @@ /obj/item/storage/box/material=1, /obj/item/uplink/debug=1, /obj/item/uplink/nuclear/debug=1, + /obj/item/clothing/ears/earmuffs/debug = 1, ) generate_items_inside(items_inside,src) diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 0f9ae43be893..4cacde34b309 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -23,6 +23,15 @@ var/latches = "single_latch" var/has_latches = TRUE wound_bonus = 5 + /// How many interactions are we currently performing + var/current_interactions = 0 + /// Items we should not interact with when left clicking + var/static/list/lmb_exception_typecache = typecacheof(list( + /obj/structure/table, + /obj/structure/rack, + /obj/structure/closet, + /obj/machinery/disposal, + )) /obj/item/storage/toolbox/Initialize(mapload) . = ..() @@ -32,11 +41,79 @@ latches = "double_latch" if(prob(1)) latches = "triple_latch" + if(prob(0.1)) + latches = "quad_latch" // like winning the lottery, but worse update_appearance() atom_storage.open_sound = 'sound/items/handling/toolbox/toolbox_open.ogg' atom_storage.rustle_sound = 'sound/items/handling/toolbox/toolbox_rustle.ogg' AddElement(/datum/element/falling_hazard, damage = force, wound_bonus = wound_bonus, hardhat_safety = TRUE, crushes = FALSE, impact_sound = hitsound) +/obj/item/storage/toolbox/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if (user.combat_mode || !user.has_hand_for_held_index(user.get_inactive_hand_index())) + return NONE + + if (is_type_in_typecache(interacting_with, lmb_exception_typecache) && !LAZYACCESS(modifiers, RIGHT_CLICK)) + return NONE + + if (current_interactions) + var/obj/item/other_tool = user.get_inactive_held_item() + if (!istype(other_tool)) // what even + return NONE + INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, other_tool) + return ITEM_INTERACT_SUCCESS + + if (user.get_inactive_held_item()) + user.balloon_alert(user, "hands busy!") + return ITEM_INTERACT_BLOCKING + + var/list/item_radial = list() + for (var/obj/item/tool in atom_storage.real_location) + if(is_type_in_list(tool, GLOB.tool_items)) + item_radial[tool] = tool.appearance + + if (!length(item_radial)) + return NONE + + playsound(user, 'sound/items/handling/toolbox/toolbox_open.ogg', 50) + var/obj/item/picked_item = show_radial_menu(user, interacting_with, item_radial, require_near = TRUE) + if (!picked_item) + return ITEM_INTERACT_BLOCKING + + playsound(user, 'sound/items/handling/toolbox/toolbox_rustle.ogg', 50) + if (!user.put_in_inactive_hand(picked_item)) + return ITEM_INTERACT_BLOCKING + + atom_storage.animate_parent() + if (istype(picked_item, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = picked_item + if (!welder.welding) + welder.attack_self(user) + + if (istype(picked_item, /obj/item/spess_knife)) + picked_item.attack_self(user) + + INVOKE_ASYNC(src, PROC_REF(use_tool_on), interacting_with, user, modifiers, picked_item) + return ITEM_INTERACT_SUCCESS + +/obj/item/storage/toolbox/proc/use_tool_on(atom/interacting_with, mob/living/user, list/modifiers, obj/item/picked_tool) + current_interactions += 1 + picked_tool.melee_attack_chain(user, interacting_with, list2params(modifiers)) + current_interactions -= 1 + + if (QDELETED(picked_tool) || picked_tool.loc != user || !user.CanReach(picked_tool)) + current_interactions = 0 + return + + if (current_interactions) + return + + if (istype(picked_tool, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = picked_tool + if (welder.welding) + welder.attack_self(user) + + atom_storage.attempt_insert(picked_tool, user) + /obj/item/storage/toolbox/update_overlays() . = ..() if(has_latches) @@ -107,6 +184,12 @@ /obj/item/storage/toolbox/mechanical/old/heirloom/PopulateContents() return +// version of below that isn't a traitor item +/obj/item/storage/toolbox/mechanical/old/cleaner + name = "old blue toolbox" + icon_state = "oldtoolboxclean" + icon_state = "toolbox_blue_old" + /obj/item/storage/toolbox/mechanical/old/clean // the assistant traitor toolbox, damage scales with TC inside name = "toolbox" desc = "An old, blue toolbox, it looks robust." @@ -227,6 +310,51 @@ new /obj/item/stack/pipe_cleaner_coil/white(src) new /obj/item/stack/pipe_cleaner_coil/brown(src) +/obj/item/storage/toolbox/medical + name = "medical toolbox" + desc = "A toolbox painted soft white and light blue. This is getting ridiculous." + icon_state = "medical" + inhand_icon_state = "toolbox_medical" + attack_verb_continuous = list("treats", "surgeries", "tends", "tends wounds on") + attack_verb_simple = list("treat", "surgery", "tend", "tend wounds on") + w_class = WEIGHT_CLASS_BULKY + material_flags = NONE + force = 5 // its for healing + wound_bonus = 25 // wounds are medical right? + /// Tray we steal the og contents from. + var/obj/item/surgery_tray/tray_type = /obj/item/surgery_tray + +/obj/item/storage/toolbox/medical/Initialize(mapload) + . = ..() + // what do any of these numbers fucking mean + atom_storage.max_total_storage = 20 + atom_storage.max_slots = 11 + +/obj/item/storage/toolbox/medical/PopulateContents() + var/atom/fake_tray = new tray_type(get_turf(src)) // not in src lest it fill storage that we need for its tools later + for(var/atom/movable/thingy in fake_tray) + thingy.forceMove(src) + qdel(fake_tray) + +/obj/item/storage/toolbox/medical/full + tray_type = /obj/item/surgery_tray/full + +/obj/item/storage/toolbox/medical/coroner + name = "coroner toolbox" + desc = "A toolbox painted soft white and dark grey. This is getting beyond ridiculous." + icon_state = "coroner" + inhand_icon_state = "toolbox_coroner" + attack_verb_continuous = list("dissects", "autopsies", "corones") + attack_verb_simple = list("dissect", "autopsy", "corone") + w_class = WEIGHT_CLASS_BULKY + material_flags = NONE + force = 17 // it's not for healing + tray_type = /obj/item/surgery_tray/full/morgue + +/obj/item/storage/toolbox/medical/coroner/Initialize(mapload) + . = ..() + AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity + /obj/item/storage/toolbox/ammobox name = "ammo canister" desc = "A metal canister designed to hold ammunition" @@ -337,6 +465,78 @@ for(var/i in 1 to 3) new extra_to_spawn (src) +/obj/item/storage/toolbox/guncase/traitor + name = "makarov gun case" + desc = "A weapon's case. Has a blood-red 'S' stamped on the cover. There seems to be a strange switch along the side inside a plastic flap." + icon_state = "pistol_case" + base_icon_state = "pistol_case" + // What ammo box do we spawn in our case? + var/ammo_box_to_spawn = /obj/item/ammo_box/c9mm + // Timer for the bomb in the case. + var/explosion_timer + // Whether or not our case is exploding. Used for determining sprite changes. + var/currently_exploding = FALSE + +/obj/item/storage/toolbox/guncase/traitor/Initialize(mapload) + . = ..() + register_context() + +/obj/item/storage/toolbox/guncase/traitor/examine(mob/user) + . = ..() + . += span_notice("Activate the Evidence Disposal Explosive using Alt-Right-Click.") + +/obj/item/storage/toolbox/guncase/traitor/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + context[SCREENTIP_CONTEXT_ALT_RMB] = "Activate Evidence Disposal Explosive" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/storage/toolbox/guncase/traitor/PopulateContents() + new weapon_to_spawn (src) + for(var/i in 1 to 2) + new extra_to_spawn (src) + new ammo_box_to_spawn(src) + +/obj/item/storage/toolbox/guncase/traitor/update_icon_state() + . = ..() + if(currently_exploding) + icon_state = "[base_icon_state]_exploding" + else + icon_state = "[base_icon_state]" + +/obj/item/storage/toolbox/guncase/traitor/click_alt_secondary(mob/user) + . = ..() + var/i_dont_even_think_once_about_blowing_stuff_up = tgui_alert(user, "Would you like to activate the evidence disposal bomb now?", "BYE BYE", list("Yes","No")) + if(i_dont_even_think_once_about_blowing_stuff_up == "No") + return + explosion_timer = addtimer(CALLBACK(src, PROC_REF(think_fast_chucklenuts)), 5 SECONDS, (TIMER_UNIQUE|TIMER_OVERRIDE)) + to_chat(user, span_warning("You prime [src]'s evidence disposal bomb!")) + log_bomber(user, "has activated a", src, "for detonation") + playsound(src, 'sound/items/weapons/armbomb.ogg', 50, TRUE) + currently_exploding = TRUE + update_appearance() + +/// proc to handle our detonation +/obj/item/storage/toolbox/guncase/traitor/proc/think_fast_chucklenuts() + explosion(src, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 2, explosion_cause = src) + qdel(src) + +/obj/item/storage/toolbox/guncase/traitor/ammunition + name = "makarov 9mm magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/m9mm + +/obj/item/storage/toolbox/guncase/traitor/donksoft + name = "\improper Donksoft riot pistol gun case" + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/toy/riot/clandestine + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + +/obj/item/storage/toolbox/guncase/traitor/ammunition/donksoft + name = "\improper Donksoft riot pistol magazine case" + weapon_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + extra_to_spawn = /obj/item/ammo_box/magazine/toy/pistol/riot + ammo_box_to_spawn = /obj/item/ammo_box/foambox/riot + /obj/item/storage/toolbox/guncase/bulldog name = "bulldog gun case" weapon_to_spawn = /obj/item/gun/ballistic/shotgun/bulldog diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 4eaaefe4b73d..43f726fd74ac 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -348,6 +348,22 @@ new /obj/item/gun/ballistic/rifle/rebarxbow/syndie(src) new /obj/item/storage/bag/rebar_quiver/syndicate(src) +/obj/item/paper/syndicate_forensics_spoofer + name = "Forensics Spoofer Guide" + default_raw_text = {" + Forensics Spoofer Info:
+ The spoofer has two modes: SCAN which scans for fingerprints and fibers, and APPLY which applies the currently chosen fingerprint/fiber to your target.
+ The spoofer can only store 5 fingerprints and 5 fibers, and may not store or report fibers/prints already stored. Additionally, it taps into the stations network to associate scanned fingerprints with names.
+ The spoofer will make the same sounds and sights as a forensics scanner, when silent mode is off.
+ "} + +/obj/item/storage/box/syndie_kit/forensics_spoofer + name = "forensics spoofing kit" + +/obj/item/storage/box/syndie_kit/forensics_spoofer/PopulateContents() + new /obj/item/forensics_spoofer(src) + new /obj/item/paper/syndicate_forensics_spoofer(src) + /obj/item/storage/box/syndie_kit/origami_bundle name = "origami kit" desc = "A box full of a number of rather masterfully engineered paper planes and a manual on \"The Art of Origami\"." @@ -461,7 +477,7 @@ /obj/item/storage/box/syndie_kit/chemical/Initialize(mapload) . = ..() - atom_storage.max_slots = 14 + atom_storage.max_slots = 15 /obj/item/storage/box/syndie_kit/chemical/PopulateContents() new /obj/item/reagent_containers/cup/bottle/polonium(src) @@ -469,6 +485,7 @@ new /obj/item/reagent_containers/cup/bottle/fentanyl(src) new /obj/item/reagent_containers/cup/bottle/formaldehyde(src) new /obj/item/reagent_containers/cup/bottle/spewium(src) + new /obj/item/reagent_containers/cup/bottle/syndol(src) new /obj/item/reagent_containers/cup/bottle/cyanide(src) new /obj/item/reagent_containers/cup/bottle/histamine(src) new /obj/item/reagent_containers/cup/bottle/initropidril(src) diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index cf5d66f8d55b..d5a67dba68a5 100644 --- a/code/game/objects/items/surgery_tray.dm +++ b/code/game/objects/items/surgery_tray.dm @@ -1,3 +1,4 @@ + /** * Surgery Trays * A storage object that displays tools in its contents based on tier, better tools are more visible. @@ -16,11 +17,17 @@ /// If true we're currently portable var/is_portable = TRUE + /// List of contents to populate with in populatecontents() + var/list/starting_items = list() + /// Fills the tray with items it should contain on creation /obj/item/surgery_tray/proc/populate_contents() + for(var/obj in starting_items) + new obj(src) + update_appearance(UPDATE_ICON) return -/obj/item/surgery_tray/Initialize(mapload) +/obj/item/surgery_tray/Initialize(mapload, effect_spawner = FALSE) . = ..() AddElement(/datum/element/drag_pickup) create_storage(storage_type = /datum/storage/surgery_tray) @@ -159,59 +166,103 @@ is_portable = FALSE /obj/item/surgery_tray/full + starting_items = list( + /obj/item/blood_filter, + /obj/item/bonesetter, + /obj/item/cautery, + /obj/item/circular_saw, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/suit/toggle/labcoat/nova/hospitalgown, // NOVA EDIT ADDITION + /obj/item/hemostat, + /obj/item/razor/surgery, + /obj/item/retractor, + /obj/item/scalpel, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/sticky_tape/surgical, + /obj/item/surgical_drapes, + /obj/item/surgicaldrill, + ) /obj/item/surgery_tray/full/deployed is_portable = FALSE -/obj/item/surgery_tray/full/populate_contents() - new /obj/item/blood_filter(src) - new /obj/item/bonesetter(src) - new /obj/item/cautery(src) - new /obj/item/circular_saw(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/suit/toggle/labcoat/nova/hospitalgown(src) // NOVA EDIT ADDITION - new /obj/item/hemostat(src) - new /obj/item/razor/surgery(src) - new /obj/item/retractor(src) - new /obj/item/scalpel(src) - new /obj/item/stack/medical/bone_gel(src) - new /obj/item/stack/sticky_tape/surgical(src) - new /obj/item/surgical_drapes(src) - new /obj/item/surgicaldrill(src) - update_appearance(UPDATE_OVERLAYS) - /obj/item/surgery_tray/full/morgue name = "autopsy tray" desc = "A Deforest brand surgery tray, made for use in morgues. It is a folding model, \ meaning the wheels on the bottom can be extended outwards, making it a cart." + starting_items = list( + /obj/item/blood_filter, + /obj/item/bonesetter, + /obj/item/cautery/cruel, + /obj/item/circular_saw, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/suit/toggle/labcoat/nova/hospitalgown, // NOVA EDIT ADDITION + /obj/item/hemostat/cruel, + /obj/item/razor/surgery, + /obj/item/retractor/cruel, + /obj/item/scalpel/cruel, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/sticky_tape/surgical, + /obj/item/surgical_drapes, + /obj/item/surgicaldrill, + ) -/obj/item/surgery_tray/full/morgue/populate_contents() - new /obj/item/blood_filter(src) - new /obj/item/bonesetter(src) - new /obj/item/cautery/cruel(src) - new /obj/item/circular_saw(src) - new /obj/item/clothing/mask/surgical(src) - new /obj/item/clothing/suit/toggle/labcoat/nova/hospitalgown(src) // NOVA EDIT ADDITION - new /obj/item/hemostat/cruel(src) - new /obj/item/razor/surgery(src) - new /obj/item/retractor/cruel(src) - new /obj/item/scalpel/cruel(src) - new /obj/item/stack/medical/bone_gel(src) - new /obj/item/stack/sticky_tape/surgical(src) - new /obj/item/surgical_drapes(src) - new /obj/item/surgicaldrill(src) +/obj/item/surgery_tray/full/morgue/deployed + is_portable = FALSE /// Surgery tray with advanced tools for debug /obj/item/surgery_tray/full/advanced + starting_items = list( + /obj/item/scalpel/advanced, + /obj/item/retractor/advanced, + /obj/item/cautery/advanced, + /obj/item/surgical_drapes, + /obj/item/reagent_containers/medigel/sterilizine, + /obj/item/bonesetter, + /obj/item/blood_filter, + /obj/item/stack/medical/bone_gel, + /obj/item/stack/sticky_tape/surgical, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/suit/toggle/labcoat/nova/hospitalgown, // NOVA EDIT ADDITION + ) + +/obj/effect/spawner/surgery_tray + name = "surgery tray spawner" + icon = 'icons/obj/medical/medicart.dmi' + icon_state = "tray" + /// Tray to usually spawn in. + var/tray_to_spawn = /obj/item/surgery_tray + /// Toolbox to sometimes replace the above tray with. + var/rare_toolbox_replacement = /obj/item/storage/toolbox/medical + /// Chance for replacement + var/toolbox_chance = 1 + +/obj/effect/spawner/surgery_tray/Initialize(mapload) + . = ..() + if(prob(toolbox_chance)) + new rare_toolbox_replacement(loc) + return + new tray_to_spawn(loc, TRUE) + +/obj/effect/spawner/surgery_tray/full + name = "full surgery tray spawner" + icon_state = "tray" + tray_to_spawn = /obj/item/surgery_tray/full + rare_toolbox_replacement = /obj/item/storage/toolbox/medical/full + +/obj/effect/spawner/surgery_tray/full/deployed + name = "full deployed tray spawner" + icon_state = "medicart" + tray_to_spawn = /obj/item/surgery_tray/full + +/obj/effect/spawner/surgery_tray/full/morgue + name = "full autopsy tray spawner" + icon_state = "tray" + tray_to_spawn = /obj/item/surgery_tray/full/morgue + rare_toolbox_replacement = /obj/item/storage/toolbox/medical/coroner + toolbox_chance = 3 // tray is rarer, so toolbox is more common -/obj/item/surgery_tray/full/advanced/populate_contents() - new /obj/item/scalpel/advanced(src) - new /obj/item/retractor/advanced(src) - new /obj/item/cautery/advanced(src) - new /obj/item/surgical_drapes(src) - new /obj/item/reagent_containers/medigel/sterilizine(src) - new /obj/item/bonesetter(src) - new /obj/item/blood_filter(src) - new /obj/item/stack/medical/bone_gel(src) - new /obj/item/stack/sticky_tape/surgical(src) - new /obj/item/clothing/mask/surgical(src) +/obj/effect/spawner/surgery_tray/full/morgue/deployed + name = "full deployed autopsy tray spawner" + icon_state = "medicart" + tray_to_spawn = /obj/item/surgery_tray/full/morgue/deployed diff --git a/code/game/objects/items/syndie_spraycan.dm b/code/game/objects/items/syndie_spraycan.dm index 5690ecb7a28c..bc1910595d42 100644 --- a/code/game/objects/items/syndie_spraycan.dm +++ b/code/game/objects/items/syndie_spraycan.dm @@ -171,7 +171,7 @@ /// Timer until the rune can be cleaned up off the floor var/protected_timer -/obj/effect/decal/cleanable/traitor_rune/traitor/Destroy() +/obj/effect/decal/cleanable/traitor_rune/Destroy() deltimer(protected_timer) QDEL_NULL(demoraliser) return ..() diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 6976c936b665..674e50caade0 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -53,6 +53,7 @@ COMSIG_JETPACK_DEACTIVATED, \ JETPACK_ACTIVATION_FAILED, \ thrust_callback, \ + thrust_callback, \ /datum/effect_system/trail_follow/ion, \ ) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 8a7f18ed2cc5..6d71ec0208ed 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -16,6 +16,7 @@ icon = 'icons/obj/canisters.dmi' icon_state = "generic" inhand_icon_state = "generic_tank" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/equipment/tanks_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tanks_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 1c23937d2b58..eba0bc82054d 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -290,6 +290,9 @@ /obj/item/extinguisher/mini/nozzle/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(AttemptRefill(interacting_with, user)) return NONE + return ..() + +/obj/item/extinguisher/mini/nozzle/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(nozzle_mode == EXTINGUISHER) return ..() diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 70ec348af63c..865c9c5ace1a 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -184,7 +184,17 @@ var/area/computer_area = get_area(target) if(!computer_area || (computer_area.area_flags & NOTELEPORT)) continue - if(computer.power_station?.teleporter_hub && computer.power_station.engaged) + + if(!computer.power_station || !computer.power_station.teleporter_hub) + continue + + if((computer.power_station.machine_stat & (NOPOWER|BROKEN|MAINT)) || computer.power_station.panel_open) + continue + + if((computer.power_station.teleporter_hub.machine_stat & (NOPOWER|BROKEN|MAINT)) || computer.power_station.teleporter_hub.panel_open) + continue + + if(computer.power_station.engaged) locations["[get_area(target)] (Active)"] = computer else locations["[get_area(target)] (Inactive)"] = computer diff --git a/code/game/objects/items/tongs.dm b/code/game/objects/items/tongs.dm index 81f71c6b3453..ec72133a2577 100644 --- a/code/game/objects/items/tongs.dm +++ b/code/game/objects/items/tongs.dm @@ -6,6 +6,7 @@ icon_state = "tongs" base_icon_state = "tongs" inhand_icon_state = "fork" // close enough + icon_angle = -45 attack_verb_continuous = list("pinches", "tongs", "nips") attack_verb_simple = list("pinch", "tong", "nip") /// What are we holding in our tongs? diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 2d5a508076d9..9081277ad942 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/tools.dmi' icon_state = "crowbar" inhand_icon_state = "crowbar" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' usesound = 'sound/items/tools/crowbar.ogg' @@ -77,6 +78,7 @@ w_class = WEIGHT_CLASS_NORMAL icon = 'icons/obj/weapons/hammer.dmi' icon_state = "clawhammer" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' inhand_icon_state = "clawhammer" @@ -88,7 +90,7 @@ custom_materials = list(/datum/material/wood=SMALL_MATERIAL_AMOUNT*0.5, /datum/material/iron=SMALL_MATERIAL_AMOUNT*0.7) wound_bonus = 35 -/obj/item/crowbar/large/heavy //from space ruin +/obj/item/crowbar/large/twenty_force //from space ruin name = "heavy crowbar" desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big. It feels oddly heavy.." force = 20 @@ -112,6 +114,7 @@ icon_state = "jaws" inhand_icon_state = "jawsoflife" worn_icon_state = "jawsoflife" + icon_angle = 180 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*2.25, /datum/material/silver = SHEET_MATERIAL_AMOUNT*1.25, /datum/material/titanium = SHEET_MATERIAL_AMOUNT*1.75) @@ -192,6 +195,7 @@ icon = 'icons/obj/items_cyborg.dmi' icon_state = "toolkit_engiborg_crowbar" worn_icon_state = "toolkit_engiborg_crowbar" //error sprite - this shouldn't have been dropped + icon_angle = 0 usesound = 'sound/items/tools/jaws_pry.ogg' force = 10 toolspeed = 0.5 @@ -203,6 +207,7 @@ base_icon_state = "mechremoval" inhand_icon_state = null icon = 'icons/obj/mechremoval.dmi' + icon_angle = -65 w_class = WEIGHT_CLASS_HUGE slot_flags = NONE toolspeed = 1.25 diff --git a/code/game/objects/items/tools/spess_knife.dm b/code/game/objects/items/tools/spess_knife.dm index 1dad6fb530f8..f689641fc28e 100644 --- a/code/game/objects/items/tools/spess_knife.dm +++ b/code/game/objects/items/tools/spess_knife.dm @@ -8,6 +8,7 @@ worn_icon_state = "spess_knife" inside_belt_icon_state = "spess_knife" inhand_icon_state = "spess_knife" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' w_class = WEIGHT_CLASS_TINY diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index ffccf8139965..e7e2c50be337 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -127,9 +127,9 @@ /obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks) var/mutable_appearance/sparks = mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, src, ABOVE_LIGHTING_PLANE) target.add_overlay(sparks) - LAZYADD(update_overlays_on_z, sparks) + LAZYADD(target.update_overlays_on_z, sparks) . = ..() - LAZYREMOVE(update_overlays_on_z, sparks) + LAZYREMOVE(target.update_overlays_on_z, sparks) target.cut_overlay(sparks) /obj/item/weldingtool/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) @@ -238,7 +238,7 @@ // /Switches the welder on /obj/item/weldingtool/proc/switched_on(mob/user) if(!status) - to_chat(user, span_warning("[src] can't be turned on while unsecured!")) + balloon_alert(user, "unsecured!") return set_welding(!welding) if(welding) diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 564403acf0ec..25f7e75593fb 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -5,6 +5,7 @@ icon_state = "wrench" inhand_icon_state = "wrench" worn_icon_state = "wrench" + icon_angle = -135 lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY @@ -43,6 +44,7 @@ desc = "A polarized wrench. It causes anything placed between the jaws to turn." icon = 'icons/obj/antags/abductor.dmi' inside_belt_icon_state = "wrench_alien" + icon_angle = -135 custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT * 2.5, /datum/material/silver = SHEET_MATERIAL_AMOUNT*1.25, /datum/material/plasma =HALF_SHEET_MATERIAL_AMOUNT, /datum/material/titanium =SHEET_MATERIAL_AMOUNT, /datum/material/diamond =SHEET_MATERIAL_AMOUNT) usesound = 'sound/effects/empulse.ogg' toolspeed = 0.1 @@ -89,6 +91,7 @@ desc = "An advanced robotic wrench, powered by internal hydraulics. Twice as fast as the handheld version." icon = 'icons/obj/items_cyborg.dmi' icon_state = "toolkit_engiborg_wrench" + icon_angle = 0 toolspeed = 0.5 /obj/item/wrench/combat @@ -97,6 +100,7 @@ icon_state = "wrench_combat" inhand_icon_state = "wrench_combat" inside_belt_icon_state = "wrench_combat" + icon_angle = -90 attack_verb_continuous = list("devastates", "brutalizes", "commits a war crime against", "obliterates", "humiliates") attack_verb_simple = list("devastate", "brutalize", "commit a war crime against", "obliterate", "humiliate") tool_behaviour = null @@ -132,4 +136,5 @@ desc = "A wrench designed to grab into airlock's bolting system and raise it regardless of the airlock's power status." icon_state = "bolter_wrench" inhand_icon_state = "bolter_wrench" + icon_angle = -90 w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index e7f56fa716f8..08a370f31348 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -565,6 +565,7 @@ desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up." icon_state = "e_sword" inhand_icon_state = "e_sword" + icon_angle = -45 icon = 'icons/obj/weapons/transforming_energy.dmi' lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' @@ -682,6 +683,7 @@ icon = 'icons/obj/toys/toy.dmi' icon_state = "foamblade" inhand_icon_state = "arm_blade" + icon_angle = -180 lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' attack_verb_continuous = list("pricks", "absorbs", "gores") @@ -781,6 +783,7 @@ icon_state = "katana" inhand_icon_state = "katana" worn_icon_state = "katana" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY @@ -788,9 +791,17 @@ force = 5 throwforce = 5 w_class = WEIGHT_CLASS_NORMAL - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices") - attack_verb_simple = list("attack", "slash", "stab", "slice") + attack_verb_continuous = list("attacks", "slashes", "slices") + attack_verb_simple = list("attack", "slash", "slice") hitsound = 'sound/items/weapons/bladeslice.ogg' + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") + +/obj/item/toy/katana/Initialize(mapload) + . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple) /* * Snap pops @@ -1121,6 +1132,7 @@ icon = 'icons/obj/weapons/khopesh.dmi' icon_state = "render" inhand_icon_state = "cultdagger" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' w_class = WEIGHT_CLASS_SMALL diff --git a/code/game/objects/items/v8_engine.dm b/code/game/objects/items/v8_engine.dm index c75f1ebc13af..20b7dd406a55 100644 --- a/code/game/objects/items/v8_engine.dm +++ b/code/game/objects/items/v8_engine.dm @@ -48,6 +48,7 @@ icon = 'icons/obj/weapons/sword.dmi' icon_state = "house_edge0" inhand_icon_state = "house_edge0" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' w_class = WEIGHT_CLASS_HUGE diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index a731772b0902..3e03cd770978 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -3,6 +3,7 @@ name = "banhammer" icon = 'icons/obj/weapons/hammer.dmi' icon_state = "toyhammer" + icon_angle = -45 slot_flags = ITEM_SLOT_BELT throwforce = 0 force = 1 @@ -47,6 +48,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/hammer.dmi' icon_state = "balloon_mallet" inhand_icon_state = "balloon_mallet" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' siemens_coefficient = 0 @@ -88,6 +90,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/sword.dmi' icon_state = "sord" inhand_icon_state = "sord" + icon_angle = -35 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' slot_flags = ITEM_SLOT_BELT @@ -109,6 +112,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/sword.dmi' icon_state = "claymore" inhand_icon_state = "claymore" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' hitsound = 'sound/items/weapons/bladeslice.ogg' @@ -117,14 +121,16 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 force = 40 throwforce = 10 w_class = WEIGHT_CLASS_NORMAL - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut") block_chance = 50 block_sound = 'sound/items/weapons/parry.ogg' sharpness = SHARP_EDGED max_integrity = 200 armor_type = /datum/armor/item_claymore resistance_flags = FIRE_PROOF + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") /datum/armor/item_claymore fire = 100 @@ -132,11 +138,18 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/claymore/Initialize(mapload) . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + make_stabby() AddComponent(/datum/component/butchering, \ speed = 4 SECONDS, \ effectiveness = 105, \ ) +// Applies alt sharpness component, for overrides +/obj/item/claymore/proc/make_stabby() + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -15) + /obj/item/claymore/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS @@ -356,6 +369,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "katana" inhand_icon_state = "katana" worn_icon_state = "katana" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY @@ -364,14 +378,22 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 throwforce = 10 w_class = WEIGHT_CLASS_HUGE hitsound = 'sound/items/weapons/bladeslice.ogg' - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut") block_chance = 50 block_sound = 'sound/items/weapons/parry.ogg' sharpness = SHARP_EDGED max_integrity = 200 armor_type = /datum/armor/item_katana resistance_flags = FIRE_PROOF + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") + +/obj/item/katana/Initialize(mapload) + . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -15) /datum/armor/item_katana fire = 100 @@ -438,15 +460,16 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "carpenter_hammer" inhand_icon_state = "carpenter_hammer" worn_icon_state = "clawhammer" //plaecholder + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' desc = "Uncanny looking hammer." - force = 20 - throwforce = 20 + force = 17 + throwforce = 14 throw_range = 4 w_class = WEIGHT_CLASS_NORMAL wound_bonus = 20 - demolition_mod = 1.25 + demolition_mod = 1.15 slot_flags = ITEM_SLOT_BELT /obj/item/carpenter_hammer/Initialize(mapload) @@ -475,6 +498,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/sword.dmi' icon_state = "switchblade" base_icon_state = "switchblade" + icon_angle = -90 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' desc = "A sharp, concealable, spring-loaded knife." @@ -491,6 +515,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 resistance_flags = FIRE_PROOF /// Whether the switchblade starts extended or not. var/start_extended = FALSE + var/list/alt_continuous = list("stabs", "pierces", "shanks") + var/list/alt_simple = list("stab", "pierce", "shank") /obj/item/switchblade/get_all_tool_behaviours() return list(TOOL_KNIFE) @@ -512,10 +538,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 sharpness_on = SHARP_EDGED, \ hitsound_on = 'sound/items/weapons/bladeslice.ogg', \ w_class_on = WEIGHT_CLASS_NORMAL, \ - attack_verb_continuous_on = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \ - attack_verb_simple_on = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut"), \ + attack_verb_continuous_on = list("slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \ + attack_verb_simple_on = list("slash", "slice", "tear", "lacerate", "rip", "dice", "cut"), \ ) + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5, TRAIT_TRANSFORM_ACTIVE) + RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) /obj/item/switchblade/proc/on_transform(obj/item/source, mob/user, active) @@ -567,6 +597,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 base_icon_state = "bambostaff" inhand_icon_state = "bambostaff0" worn_icon_state = "bambostaff0" + icon_angle = -135 lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' @@ -589,6 +620,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/staff.dmi' icon_state = "cane" inhand_icon_state = "stick" + icon_angle = 135 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 5 @@ -630,6 +662,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/staff.dmi' icon_state = "crutch_med" inhand_icon_state = "crutch_med" + icon_angle = 45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 12 @@ -682,6 +715,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 desc = "Traditionally used by the blind to help them see. Folds down to be easier to transport." icon_state = "cane_white" inhand_icon_state = "cane_white" + icon_angle = 45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 1 @@ -756,6 +790,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/staff.dmi' icon_state = "cane" inhand_icon_state = "stick" + icon_angle = 135 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 3 @@ -788,6 +823,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 desc = "For the beating to death of lizards with their own tails." icon = 'icons/obj/weapons/club.dmi' icon_state = "tailclub" + icon_angle = -25 force = 14 throwforce = 1 // why are you throwing a club do you even weapon throw_speed = 1 @@ -895,6 +931,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/bat.dmi' icon_state = "baseball_bat" inhand_icon_state = "baseball_bat" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 12 @@ -917,13 +954,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/melee/baseball_bat/Initialize(mapload) . = ..() - if(prob(1)) - name = "cricket bat" - icon_state = "baseball_bat_brit" - inhand_icon_state = "baseball_bat_brit" - desc = pick("You've got red on you.", "You gotta know what a crumpet is to understand cricket.") - AddElement(/datum/element/kneecapping) + // No subtypes + if(type != /obj/item/melee/baseball_bat) + return + if(prob(check_holidays(APRIL_FOOLS) ? 50 : 1)) + make_silly() /obj/item/melee/baseball_bat/attack_self(mob/user) if(!homerun_able) @@ -1011,6 +1047,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 target.throw_at(target_turf, get_dist(target, target_turf), datum_throw_speed + 1, user, callback = CALLBACK(src, PROC_REF(on_hit), target)) thrown_datums[target] = target.throwing +/obj/item/melee/baseball_bat/proc/make_silly() + name = "cricket bat" + icon_state = "baseball_bat_brit" + inhand_icon_state = "baseball_bat_brit" + desc = pick("You've got red on you.", "You gotta know what a crumpet is to understand cricket.") + /obj/item/melee/baseball_bat/proc/on_hit(atom/movable/target) target.remove_filter("baseball_launch") target.throwforce *= 0.5 @@ -1039,12 +1081,18 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers return TRUE +// In case you ever want to spawn it via map/admin console +/obj/item/melee/baseball_bat/british/Initialize(mapload) + . = ..() + make_silly() + /obj/item/melee/flyswatter name = "flyswatter" desc = "Useful for killing pests of all sizes." icon = 'icons/obj/service/hydroponics/equipment.dmi' icon_state = "flyswatter" inhand_icon_state = "flyswatter" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' force = 1 @@ -1135,6 +1183,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/club.dmi' icon_state = "gohei" inhand_icon_state = "gohei" + icon_angle = -65 lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' @@ -1145,6 +1194,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon_state = "swordon" inhand_icon_state = "swordon" worn_icon_state = "swordon" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' w_class = WEIGHT_CLASS_BULKY @@ -1155,8 +1205,16 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 force = 14 throwforce = 12 hitsound = 'sound/items/weapons/bladeslice.ogg' - attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") - attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut") + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") + +/obj/item/melee/moonlight_greatsword/Initialize(mapload) + . = ..() + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple) //High Frequency Blade @@ -1167,6 +1225,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 icon = 'icons/obj/weapons/sword.dmi' icon_state = "hfrequency0" worn_icon_state = "hfrequency0" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' force = 10 diff --git a/code/game/objects/items/wizard_weapons.dm b/code/game/objects/items/wizard_weapons.dm index e5750c06bb2d..9cbbce1a4c8f 100644 --- a/code/game/objects/items/wizard_weapons.dm +++ b/code/game/objects/items/wizard_weapons.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/weapons/hammer.dmi' icon_state = "singularity_hammer0" base_icon_state = "singularity_hammer" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' worn_icon_state = "singularity_hammer" @@ -77,6 +78,7 @@ icon_state = "mjollnir0" base_icon_state = "mjollnir" worn_icon_state = "mjollnir" + icon_angle = -45 lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' obj_flags = CONDUCTS_ELECTRICITY diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 91991bec3a77..7a58e3ef4864 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -69,18 +69,29 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) return var/total_force = (attacking_item.force * attacking_item.demolition_mod) + var/damage = take_damage(total_force, attacking_item.damtype, MELEE, TRUE, get_dir(src, user), attacking_item.armour_penetration) - var/damage = take_damage(total_force, attacking_item.damtype, MELEE, 1, get_dir(src, user)) + // Sanity in case one is null for some reason + var/picked_index = rand(max(length(attacking_item.attack_verb_simple), length(attacking_item.attack_verb_continuous))) - var/damage_verb = "hit" + var/message_verb_continuous = "attacks" + var/message_verb_simple = "attack" + // Sanity in case one is... longer than the other? + if (picked_index && length(attacking_item.attack_verb_continuous) >= picked_index) + message_verb_continuous = attacking_item.attack_verb_continuous[picked_index] + if (picked_index && length(attacking_item.attack_verb_simple) >= picked_index) + message_verb_simple = attacking_item.attack_verb_simple[picked_index] + + if(attacking_item.demolition_mod > 1 && prob(damage * 5)) + message_verb_simple = "pulverise" + message_verb_continuous = "pulverises" - if(attacking_item.demolition_mod > 1 && damage) - damage_verb = "pulverise" if(attacking_item.demolition_mod < 1) - damage_verb = "ineffectively pierce" + message_verb_simple = "ineffectively " + message_verb_simple + message_verb_continuous = "ineffectively " + message_verb_continuous - user.visible_message(span_danger("[user] [damage_verb][plural_s(damage_verb)] [src] with [attacking_item][damage ? "." : ", [no_damage_feedback]!"]"), \ - span_danger("You [damage_verb] [src] with [attacking_item][damage ? "." : ", [no_damage_feedback]!"]"), null, COMBAT_MESSAGE_RANGE) + user.visible_message(span_danger("[user] [message_verb_continuous] [src] with [attacking_item][damage ? "." : ", [no_damage_feedback]!"]"), \ + span_danger("You [message_verb_simple] [src] with [attacking_item][damage ? "." : ", [no_damage_feedback]!"]"), null, COMBAT_MESSAGE_RANGE) log_combat(user, src, "attacked", attacking_item) /obj/assume_air(datum/gas_mixture/giver) diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 4a5ee234c774..cef73b0fbfd8 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -77,10 +77,13 @@ icon_state = "ai-empty" anchored = TRUE state = AI_READY_CORE + var/mob/living/silicon/ai/attached_ai -/obj/structure/ai_core/deactivated/Initialize(mapload, skip_mmi_creation = FALSE, posibrain = FALSE) +/obj/structure/ai_core/deactivated/Initialize(mapload, skip_mmi_creation = FALSE, posibrain = FALSE, linked_ai) . = ..() circuit = new(src) + if(linked_ai) + attached_ai = linked_ai if(skip_mmi_creation) return if(posibrain) @@ -90,6 +93,16 @@ core_mmi.brain = new(core_mmi) core_mmi.update_appearance() +/obj/structure/ai_core/deactivated/Destroy() + if(attached_ai) + attached_ai.linked_core = null + attached_ai = null + . = ..() + +/obj/structure/ai_core/deactivated/proc/disable_doomsday(datum/source) + SIGNAL_HANDLER + attached_ai.ShutOffDoomsdayDevice() + /obj/structure/ai_core/latejoin_inactive name = "networked AI core" desc = "This AI core is connected by bluespace transmitters to NTNet, allowing for an AI personality to be downloaded to it on the fly mid-shift." diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index de9553034e7f..363093ed88eb 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -7,7 +7,7 @@ can_buckle = TRUE buckle_lying = 0 //you sit in a chair, not lay resistance_flags = NONE - max_integrity = 250 + max_integrity = 100 integrity_failure = 0.1 custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT) layer = OBJ_LAYER @@ -77,19 +77,28 @@ return . = ..() +/obj/structure/chair/update_atom_colour() + . = ..() + if (armrest) + color_atom_overlay(armrest) + /obj/structure/chair/proc/gen_armrest() armrest = GetArmrest() armrest.layer = ABOVE_MOB_LAYER + armrest.appearance_flags |= KEEP_APART update_armrest() /obj/structure/chair/proc/GetArmrest() return mutable_appearance(icon, "[icon_state]_armrest") /obj/structure/chair/proc/update_armrest() + armrest = color_atom_overlay(armrest) + update_appearance() + +/obj/structure/chair/update_overlays() + . = ..() if(has_buckled_mobs()) - add_overlay(armrest) - else - cut_overlay(armrest) + . += armrest ///allows each chair to request the electrified_buckle component with overlays that dont look ridiculous /obj/structure/chair/proc/electrify_self(obj/item/assembly/shock_kit/input_shock_kit, mob/user, list/overlays_from_child_procs) @@ -97,8 +106,8 @@ if(!user.temporarilyRemoveItemFromInventory(input_shock_kit)) return if(!overlays_from_child_procs || overlays_from_child_procs.len == 0) - var/image/echair_over_overlay = image('icons/obj/chairs.dmi', loc, "echair_over", OBJ_LAYER) - AddComponent(/datum/component/electrified_buckle, (SHOCK_REQUIREMENT_ITEM | SHOCK_REQUIREMENT_LIVE_CABLE | SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE), input_shock_kit, list(echair_over_overlay), FALSE) + var/mutable_appearance/echair_overlay = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) + AddComponent(/datum/component/electrified_buckle, (SHOCK_REQUIREMENT_ITEM | SHOCK_REQUIREMENT_LIVE_CABLE | SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE), input_shock_kit, list(echair_overlay), FALSE) else AddComponent(/datum/component/electrified_buckle, (SHOCK_REQUIREMENT_ITEM | SHOCK_REQUIREMENT_LIVE_CABLE | SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE), input_shock_kit, overlays_from_child_procs, FALSE) @@ -171,7 +180,7 @@ name = "wooden chair" desc = "Old is never too old to not be in fashion." resistance_flags = FLAMMABLE - max_integrity = 70 + max_integrity = 40 buildstacktype = /obj/item/stack/sheet/mineral/wood buildstackamount = 3 item_chair = /obj/item/chair/wood @@ -219,7 +228,9 @@ /obj/structure/chair/comfy/shuttle/electrify_self(obj/item/assembly/shock_kit/input_shock_kit, mob/user, list/overlays_from_child_procs) if(!overlays_from_child_procs) - overlays_from_child_procs = list(image('icons/obj/chairs.dmi', loc, "echair_over", pixel_x = -1, layer = OBJ_LAYER)) + var/mutable_appearance/echair_overlay = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) + echair_overlay.pixel_x = -1 + overlays_from_child_procs = list(echair_overlay) . = ..() /obj/structure/chair/comfy/shuttle/tactical @@ -246,7 +257,9 @@ /obj/structure/chair/office/electrify_self(obj/item/assembly/shock_kit/input_shock_kit, mob/user, list/overlays_from_child_procs) if(!overlays_from_child_procs) - overlays_from_child_procs = list(image('icons/obj/chairs.dmi', loc, "echair_over", pixel_x = -1, layer = OBJ_LAYER)) + var/mutable_appearance/echair_overlay = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) + echair_overlay.pixel_x = -1 + overlays_from_child_procs = list(echair_overlay) . = ..() /obj/structure/chair/office/tactical @@ -266,6 +279,7 @@ can_buckle = FALSE buildstackamount = 1 item_chair = /obj/item/chair/stool + max_integrity = 300 MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0) @@ -286,6 +300,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0) var/obj/item/chair_item = new item_chair(loc) chair_item.set_custom_materials(custom_materials) TransferComponents(chair_item) + chair_item.update_integrity(get_integrity()) user.put_in_hands(chair_item) qdel(src) @@ -312,7 +327,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) desc = "A makeshift bamboo stool with a rustic look." icon_state = "bamboo_stool" resistance_flags = FLAMMABLE - max_integrity = 60 + max_integrity = 40 buildstacktype = /obj/item/stack/sheet/mineral/bamboo buildstackamount = 2 item_chair = /obj/item/chair/stool/bamboo @@ -323,6 +338,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) icon = 'icons/obj/chairs.dmi' icon_state = "chair_toppled" inhand_icon_state = "chair" + icon_angle = 180 lefthand_file = 'icons/mob/inhands/items/chairs_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/chairs_righthand.dmi' w_class = WEIGHT_CLASS_HUGE @@ -330,11 +346,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) throwforce = 10 demolition_mod = 1.25 throw_range = 3 + max_integrity = 100 hitsound = 'sound/items/trayhit/trayhit1.ogg' hit_reaction_chance = 50 custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT) item_flags = SKIP_FANTASY_ON_SPAWN - var/break_chance = 5 //Likely hood of smashing the chair. + + // Whether or not the chair causes the target to become shove stun vulnerable if smashed against someone from behind. + var/inflicts_stun_vulnerability = TRUE + + // What structure type does this chair become when placed? var/obj/structure/chair/origin_type = /obj/structure/chair /obj/item/chair/suicide_act(mob/living/carbon/user) @@ -373,6 +394,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) chair.set_custom_materials(custom_materials) TransferComponents(chair) chair.setDir(user.dir) + chair.update_integrity(get_integrity()) qdel(src) /obj/item/chair/proc/smash(mob/living/user) @@ -391,19 +413,43 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) /obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance) || attack_type == LEAP_ATTACK && prob(hit_reaction_chance)) owner.visible_message(span_danger("[owner] fends off [attack_text] with [src]!")) + if(take_chair_damage(damage, damage_type, MELEE)) // Our chair takes our incoming damage for us, which can result in it smashing. + smash(owner) return TRUE return FALSE /obj/item/chair/afterattack(atom/target, mob/user, click_parameters) - if(!prob(break_chance)) + if(!ishuman(target)) return - user.visible_message(span_danger("[user] smashes [src] to pieces against [target]")) - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(C.health < C.maxHealth*0.5) - C.Paralyze(20) + + var/mob/living/carbon/human/give_this_fucker_the_chair = target + + // Here we determine if our attack is against a vulnerable target + var/vulnerable_hit = check_behind(user, give_this_fucker_the_chair) + + // If our attack is against a vulnerable target, we do additional damage to the chair + var/damage_to_inflict = vulnerable_hit ? (force * 5) : (force * 2.5) + + if(!take_chair_damage(damage_to_inflict, damtype, MELEE)) // If we would do enough damage to bring our chair's integrity to 0, we instead go past the check to smash it against our target + return + + user.visible_message(span_danger("[user] smashes [src] to pieces against [give_this_fucker_the_chair]")) + if(!HAS_TRAIT(give_this_fucker_the_chair, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) + if(vulnerable_hit || give_this_fucker_the_chair.get_timed_status_effect_duration(/datum/status_effect/staggered)) + give_this_fucker_the_chair.Knockdown(2 SECONDS) + if(give_this_fucker_the_chair.health < give_this_fucker_the_chair.maxHealth*0.5) + give_this_fucker_the_chair.adjust_confusion(10 SECONDS) + if(inflicts_stun_vulnerability) + give_this_fucker_the_chair.apply_status_effect(/datum/status_effect/next_shove_stuns) + smash(user) +/obj/item/chair/proc/take_chair_damage(damage_to_inflict, damage_type, armor_flag) + if(damage_to_inflict >= atom_integrity) + return TRUE + take_damage(damage_to_inflict, damage_type, armor_flag) + return FALSE + /obj/item/chair/greyscale material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS origin_type = /obj/structure/chair/greyscale @@ -413,7 +459,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) icon_state = "stool_toppled" inhand_icon_state = "stool" origin_type = /obj/structure/chair/stool - break_chance = 0 //It's too sturdy. + max_integrity = 300 //It's too sturdy. /obj/item/chair/stool/bar name = "bar stool" @@ -427,7 +473,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) inhand_icon_state = "stool_bamboo" hitsound = 'sound/items/weapons/genhit1.ogg' origin_type = /obj/structure/chair/stool/bamboo - break_chance = 50 //Submissive and breakable unlike the chad iron stool + max_integrity = 40 //Submissive and breakable unlike the chad iron stool + inflicts_stun_vulnerability = FALSE //Not hard enough to cause them to become vulnerable to a shove /obj/item/chair/stool/narsie_act() return //sturdy enough to ignore a god @@ -437,11 +484,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) icon_state = "wooden_chair_toppled" inhand_icon_state = "woodenchair" resistance_flags = FLAMMABLE - max_integrity = 70 + max_integrity = 40 hitsound = 'sound/items/weapons/genhit1.ogg' origin_type = /obj/structure/chair/wood custom_materials = null - break_chance = 50 + inflicts_stun_vulnerability = FALSE /obj/item/chair/wood/narsie_act() return @@ -526,7 +573,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) name = "folding plastic chair" desc = "No matter how much you squirm, it'll still be uncomfortable." resistance_flags = FLAMMABLE - max_integrity = 50 + max_integrity = 70 custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT) buildstacktype = /obj/item/stack/sheet/plastic buildstackamount = 2 @@ -562,7 +609,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) force = 7 throw_range = 5 //Lighter Weight --> Flies Farther. custom_materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT) - break_chance = 25 + max_integrity = 70 + inflicts_stun_vulnerability = FALSE origin_type = /obj/structure/chair/plastic /obj/structure/chair/musical diff --git a/code/game/objects/structures/beds_chairs/sofa.dm b/code/game/objects/structures/beds_chairs/sofa.dm index 7ff735750481..36b95e9515e3 100644 --- a/code/game/objects/structures/beds_chairs/sofa.dm +++ b/code/game/objects/structures/beds_chairs/sofa.dm @@ -28,7 +28,9 @@ path/corner/color_name {\ /obj/structure/chair/sofa/electrify_self(obj/item/assembly/shock_kit/input_shock_kit, mob/user, list/overlays_from_child_procs) if(!overlays_from_child_procs) - overlays_from_child_procs = list(image('icons/obj/chairs.dmi', loc, "echair_over", pixel_x = -1, layer = OBJ_LAYER)) + var/mutable_appearance/echair_overlay = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) + echair_overlay.pixel_x = -1 + overlays_from_child_procs = list(echair_overlay) . = ..() /obj/structure/chair/sofa/corner/handle_layer() //only the armrest/back of this chair should cover the mob. diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 7ce90f4063d9..30a2c4e9efd2 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -58,6 +58,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) var/cutting_tool = /obj/item/weldingtool var/open_sound = 'sound/machines/closet/closet_open.ogg' var/close_sound = 'sound/machines/closet/closet_close.ogg' + var/lock_sound = 'sound/machines/closet/closet_lock.ogg' + var/unlock_sound = 'sound/machines/closet/closet_unlock.ogg' var/open_sound_volume = 35 var/close_sound_volume = 50 var/material_drop = /obj/item/stack/sheet/iron @@ -236,7 +238,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) . += door_overlay door_overlay.overlays += emissive_blocker(door_overlay.icon, door_overlay.icon_state, src, alpha = door_overlay.alpha) // If we don't do this the door doesn't block emissives and it looks weird. else if(has_closed_overlay) - . += "[icon_door || overlay_state]_door" + var/mutable_appearance/door_overlay = mutable_appearance(icon, "[icon_door || overlay_state]_door", alpha = src.alpha) + . += door_overlay if(opened) return @@ -485,7 +488,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) if(!before_open(user, force) || (SEND_SIGNAL(src, COMSIG_CLOSET_PRE_OPEN, user, force) & BLOCK_OPEN)) return FALSE welded = FALSE - locked = FALSE + unlock() if(special_effects) playsound(loc, open_sound, open_sound_volume, TRUE, -3) opened = TRUE @@ -1031,6 +1034,8 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) open() return + if(DOING_INTERACTION_WITH_TARGET(user, src)) + return //okay, so the closet is either welded or locked... resist!!! user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT @@ -1052,7 +1057,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) to_chat(user, span_warning("You fail to break out of [src]!")) /obj/structure/closet/relay_container_resist_act(mob/living/user, obj/container) - container.container_resist_act() + container.container_resist_act(user) /// Check if someone is still resisting inside, and choose to either keep shaking or stop shaking the closet /obj/structure/closet/proc/check_if_shake() @@ -1075,7 +1080,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/proc/bust_open() SIGNAL_HANDLER welded = FALSE //applies to all lockers - locked = FALSE //applies to critter crates and secure lockers only + unlock() //applies to critter crates and secure lockers only broken = TRUE //applies to secure lockers only open(force = TRUE, special_effects = FALSE) @@ -1128,12 +1133,33 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) if(iscarbon(user)) add_fingerprint(user) locked = !locked + play_closet_lock_sound() user.visible_message( span_notice("[user] [locked ? "locks" : "unlocks"] [src]."), span_notice("You [locked ? "locked" : "unlocked"] [src]."), ) update_appearance() +/// toggles the lock state of a closet +/obj/structure/closet/proc/lock() + if(locked) + return + locked = TRUE + play_closet_lock_sound() + update_appearance() + +/// unlocks the closet +/obj/structure/closet/proc/unlock() + if(!locked) + return + locked = FALSE + play_closet_lock_sound() + update_appearance() + +/// plays the closet's lock/unlock sound, this should be placed AFTER you've changed the lock state +/obj/structure/closet/proc/play_closet_lock_sound() + playsound(src, locked ? lock_sound : unlock_sound, 50, TRUE) + /obj/structure/closet/emag_act(mob/user, obj/item/card/emag/emag_card) if(secure && !broken) visible_message(span_warning("Sparks fly from [src]!"), blind_message = span_hear("You hear a faint electrical spark.")) @@ -1211,7 +1237,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/proc/on_magic_unlock(datum/source, datum/action/cooldown/spell/aoe/knock/spell, atom/caster) SIGNAL_HANDLER - locked = FALSE + INVOKE_ASYNC(src, PROC_REF(unlock)) INVOKE_ASYNC(src, PROC_REF(open)) /obj/structure/closet/preopen diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index b07581a0ee4a..f49cdf98feaa 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -295,6 +295,21 @@ new /obj/item/bodypart/leg/right/robot/surplus(src) new /obj/item/bodypart/leg/right/robot/surplus(src) +/obj/structure/closet/crate/freezer/organ + name = "organ freezer" + desc = "A freezer containing a set of organic organs." + +/obj/structure/closet/crate/freezer/organ/PopulateContents() + . = ..() + new /obj/item/organ/heart(src) + new /obj/item/organ/lungs(src) + new /obj/item/organ/eyes(src) + new /obj/item/organ/ears(src) + new /obj/item/organ/tongue(src) + new /obj/item/organ/liver(src) + new /obj/item/organ/stomach(src) + new /obj/item/organ/appendix(src) + /obj/structure/closet/crate/freezer/food name = "food icebox" icon_state = "food" diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 8df558169f82..70fb5b57ae23 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -9,7 +9,8 @@ /obj/structure/chair/e_chair/Initialize(mapload) . = ..() var/obj/item/assembly/shock_kit/stored_kit = new(contents) - var/image/export_to_component = image('icons/obj/chairs.dmi', loc, "echair_over", OBJ_LAYER) + var/mutable_appearance/export_to_component = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) + export_to_component = color_atom_overlay(export_to_component) AddComponent(/datum/component/electrified_buckle, (SHOCK_REQUIREMENT_ITEM | SHOCK_REQUIREMENT_LIVE_CABLE | SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE), stored_kit, list(export_to_component)) /obj/structure/chair/e_chair/attackby(obj/item/W, mob/user, params) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 9a3994452b09..032b77aa6c02 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -1,11 +1,16 @@ /obj/structure/girder + icon = 'icons/obj/smooth_structures/girder.dmi' name = "girder" - icon_state = "girder" + base_icon_state = "girder" + icon_state = "girder-0" desc = "A large structural assembly made out of metal; It requires a layer of iron before it can be considered a wall." anchored = TRUE density = TRUE max_integrity = 200 rad_insulation = RAD_VERY_LIGHT_INSULATION + smoothing_flags = SMOOTH_BITMASK + smoothing_groups = SMOOTH_GROUP_GIRDER + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_WALLS var/state = GIRDER_NORMAL var/girderpasschance = 20 // percentage chance that a projectile passes through the girder. var/can_displace = TRUE //If the girder can be moved around by wrenching it @@ -393,15 +398,21 @@ /obj/structure/girder/displaced name = "displaced girder" + icon = 'icons/obj/structures.dmi' icon_state = "displaced" anchored = FALSE state = GIRDER_DISPLACED girderpasschance = 25 max_integrity = 120 + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null /obj/structure/girder/reinforced name = "reinforced girder" - icon_state = "reinforced" + icon = 'icons/obj/smooth_structures/reinforced_girder.dmi' + icon_state = "reinforced-0" + base_icon_state = "reinforced" state = GIRDER_REINF girderpasschance = 0 max_integrity = 350 @@ -409,9 +420,13 @@ /obj/structure/girder/tram name = "tram girder" desc = "Titanium framework to construct tram walls. Can be plated with titanium glass or other wall materials." + icon = 'icons/obj/structures.dmi' icon_state = "tram" state = GIRDER_TRAM obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null /obj/structure/girder/tram/corner name = "tram frame corner" @@ -424,6 +439,9 @@ icon = 'icons/obj/antags/cult/structures.dmi' icon_state= "cultgirder" can_displace = FALSE + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null /obj/structure/girder/cult/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -493,8 +511,12 @@ /obj/structure/girder/bronze name = "wall gear" desc = "A girder made out of sturdy bronze, made to resemble a gear." + icon = 'icons/obj/structures.dmi' icon_state = "wall_gear" can_displace = FALSE + smoothing_flags = NONE + smoothing_groups = null + canSmoothWith = null /obj/structure/girder/bronze/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) diff --git a/code/game/objects/structures/gym/weight_machine.dm b/code/game/objects/structures/gym/weight_machine.dm index b36e35245c20..a329f70750de 100644 --- a/code/game/objects/structures/gym/weight_machine.dm +++ b/code/game/objects/structures/gym/weight_machine.dm @@ -152,7 +152,8 @@ if(!has_buckled_mobs()) end_workout() return FALSE - var/mutable_appearance/workout = mutable_appearance(icon, "[base_icon_state]-o", ABOVE_MOB_LAYER) + var/mutable_appearance/workout = mutable_appearance(icon, "[base_icon_state]-o", ABOVE_MOB_LAYER, src, appearance_flags = KEEP_APART) + workout = color_atom_overlay(workout) flick_overlay_view(workout, 0.8 SECONDS) flick("[base_icon_state]-u", src) var/mob/living/user = buckled_mobs[1] diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index a0cf53487cf3..f22ef3f7e2b4 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -34,6 +34,13 @@ . = ..() . += deconstruction_hints(user) +/obj/structure/lattice/Destroy(force) // so items on the lattice fall when the lattice is destroyed + var/turf/turfloc = loc + . = ..() + if(isturf(turfloc)) + for(var/thing_that_falls as anything in turfloc) // as anything because turfloc can only contain movables + turfloc.zFall((thing_that_falls)) + /obj/structure/lattice/proc/deconstruction_hints(mob/user) return span_notice("The rods look like they could be cut. There's space for more rods or a tile.") @@ -155,7 +162,7 @@ /obj/structure/lattice/lava/attackby(obj/item/attacking_item, mob/user, params) . = ..() - if(!istype(attacking_item, /obj/item/stack/tile/iron)) + if(!ismetaltile(attacking_item)) return var/obj/item/stack/tile/iron/attacking_tiles = attacking_item if(!attacking_tiles.use(1)) diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm index 6a8dc8e31cde..9a546e8154d9 100644 --- a/code/game/objects/structures/lavaland/geyser.dm +++ b/code/game/objects/structures/lavaland/geyser.dm @@ -121,6 +121,7 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "plunger" worn_icon_state = "plunger" + icon_angle = 90 slot_flags = ITEM_SLOT_MASK flags_inv = HIDESNOUT diff --git a/code/game/objects/structures/maintenance.dm b/code/game/objects/structures/maintenance.dm index d3eb552c46b8..bf96397507af 100644 --- a/code/game/objects/structures/maintenance.dm +++ b/code/game/objects/structures/maintenance.dm @@ -80,12 +80,11 @@ at the cost of risking a vicious bite.**/ return if(critter_infested && prob(50) && iscarbon(user)) var/mob/living/carbon/bite_victim = user - var/obj/item/bodypart/affecting = bite_victim.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") - to_chat(user, span_danger("You feel a sharp pain as an unseen creature sinks its [pick("fangs", "beak", "proboscis")] into your arm!")) - if(affecting?.receive_damage(30)) - bite_victim.update_damage_overlays() - playsound(src,'sound/items/weapons/bite.ogg', 70, TRUE) - return + var/obj/item/bodypart/affecting = bite_victim.get_active_hand() + to_chat(user, span_danger("You feel a sharp pain as an unseen creature sinks its [pick("fangs", "beak", "proboscis")] into your [affecting.plaintext_zone]!")) + bite_victim.apply_damage(30, BRUTE, affecting) + playsound(src,'sound/items/weapons/bite.ogg', 70, TRUE) + return to_chat(user, span_warning("You find nothing of value...")) /obj/structure/moisture_trap/attackby(obj/item/I, mob/user, params) diff --git a/code/game/objects/structures/plaques/static_plaques.dm b/code/game/objects/structures/plaques/static_plaques.dm index 978cfbc5451c..d0ef78a3a27c 100644 --- a/code/game/objects/structures/plaques/static_plaques.dm +++ b/code/game/objects/structures/plaques/static_plaques.dm @@ -116,6 +116,14 @@ //Current stations +// Birdshot: added Apr 29, 2023 (#74371) +/obj/structure/plaque/static_plaque/golden/commission/birdshot + desc = "Spinward Sector Station SS-13\n'Birdshot' Class Outpost\nCommissioned 29/04/2563\n'Shooting for the Stars'" + +// Deltastation: added Dec 17, 2016 (#22066) +/obj/structure/plaque/static_plaque/golden/commission/delta + desc = "Spinward Sector Station SS-13\n'Delta' Class Outpost\nCommissioned 17/12/2556\n'Efficiency Through Redundancy'" + // Icebox Station: added May 13, 2020 (#51090) /obj/structure/plaque/static_plaque/golden/commission/icebox desc = "Cabriole Sector Station SS-13\n'Box' Class Outpost (Revision 2.2: 'Icebox')\nCommissioned 13/05/2560\n'Cold Reliable'" @@ -126,13 +134,13 @@ // Deltastation: added Dec 17, 2016 (#22066) /obj/structure/plaque/static_plaque/golden/commission/delta - desc = "CabrioleSector Station SS-13\n'Delta' Class Outpost\nCommissioned 17/12/2556\n'Efficiency Through Redundancy'" + desc = "Cabriole Sector Station SS-13\n'Delta' Class Outpost\nCommissioned 17/12/2556\n'Efficiency Through Redundancy'" // Tramstation: added Mar 11, 2021 (#56509) /obj/structure/plaque/static_plaque/golden/commission/tram desc = "Cabriole Sector Station SS-13\n'Tram' Class Outpost\nCommissioned 11/03/2561\n'Making Moves'" -// Wawastation: added add date here +// Wawastation: added Jun 4, 2024 (#82298) /obj/structure/plaque/static_plaque/golden/commission/wawa desc = "Cabriole Sector Station SS-13\n'Wawa' Class Outpost\nCommissioned 11/03/add here\n'Forever Vertical'" @@ -190,6 +198,10 @@ /obj/structure/plaque/static_plaque/golden/commission/mini desc = "Spinward Sector Station SS-08\n'Mini' Class Outpost\nCommissioned 29/01/2554\nDecommissioned 27/12/2556\n'The Littlest Station'" +// North Star: added Apr 13, 2023 (#74371), removed Nov 25, 2024 (#87937)- 1 year, 7 months, 12 days +/obj/structure/plaque/static_plaque/golden/commission/northstar + desc = "Spinward Sector Ship SS-13\n'North Star' Class Vessel\nCommissioned 13/04/2563\nDecommissioned 25/11/2564\n'New Opportunities'" + // Omegastation: added Dec 27, 2016 (#22453), removed Sep 20, 2018 (#40352)- 1 year, 8 months, 24 days /obj/structure/plaque/static_plaque/golden/commission/omega desc = "Spinward Sector Station SS-09\n'Omega' Class Outpost\nCommissioned 27/12/2556\nDecommissioned 20/09/2558\n'Tiny Take Two'" diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index 14ac05263942..67adbddeba5f 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -128,8 +128,8 @@ /obj/structure/showcase/katana name = "seppuku katana" - density = 0 desc = "Welp, only one way to recover your honour." + density = 0 icon = 'icons/obj/weapons/sword.dmi' icon_state = "katana" diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm index 2447b847c16d..91b417fdbdd8 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -200,7 +200,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) . = ..() if(!actually_on) return - var/mutable_appearance/water_falling = mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER) + var/mutable_appearance/water_falling = mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER, appearance_flags = KEEP_APART) water_falling.color = mix_color_from_reagents(reagents.reagent_list) switch(dir) if(NORTH) @@ -280,7 +280,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) if(!radioactive_shower) // note it is possible to have a clean_shower that is radioactive (+70% water mixed with +20% radiation) wash_flags |= CLEAN_RAD - target.wash(wash_flags) + + if (isturf(target)) + target.wash(wash_flags, TRUE) + else + target.wash(wash_flags) reagents.expose(target, (TOUCH), SHOWER_EXPOSURE_MULTIPLIER * SHOWER_SPRAY_VOLUME / max(reagents.total_volume, SHOWER_SPRAY_VOLUME)) if(!isliving(target)) @@ -352,10 +356,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) // Wash up. wash_atom(loc) - for(var/atom/movable/movable_content as anything in loc) - if(!ismopable(movable_content)) // Mopables will be cleaned anyways by the turf wash above - wash_atom(movable_content) // Reagent exposure is handled in wash_atom - reagents.remove_all(SHOWER_SPRAY_VOLUME) /obj/machinery/shower/on_deconstruction(disassembled = TRUE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 08a730110a9c..d0ef4c4f996a 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -197,7 +197,7 @@ var/extra_wound = 0 if(HAS_TRAIT(user, TRAIT_HULK)) extra_wound = 20 - banged_limb?.receive_damage(30, wound_bonus = extra_wound) + pushed_mob.apply_damage(30, BRUTE, banged_limb, wound_bonus = extra_wound) pushed_mob.apply_damage(60, STAMINA) take_damage(50) if(user.mind?.martial_art?.smashes_tables && user.mind?.martial_art.can_use(user)) @@ -382,7 +382,6 @@ /obj/structure/table/rolling/Initialize(mapload) . = ..() AddElement(/datum/element/noisy_movement) - RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_our_moved)) /obj/structure/table/rolling/Destroy() for(var/item in attached_items) @@ -390,6 +389,24 @@ LAZYNULL(attached_items) // safety return ..() +/obj/structure/table/rolling/item_interaction(mob/living/user, obj/item/rolling_table_dock/rable, list/modifiers) + . = NONE + if(!istype(rable)) + return + + if(rable.loaded) + to_chat(user, span_warning("You already have \a [rable.loaded] docked!")) + return ITEM_INTERACT_FAILURE + + if(locate(/mob/living) in loc.get_all_contents()) + to_chat(user, span_warning("You can't collect \the [src] with that much on top!")) + return ITEM_INTERACT_FAILURE + + rable.loaded = src + forceMove(rable) + user.visible_message(span_notice("[user] collects \the [src]."), span_notice("You collect \the [src].")) + return ITEM_INTERACT_SUCCESS + /obj/structure/table/rolling/AfterPutItemOnTable(obj/item/thing, mob/living/user) . = ..() LAZYADD(attached_items, thing) @@ -406,8 +423,9 @@ clear_item_reference(thing) /// Handles movement of the table itself, as well as moving along any atoms we have on our surface. -/obj/structure/table/rolling/proc/on_our_moved(datum/source, atom/old_loc, dir, forced, list/old_locs, momentum_change) - SIGNAL_HANDLER +/obj/structure/table/rolling/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + if(isnull(loc)) // aw hell naw return diff --git a/code/game/objects/structures/votingbox.dm b/code/game/objects/structures/votingbox.dm index 55909978fe2f..013556febbd5 100644 --- a/code/game/objects/structures/votingbox.dm +++ b/code/game/objects/structures/votingbox.dm @@ -44,13 +44,13 @@ dat += "

Unregistered. Swipe ID card to register as voting box operator

" dat += "

[vote_description]

" if(is_operator(user)) - dat += "Voting: [voting_active ? "Active" : "Maintenance Mode"]
" - dat += "Set Description: Set Description
" - dat += "One vote per ID: [id_auth ? "Yes" : "No"]
" - dat += "Reset voted ID's: Reset
" - dat += "Draw random vote: Raffle
" - dat += "Shred votes: Shred
" - dat += "Tally votes: Tally
" + dat += "Voting: [voting_active ? "Active" : "Maintenance Mode"]
" + dat += "Set Description: Set Description
" + dat += "One vote per ID: [id_auth ? "Yes" : "No"]
" + dat += "Reset voted ID's: Reset
" + dat += "Draw random vote: Raffle
" + dat += "Shred votes: Shred
" + dat += "Tally votes: Tally
" var/datum/browser/popup = new(user, "votebox", "Voting Box", 300, 300) popup.set_content(dat.Join()) diff --git a/code/game/objects/structures/water_structures/sink.dm b/code/game/objects/structures/water_structures/sink.dm index 1cd3f7d7aaa5..3a6dfbb2a2c1 100644 --- a/code/game/objects/structures/water_structures/sink.dm +++ b/code/game/objects/structures/water_structures/sink.dm @@ -73,10 +73,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink, (-14)) if(busy) to_chat(user, span_warning("Someone's already washing here!")) return + var/selected_area = user.parse_zone_with_bodypart(user.zone_selected) - var/washing_face = 0 + var/washing_face = FALSE if(selected_area in list(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_PRECISE_EYES)) - washing_face = 1 + washing_face = TRUE + + playsound(src, 'sound/machines/sink-faucet.ogg', 50) user.visible_message(span_notice("[user] starts washing [user.p_their()] [washing_face ? "face" : "hands"]..."), \ span_notice("You start washing your [washing_face ? "face" : "hands"]...")) busy = TRUE @@ -206,6 +209,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink, (-14)) if(!user.combat_mode || (O.item_flags & NOBLUDGEON)) to_chat(user, span_notice("You start washing [O]...")) + playsound(src, 'sound/machines/sink-faucet.ogg', 50) busy = TRUE if(!do_after(user, 4 SECONDS, target = src)) busy = FALSE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 83a848d86677..21b76604ab76 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -82,12 +82,11 @@ /obj/structure/window/mouse_drop_receive(atom/dropping, mob/user, params) . = ..() - if (added_leaning || (flags_1 & ON_BORDER_1)) + if (flags_1 & ON_BORDER_1) return - /// For performance reasons and to cut down on init times we are "lazy-loading" the leaning component when someone drags their sprite onto us, and then calling dragging code again to trigger the component - AddComponent(/datum/component/leanable, 11) - added_leaning = TRUE - dropping.base_mouse_drop_handler(src, null, null, params) + + //Adds the component only once. We do it here & not in Initialize() because there are tons of windows & we don't want to add to their init times + LoadComponent(/datum/component/leanable, dropping) /obj/structure/window/examine(mob/user) . = ..() diff --git a/code/game/say.dm b/code/game/say.dm index e0d4e2de9aaf..f1733d3c9fed 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -171,7 +171,7 @@ GLOBAL_LIST_INIT(freqtospan, list( if(istype(dialect) && dialect.display_icon(src)) languageicon = "[dialect.get_icon()] " - messagepart = " [say_emphasis(messagepart)]" + messagepart = " [messagepart]" return "[spanpart1][spanpart2][freqpart][languageicon][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]" @@ -229,8 +229,14 @@ GLOBAL_LIST_INIT(freqtospan, list( if(copytext_char(input, -2) == "!!") spans |= SPAN_YELL - var/spanned = attach_spans(input, spans) - return "[say_mod], \"[spanned]\"" + /* all inputs should be fully figured out past this point */ + + var/processed_input = say_emphasis(input) //This MUST be done first so that we don't get clipped by spans + processed_input = attach_spans(processed_input, spans) + + var/processed_say_mod = say_emphasis(say_mod) + + return "[processed_say_mod], \"[processed_input]\"" /// Transforms the speech emphasis mods from [/atom/movable/proc/say_emphasis] into the appropriate HTML tags. Includes escaping. #define ENCODE_HTML_EMPHASIS(input, char, html, varname) \ @@ -241,8 +247,8 @@ GLOBAL_LIST_INIT(freqtospan, list( /atom/movable/proc/say_emphasis(input) ENCODE_HTML_EMPHASIS(input, "\\|", "i", italics) ENCODE_HTML_EMPHASIS(input, "\\+", "b", bold) - ENCODE_HTML_EMPHASIS(input, "_", "u", underline) - var/static/regex/remove_escape_backlashes = regex("\\\\(_|\\+|\\|)", "g") // Removes backslashes used to escape text modification. + ENCODE_HTML_EMPHASIS(input, "\\_", "u", underline) + var/static/regex/remove_escape_backlashes = regex("\\\\(\\_|\\+|\\|)", "g") // Removes backslashes used to escape text modification. input = remove_escape_backlashes.Replace_char(input, "$1") return input diff --git a/code/game/sound.dm b/code/game/sound.dm index 1e2160c65112..4c5491421875 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -51,6 +51,9 @@ if (!turf_source || !soundin || !vol) return + if(vol < SOUND_AUDIBLE_VOLUME_MIN) // never let sound go below SOUND_AUDIBLE_VOLUME_MIN or bad things will happen + return + //allocate a channel if necessary now so its the same for everyone channel = channel || SSsounds.random_available_channel() @@ -64,8 +67,9 @@ var/turf/above_turf = GET_TURF_ABOVE(turf_source) var/turf/below_turf = GET_TURF_BELOW(turf_source) - if(ignore_walls) + var/audible_distance = CALCULATE_MAX_SOUND_AUDIBLE_DISTANCE(vol, maxdistance, falloff_distance, falloff_exponent) + if(ignore_walls) if(above_turf && istransparentturf(above_turf)) listeners += SSmobs.clients_by_zlevel[above_turf.z] @@ -73,16 +77,16 @@ listeners += SSmobs.clients_by_zlevel[below_turf.z] else //these sounds don't carry through walls - listeners = get_hearers_in_view(maxdistance, turf_source) + listeners = get_hearers_in_view(audible_distance, turf_source) if(above_turf && istransparentturf(above_turf)) - listeners += get_hearers_in_view(maxdistance, above_turf) + listeners += get_hearers_in_view(audible_distance, above_turf) if(below_turf && istransparentturf(turf_source)) - listeners += get_hearers_in_view(maxdistance, below_turf) + listeners += get_hearers_in_view(audible_distance, below_turf) for(var/mob/listening_mob in listeners | SSmobs.dead_players_by_zlevel[source_z])//observers always hear through walls - if(get_dist(listening_mob, turf_source) <= maxdistance) + if(get_dist(listening_mob, turf_source) <= audible_distance) listening_mob.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb) . += listening_mob @@ -122,15 +126,16 @@ else sound_to_use.frequency = get_rand_frequency() + var/distance = 0 + if(isturf(turf_source)) var/turf/turf_loc = get_turf(src) //sound volume falloff with distance - var/distance = get_dist(turf_loc, turf_source) * distance_multiplier + distance = get_dist(turf_loc, turf_source) * distance_multiplier if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff. - sound_to_use.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * sound_to_use.volume - //https://www.desmos.com/calculator/sqdfl8ipgf + sound_to_use.volume -= CALCULATE_SOUND_VOLUME(vol, distance, max_distance, falloff_distance, falloff_exponent) if(pressure_affected) //Atmosphere affects sound @@ -151,7 +156,7 @@ sound_to_use.volume *= pressure_factor //End Atmosphere affecting sound - if(sound_to_use.volume <= 0) + if(sound_to_use.volume < SOUND_AUDIBLE_VOLUME_MIN) return //No sound var/dx = turf_source.x - turf_loc.x // Hearing from the right/left @@ -176,6 +181,9 @@ sound_to_use.echo[3] = -1300 //Room setting, 0 means normal reverb //NOVA EDIT CHANGE sound_to_use.echo[4] = -1300 //RoomHF setting, 0 means normal reverb. //NOVA EDIT CHANGE + if(HAS_TRAIT(src, TRAIT_SOUND_DEBUGGED)) + to_chat(src, span_admin("Max Range-[max_distance] Distance-[distance] Vol-[round(sound_to_use.volume, 0.01)] Sound-[sound_to_use.file]")) + SEND_SOUND(src, sound_to_use) /proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S) diff --git a/code/game/turfs/baseturfs.dm b/code/game/turfs/baseturfs.dm index ad016b634477..b65d1a6b71db 100644 --- a/code/game/turfs/baseturfs.dm +++ b/code/game/turfs/baseturfs.dm @@ -112,17 +112,16 @@ /// Replaces all instances of needle_type in baseturfs with replacement_type /turf/proc/replace_baseturf(needle_type, replacement_type) if (islist(baseturfs)) - var/list/new_baseturfs + var/list/new_baseturfs = baseturfs.Copy() - while (TRUE) - var/found_index = baseturfs.Find(needle_type) + for(var/base_i in 1 to length(new_baseturfs)) + var/found_index = new_baseturfs.Find(needle_type) if (found_index == 0) break - new_baseturfs ||= baseturfs.Copy() new_baseturfs[found_index] = replacement_type - if (!isnull(new_baseturfs)) + if (length(new_baseturfs)) baseturfs = baseturfs_string_list(new_baseturfs, src) else if (baseturfs == needle_type) baseturfs = replacement_type diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index 513bdc3d0b2f..19f4a4639d29 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -221,6 +221,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( QUEUE_SMOOTH_NEIGHBORS(src) QUEUE_SMOOTH(src) + // we need to update gravity for any mob on a tile that is being created or destroyed + for(var/mob/living/target in new_turf.contents) + target.refresh_gravity() + return new_turf /turf/open/ChangeTurf(path, list/new_baseturfs, flags) //Resist the temptation to make this default to keeping air. diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index b7789fc5c8c9..e7b161721e86 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -215,9 +215,13 @@ dismantle_wall() /turf/closed/wall/r_wall/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if(the_rcd.canRturf || the_rcd.construction_mode == RCD_WALLFRAME) + if (the_rcd.construction_mode == RCD_WALLFRAME) return ..() - + if(!the_rcd.canRturf) + return + . = ..() + if (.) + .["delay"] *= RCD_RWALL_DELAY_MULT /turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) if(the_rcd.canRturf || rcd_data["[RCD_DESIGN_MODE]"] == RCD_WALLFRAME) diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 170a29bc0ab9..a8fbaebc4846 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -49,15 +49,18 @@ underlay_appearance.icon_state = fixed_underlay["icon_state"] fixed_underlay = string_assoc_list(fixed_underlay) underlays += underlay_appearance + register_context() + +/turf/closed/wall/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(!isnull(held_item)) + if((initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS) && held_item.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "Adjust Wall Corner" + return CONTEXTUAL_SCREENTIP_SET /turf/closed/wall/mouse_drop_receive(atom/dropping, mob/user, params) - . = ..() - if (added_leaning) - return - /// For performance reasons and to cut down on init times we are "lazy-loading" the leaning component when someone drags their sprite onto us, and then calling dragging code again to trigger the component - AddComponent(/datum/component/leanable, 11) - added_leaning = TRUE - dropping.base_mouse_drop_handler(src, null, null, params) + //Adds the component only once. We do it here & not in Initialize() because there are tons of walls & we don't want to add to their init times + LoadComponent(/datum/component/leanable, dropping) /turf/closed/wall/atom_destruction(damage_flag) . = ..() @@ -69,7 +72,9 @@ return ..() /turf/closed/wall/examine(mob/user) - . += ..() + . = ..() + if(initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS) + . += span_notice("You could adjust its corners with a wrench.") . += deconstruction_hints(user) /turf/closed/wall/proc/deconstruction_hints(mob/user) @@ -173,7 +178,7 @@ **arg2 is the hulk */ /turf/closed/wall/proc/hulk_recoil(obj/item/bodypart/arm, mob/living/carbon/human/hulkman, damage = 20) - arm.receive_damage(brute = damage, blocked = 0, wound_bonus = CANT_WOUND) + hulkman.apply_damage(damage, BRUTE, arm, wound_bonus = CANT_WOUND) var/datum/mutation/human/hulk/smasher = locate(/datum/mutation/human/hulk) in hulkman.dna.mutations if(!smasher || !damage) //sanity check but also snow and wood walls deal no recoil damage, so no arm breaky return @@ -329,3 +334,15 @@ /turf/closed/wall/Exited(atom/movable/gone, direction) . = ..() SEND_SIGNAL(gone, COMSIG_LIVING_WALL_EXITED, src) + +/turf/closed/wall/wrench_act(mob/living/user, obj/item/tool) + if(user.combat_mode || !(initial(smoothing_flags) & SMOOTH_DIAGONAL_CORNERS)) + return ITEM_INTERACT_SKIP_TO_ATTACK + if(smoothing_flags & SMOOTH_DIAGONAL_CORNERS) + smoothing_flags &= ~SMOOTH_DIAGONAL_CORNERS + else + smoothing_flags |= SMOOTH_DIAGONAL_CORNERS + QUEUE_SMOOTH(src) + to_chat(user, span_notice("You adjust [src].")) + tool.play_tool_sound(src) + return ITEM_INTERACT_SUCCESS diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index 1772769649fa..11d2d0c630cb 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -337,14 +337,10 @@ for(var/mob/living/basic/slime/M in src) M.apply_water() - wash(CLEAN_WASH) - for(var/atom/movable/movable_content as anything in src) - if(ismopable(movable_content)) // Will have already been washed by the wash call above at this point. - continue - movable_content.wash(CLEAN_WASH) + wash(CLEAN_WASH, TRUE) return TRUE -/turf/open/handle_slip(mob/living/carbon/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, force_drop) +/turf/open/handle_slip(mob/living/slipper, knockdown_amount, obj/slippable, lube, paralyze_amount, force_drop) if(slipper.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) return FALSE if(!has_gravity(src)) @@ -390,9 +386,10 @@ SEND_SIGNAL(slipper, COMSIG_ON_CARBON_SLIP) slipper.add_mood_event("slipped", /datum/mood_event/slipped) - if(force_drop) + if(force_drop && iscarbon(slipper)) //carbon specific behavior that living doesn't have + var/mob/living/carbon/carbon = slipper for(var/obj/item/item in slipper.held_items) - slipper.accident(item) + carbon.accident(item) var/olddir = slipper.dir slipper.moving_diagonally = 0 //If this was part of diagonal move slipping will stop it. @@ -407,7 +404,7 @@ slipper.Knockdown(knockdown_amount) slipper.Paralyze(paralyze_amount) - if(buckled_obj) + if(!isnull(buckled_obj) && !ismob(buckled_obj)) buckled_obj.unbuckle_mob(slipper) // This is added onto the end so they slip "out of their chair" (one tile) lube |= SLIDE_ICE diff --git a/code/game/turfs/open/chasm.dm b/code/game/turfs/open/chasm.dm index 2699b4933626..003719d3bdf6 100644 --- a/code/game/turfs/open/chasm.dm +++ b/code/game/turfs/open/chasm.dm @@ -55,22 +55,26 @@ return TRUE /turf/open/chasm/attackby(obj/item/C, mob/user, params, area/area_restriction) - ..() - if(istype(C, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = C - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - return - if(!R.use(1)) - to_chat(user, span_warning("You need one rod to build a lattice.")) - return - to_chat(user, span_notice("You construct a lattice.")) - playsound(src, 'sound/items/weapons/genhit.ogg', 50, TRUE) - // Create a lattice, without reverting to our baseturf - new /obj/structure/lattice(src) - return - else if(istype(C, /obj/item/stack/tile/iron)) + . = ..() + if(ismetaltile(C)) build_with_floor_tiles(C, user) + return + + if(!istype(C, /obj/item/stack/rods)) + return + + var/obj/item/stack/rods/R = C + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + if(L) + return + if(!R.use(1)) + to_chat(user, span_warning("You need one rod to build a lattice.")) + return + to_chat(user, span_notice("You construct a lattice.")) + playsound(src, 'sound/items/weapons/genhit.ogg', 50, TRUE) + // Create a lattice, without reverting to our baseturf + new /obj/structure/lattice(src) + /// Handles adding the chasm component to the turf (So stuff falls into it!) /turf/open/chasm/proc/apply_components(mapload) @@ -137,6 +141,6 @@ /turf/open/chasm/true/no_smooth/attackby(obj/item/item, mob/user, params, area/area_restriction) if(istype(item, /obj/item/stack/rods)) return - else if(istype(item, /obj/item/stack/tile/iron)) + else if(ismetaltile(item)) return return ..() diff --git a/code/game/turfs/open/floor/plating.dm b/code/game/turfs/open/floor/plating.dm index e918cd72e8c7..8c3e395b4d42 100644 --- a/code/game/turfs/open/floor/plating.dm +++ b/code/game/turfs/open/floor/plating.dm @@ -135,26 +135,28 @@ /turf/open/floor/plating/foam/break_tile() return //jetfuel can't break steel foam... -/turf/open/floor/plating/foam/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/stack/tile/iron)) - var/obj/item/stack/tile/iron/P = I - if(P.use(1)) - var/obj/L = locate(/obj/structure/lattice) in src - if(L) - qdel(L) - to_chat(user, span_notice("You reinforce the foamed plating with tiling.")) - playsound(src, 'sound/items/weapons/Genhit.ogg', 50, TRUE) - ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) +/turf/open/floor/plating/foam/attackby(obj/item/attacking_item, mob/user, params) + if(ismetaltile(attacking_item)) + var/obj/item/stack/tile/tiles = attacking_item + if(!tiles.use(1)) + return + var/obj/lattice = locate(/obj/structure/lattice) in src + if(lattice) + qdel(lattice) + to_chat(user, span_notice("You reinforce the foamed plating with tiling.")) + playsound(src, 'sound/items/weapons/Genhit.ogg', 50, TRUE) + ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + return + + playsound(src, 'sound/items/weapons/tap.ogg', 100, TRUE) //The attack sound is muffled by the foam itself + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + if(prob(attacking_item.force * 20 - 25)) + user.visible_message(span_danger("[user] smashes through [src]!"), \ + span_danger("You smash through [src] with [attacking_item]!")) + ScrapeAway(flags = CHANGETURF_INHERIT_AIR) else - playsound(src, 'sound/items/weapons/tap.ogg', 100, TRUE) //The attack sound is muffled by the foam itself - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - if(prob(I.force * 20 - 25)) - user.visible_message(span_danger("[user] smashes through [src]!"), \ - span_danger("You smash through [src] with [I]!")) - ScrapeAway(flags = CHANGETURF_INHERIT_AIR) - else - to_chat(user, span_danger("You hit [src], to no effect!")) + to_chat(user, span_danger("You hit [src], to no effect!")) /turf/open/floor/plating/foam/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if(the_rcd.mode == RCD_TURF && the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 283ee3c31901..a71ed37f374f 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -228,10 +228,10 @@ to_chat(user, span_warning("The [ciggie.name] is already lit!")) return TRUE var/clumsy_modifier = HAS_TRAIT(user, TRAIT_CLUMSY) ? 2 : 1 - if(prob(25 * clumsy_modifier )) + if(prob(25 * clumsy_modifier) && isliving(user)) ciggie.light(span_warning("[user] expertly dips \the [ciggie.name] into [src], along with the rest of [user.p_their()] arm. What a dumbass.")) - var/obj/item/bodypart/affecting = user.get_active_hand() - affecting?.receive_damage(burn = 90) + var/mob/living/burned_guy = user + burned_guy.apply_damage(90, BURN, user.get_active_hand()) else ciggie.light(span_rose("[user] expertly dips \the [ciggie.name] into [src], lighting it with the scorching heat of the planet. Witnessing such a feat is almost enough to make you cry.")) return TRUE @@ -266,12 +266,9 @@ /turf/open/lava/proc/can_burn_stuff(atom/movable/burn_target) if(QDELETED(burn_target)) return LAVA_BE_IGNORING - if(burn_target.movement_type & MOVETYPES_NOT_TOUCHING_GROUND || !burn_target.has_gravity()) //you're flying over it. + if((burn_target.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) || burn_target.throwing || !burn_target.has_gravity()) //you're flying over it. return LAVA_BE_IGNORING - if(isobj(burn_target)) - if(burn_target.throwing) // to avoid gulag prisoners easily escaping, throwing only works for objects. - return LAVA_BE_IGNORING var/obj/burn_obj = burn_target if((burn_obj.resistance_flags & immunity_resistance_flags)) return LAVA_BE_PROCESSING @@ -285,7 +282,7 @@ var/mob/living/burn_living = burn_target var/atom/movable/burn_buckled = burn_living.buckled if(burn_buckled) - if(burn_buckled.movement_type & MOVETYPES_NOT_TOUCHING_GROUND || !burn_buckled.has_gravity()) + if((burn_buckled.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) || burn_buckled.throwing || !burn_buckled.has_gravity()) return LAVA_BE_PROCESSING if(isobj(burn_buckled)) var/obj/burn_buckled_obj = burn_buckled diff --git a/code/game/turfs/open/misc.dm b/code/game/turfs/open/misc.dm index f00e6ed6ded6..f99d45387489 100644 --- a/code/game/turfs/open/misc.dm +++ b/code/game/turfs/open/misc.dm @@ -21,16 +21,17 @@ heat_capacity = 20000 tiled_dirt = TRUE -/turf/open/misc/attackby(obj/item/W, mob/user, params) +/turf/open/misc/attackby(obj/item/attacking_item, mob/user, params) . = ..() if(.) return TRUE - if(istype(W, /obj/item/stack/rods)) - build_with_rods(W, user) + if(istype(attacking_item, /obj/item/stack/rods)) + build_with_rods(attacking_item, user) return TRUE - else if(istype(W, /obj/item/stack/tile/iron)) - build_with_floor_tiles(W, user) + + if(ismetaltile(attacking_item)) + build_with_floor_tiles(attacking_item, user) return TRUE /turf/open/misc/attack_paw(mob/user, list/modifiers) diff --git a/code/game/turfs/open/openspace.dm b/code/game/turfs/open/openspace.dm index 9b9c739f397c..e9f8beadf0d6 100644 --- a/code/game/turfs/open/openspace.dm +++ b/code/game/turfs/open/openspace.dm @@ -113,18 +113,18 @@ /turf/open/openspace/proc/CanBuildHere() return can_build_on -/turf/open/openspace/attackby(obj/item/C, mob/user, params) +/turf/open/openspace/attackby(obj/item/attacking_item, mob/user, params) ..() if(!CanBuildHere()) return - if(istype(C, /obj/item/stack/rods)) - build_with_rods(C, user) - else if(istype(C, /obj/item/stack/tile/iron)) - build_with_floor_tiles(C, user) - else if(istype(C, /obj/item/stack/thermoplastic)) - build_with_transport_tiles(C, user) - else if(istype(C, /obj/item/stack/sheet/mineral/titanium)) - build_with_titanium(C, user) + if(istype(attacking_item, /obj/item/stack/rods)) + build_with_rods(attacking_item, user) + else if(ismetaltile(attacking_item)) + build_with_floor_tiles(attacking_item, user) + else if(istype(attacking_item, /obj/item/stack/thermoplastic)) + build_with_transport_tiles(attacking_item, user) + else if(istype(attacking_item, /obj/item/stack/sheet/mineral/titanium)) + build_with_titanium(attacking_item, user) /turf/open/openspace/build_with_floor_tiles(obj/item/stack/tile/iron/used_tiles) if(!CanCoverUp()) @@ -151,7 +151,7 @@ return FALSE /turf/open/openspace/CanAStarPass(to_dir, datum/can_pass_info/pass_info) - var/atom/movable/our_movable = pass_info.caller_ref.resolve() + var/atom/movable/our_movable = pass_info.requester_ref.resolve() if(our_movable && !our_movable.can_z_move(DOWN, src, null, ZMOVE_FALL_FLAGS)) //If we can't fall here (flying/lattice), it's fine to path through return TRUE return FALSE diff --git a/code/game/turfs/open/space/space.dm b/code/game/turfs/open/space/space.dm index ddc322185d29..1142afb4e4d1 100644 --- a/code/game/turfs/open/space/space.dm +++ b/code/game/turfs/open/space/space.dm @@ -138,14 +138,14 @@ GLOBAL_LIST_EMPTY(starlight) /turf/open/space/handle_slip() return -/turf/open/space/attackby(obj/item/C, mob/user, params) +/turf/open/space/attackby(obj/item/attacking_item, mob/user, params) ..() if(!CanBuildHere()) return - if(istype(C, /obj/item/stack/rods)) - build_with_rods(C, user) - else if(istype(C, /obj/item/stack/tile/iron) || istype(C, /obj/item/stack/tile/material) && C.has_material_type(/datum/material/iron)) - build_with_floor_tiles(C, user) + if(istype(attacking_item, /obj/item/stack/rods)) + build_with_rods(attacking_item, user) + else if(ismetaltile(attacking_item)) + build_with_floor_tiles(attacking_item, user) /turf/open/space/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index f8b1d5ab743b..b78f88e64fb0 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -91,6 +91,7 @@ icon_state = "tizira_water" base_icon_state = "tizira_water" baseturfs = /turf/open/water/beach/tizira + fishing_datum = /datum/fish_source/tizira /** * A special subtype of water with steam particles and a status effect similar to showers, that's however only applied if @@ -112,6 +113,13 @@ /turf/open/water/hot_spring/Initialize(mapload) . = ..() + // We need to add the immerse element now because the icon_states are randomized and + // we don't want to end up with 4 different immerse elements, which would cause + // the immerse trait to be repeatedly removed and readded as someone moves within the pool, + // replacing the status effect over and over, which can be seen through the status effect alert icon. + if(!immerse_added) // NOVA EDIT ADDITION + AddElement(/datum/element/immerse, icon, icon_state, "immerse", immerse_overlay_color, alpha = immerse_overlay_alpha) // NOVA EDIT CHANGE - Indented into if block + immerse_added = TRUE icon_state = "pool_[rand(1, 4)]" particle_effect = new(src, /particles/hotspring_steam, 4) //render the steam over mobs and objects on the game plane @@ -121,8 +129,7 @@ add_filter("hot_spring_waves", 1, wave_filter(y = 1, size = 1, offset = 0, flags = WAVE_BOUNDED)) var/filter = get_filter("hot_spring_waves") animate(filter, offset = 1, time = 3 SECONDS, loop = -1, easing = SINE_EASING|EASE_IN|EASE_OUT) - animate(offset = -1, time = 3 SECONDS, easing = SINE_EASING|EASE_IN|EASE_OUT) - + animate(offset = 0, time = 3 SECONDS, easing = SINE_EASING|EASE_IN|EASE_OUT) /turf/open/water/hot_spring/Destroy() QDEL_NULL(particle_effect) @@ -137,11 +144,7 @@ return enter_hot_spring(arrived) -/turf/open/water/hot_spring/proc/enter_initialized_movable(datum/source, atom/movable/movable) - SIGNAL_HANDLER - if(!immerse_added && !is_type_in_typecache(movable, GLOB.immerse_ignored_movable)) - AddElement(/datum/element/immerse, icon, icon_state, "immerse", immerse_overlay_color, alpha = immerse_overlay_alpha) - immerse_added = TRUE +/turf/open/water/hot_spring/on_atom_inited(datum/source, atom/movable/movable) enter_hot_spring(movable) ///Registers the signals from the immerse element and calls dip_in if the movable has the required trait. diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index cb1ddd97ede0..b780fc13323e 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -703,19 +703,14 @@ GLOBAL_LIST_EMPTY(station_turfs) var/reac_volume = reagents[reagent] . |= reagent.expose_turf(src, reac_volume) -/** - * Called when this turf is being washed. Washing a turf will also wash any mopable floor decals - */ -/turf/wash(clean_types) +// When our turf is washed, we may wash everything on top of the turf +// By default we will only wash mopable things (like blood or vomit) +// but you may optionally pass in all_contents = TRUE to wash everything +/turf/wash(clean_types, all_contents = FALSE) . = ..() - - for(var/am in src) - if(am == src) - continue - var/atom/movable/movable_content = am - if(!ismopable(movable_content)) - continue - movable_content.wash(clean_types) + for(var/atom/movable/to_clean as anything in src) + if(all_contents || HAS_TRAIT(to_clean, TRAIT_MOPABLE)) + to_clean.wash(clean_types) /turf/set_density(new_value) var/old_density = density @@ -741,16 +736,16 @@ GLOBAL_LIST_EMPTY(station_turfs) * Returns adjacent turfs to this turf that are reachable, in all cardinal directions * * Arguments: - * * caller: The movable, if one exists, being used for mobility checks to see what tiles it can reach + * * requester: The movable, if one exists, being used for mobility checks to see what tiles it can reach * * access: A list that decides if we can gain access to doors that would otherwise block a turf * * simulated_only: Do we only worry about turfs with simulated atmos, most notably things that aren't space? * * no_id: When true, doors with public access will count as impassible */ -/turf/proc/reachableAdjacentTurfs(atom/movable/caller, list/access, simulated_only, no_id = FALSE) +/turf/proc/reachableAdjacentTurfs(atom/movable/requester, list/access, simulated_only, no_id = FALSE) var/static/space_type_cache = typecacheof(/turf/open/space) . = list() - var/datum/can_pass_info/pass_info = new(caller, access, no_id) + var/datum/can_pass_info/pass_info = new(requester, access, no_id) for(var/iter_dir in GLOB.cardinals) var/turf/turf_to_check = get_step(src,iter_dir) if(!turf_to_check || (simulated_only && space_type_cache[turf_to_check.type])) diff --git a/code/game/world.dm b/code/game/world.dm index 18d35b5b083a..84a32c663787 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -423,8 +423,6 @@ GLOBAL_PROTECT(tracy_init_reason) new_status += "
Time: [time2text(STATION_TIME_PASSED(), "hh:mm", 0)]" if(SSshuttle?.emergency && SSshuttle?.emergency?.mode != (SHUTTLE_IDLE || SHUTTLE_ENDGAME)) new_status += " | Shuttle: [SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]" - if(SStime_track?.time_dilation_avg > 0) - new_status += " | Time Dilation: [round(SStime_track?.time_dilation_avg)]%" else if(SSticker.current_state == GAME_STATE_FINISHED) new_status += "
RESTARTING" if(SSmapping.current_map) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5f40de037f4a..986a1c2a5a04 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -19,31 +19,33 @@ if(!check_rights(0)) return - var/dat = "
Game Panel

" + var/dat if(SSticker.current_state <= GAME_STATE_PREGAME) - dat += "(Manage Dynamic Rulesets)
" - dat += "(Force Roundstart Rulesets)
" + dat += "(Manage Dynamic Rulesets)
" + dat += "(Force Roundstart Rulesets)
" if (GLOB.dynamic_forced_roundstart_ruleset.len > 0) for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) - dat += {"-> [rule.name] <-
"} - dat += "(Clear Rulesets)
" - dat += "(Dynamic mode options)
" - dat += "
" + dat += {"-> [rule.name] <-
"} + dat += "(Clear Rulesets)
" + dat += "(Dynamic mode options)
" + dat += "
" if(SSticker.IsRoundInProgress()) - dat += "(Game Mode Panel)
" - dat += "(Manage Dynamic Rulesets)
" + dat += "(Game Mode Panel)
" + dat += "(Manage Dynamic Rulesets)
" + dat += "
" dat += {" -
- Create Object
- Quick Create Object
- Create Turf
- Create Mob
+ Create Object
+ Quick Create Object
+ Create Turf
+ Create Mob
"} if(marked_datum && istype(marked_datum, /atom)) - dat += "Duplicate Marked Datum
" + dat += "Duplicate Marked Datum
" - usr << browse(dat, "window=admin2;size=240x280") + var/datum/browser/browser = new(usr, "admin2", "Game Panel", 240, 280) + browser.set_content(dat) + browser.open() return ////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS @@ -104,36 +106,37 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA BLACKBOX_LOG_ADMIN_VERB("Spawn Cargo") /datum/admins/proc/dynamic_mode_options(mob/user) - var/dat = {" -

Dynamic Mode Options


-
-

Common options

+ var/dat = {"

Common options

All these options can be changed midround.

- Force extended: - Option is [GLOB.dynamic_forced_extended ? "ON" : "OFF"]. + Force extended: - Option is [GLOB.dynamic_forced_extended ? "ON" : "OFF"].
This will force the round to be extended. No rulesets will be drafted.

- No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"]. + No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"].
Unless the threat goes above [GLOB.dynamic_stacking_limit], only one "round-ender" ruleset will be drafted.

- Forced threat level: Current value : [GLOB.dynamic_forced_threat_level]. + Forced threat level: Current value : [GLOB.dynamic_forced_threat_level].
The value threat is set to if it is higher than -1.


- Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit]. + Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit].
The threshold at which "round-ender" rulesets will stack. A value higher than 100 ensure this never happens.
- "} + "} - user << browse(dat, "window=dyn_mode_options;size=900x650") + var/datum/browser/browser = new(user, "dyn_mode_options", "Dynamic Mode Options", 900, 650) + browser.set_content(dat) + browser.open() /datum/admins/proc/dynamic_ruleset_manager(mob/user) - var/dat = "

Dynamic Ruleset Management


\ - Change these options to forcibly enable or disable dynamic rulesets.
\ - Disabled rulesets will never run, even if they would otherwise be valid.
\ - Enabled rulesets will run even if the qualifying minimum of threat or player count is not present, this does not guarantee that they will necessarily be chosen (for example their weight may be set to 0 in config).
\ - \[force enable all / \ - force disable all / \ - reset all\]" + var/datum/browser/browser = new(user, "dyn_mode_options", "Dynamic Ruleset Management", 900, 650) + var/dat = {" + Change these options to forcibly enable or disable dynamic rulesets.
+ Disabled rulesets will never run, even if they would otherwise be valid.
+ Enabled rulesets will run even if the qualifying minimum of threat or player count is not present, this does not guarantee that they will necessarily be chosen (for example their weight may be set to 0 in config).
+ force enable all + force disable all + reset all + "} if (SSticker.current_state <= GAME_STATE_PREGAME) // Don't bother displaying after the round has started var/static/list/rulesets_by_context = list() @@ -146,29 +149,31 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA dat += dynamic_ruleset_category_pre_start_display("Roundstart", rulesets_by_context[ROUNDSTART_RULESET]) dat += dynamic_ruleset_category_pre_start_display("Latejoin", rulesets_by_context[LATEJOIN_RULESET]) dat += dynamic_ruleset_category_pre_start_display("Midround", rulesets_by_context[MIDROUND_RULESET]) - user << browse(dat, "window=dyn_mode_options;size=900x650") + browser.set_content(dat) + browser.open() return var/pop_count = length(GLOB.alive_player_list) var/threat_level = SSdynamic.threat_level dat += dynamic_ruleset_category_during_round_display("Latejoin", SSdynamic.latejoin_rules, pop_count, threat_level) dat += dynamic_ruleset_category_during_round_display("Midround", SSdynamic.midround_rules, pop_count, threat_level) - user << browse(dat, "window=dyn_mode_options;size=900x650") + browser.set_content(dat) + browser.open() /datum/admins/proc/dynamic_ruleset_category_pre_start_display(title, list/rules) var/dat = "

[title]

" for (var/datum/dynamic_ruleset/rule as anything in rules) var/forced = GLOB.dynamic_forced_rulesets[rule] || RULESET_NOT_FORCED - var/color = COLOR_BLACK + var/color = COLOR_SILVER switch (forced) if (RULESET_FORCE_ENABLED) color = COLOR_GREEN if (RULESET_FORCE_DISABLED) color = COLOR_RED - dat += "" + dat += "" dat += "
[initial(rule.name)]\[[forced]\]\[\ - force enabled /\ - force disabled /\ - reset\]
[initial(rule.name)]\[ [forced] \] \ + force enabled \ + force disabled \ + reset
" return dat @@ -196,13 +201,14 @@ ADMIN_VERB(spawn_cargo, R_SPAWN, "Spawn Cargo", "Spawn a cargo crate.", ADMIN_CA explanation = " - Forcibly enabled" active = active ? "Active" : "Inactive" - dat += "[rule.name]\ - \[Weight : [rule.weight]\]\ - \[[active][explanation]\]\[\ - force enabled /\ - force disabled /\ - reset\]\ - \[VV\]" + dat += {"[rule.name] + \[ Weight: [rule.weight] \] + \[ [active][explanation] \] + force enabled + force disabled + reset + VV + "} dat += "" return dat diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index a329ad595fa5..e38401986654 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -61,4 +61,7 @@ ADMIN_VERB(investigate_show, R_NONE, "Investigate", "Browse various detailed log if(!fexists(F)) to_chat(user, span_danger("No [selected] logfile was found."), confidential = TRUE) return - user << browse(F,"window=investigate[selected];size=800x300") + + var/datum/browser/browser = new(user, "investigate[selected]", "Investigation of [selected]", 800, 300) + browser.set_content(file2text(F)) + browser.open() diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 9997e9ad5778..be57f2c342d8 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -30,7 +30,7 @@ GLOBAL_VAR(antag_prototypes) /datum/antagonist/proc/antag_panel() var/list/commands = list() for(var/command in get_admin_commands()) - commands += "[command]" + commands += "[command]" var/command_part = commands.Join(" | ") var/data_part = antag_panel_data() var/objective_part = antag_panel_objectives() @@ -47,32 +47,32 @@ GLOBAL_VAR(antag_prototypes) var/obj_count = 1 for(var/datum/objective/objective as anything in objectives) result += "[obj_count]: [objective.explanation_text] \ - Edit \ - Delete \ - [objective.completed ? "Mark as incomplete" : "Mark as complete"] \ + Edit \ + Delete \ + [objective.completed ? "Mark as incomplete" : "Mark as complete"] \
" obj_count++ - result += "Add objective
" - result += "Prompt custom objective entry
" - result += "Announce objectives
" + result += "Add objective
" + result += "Prompt custom objective entry
" + result += "Announce objectives
" return result /datum/mind/proc/get_common_admin_commands() var/common_commands = "Common Commands:" if(ishuman(current)) - common_commands += "undress" + common_commands += "undress" else if(iscyborg(current)) var/mob/living/silicon/robot/R = current if(R.emagged) - common_commands += "Unemag" + common_commands += "Unemag" else if(isAI(current)) var/mob/living/silicon/ai/A = current if (A.connected_robots.len) for (var/mob/living/silicon/robot/R in A.connected_robots) if (R.emagged) - common_commands += "Unemag slaved cyborgs" + common_commands += "Unemag slaved cyborgs" break - common_commands += "Toggle exploitables override" //NOVA EDIT ADDITION -- EXPLOITABLES + common_commands += "Toggle exploitables override" //NOVA EDIT ADDITION -- EXPLOITABLES return common_commands /datum/mind/proc/get_special_statuses() @@ -100,9 +100,9 @@ GLOBAL_VAR(antag_prototypes) var/out = "[name][(current && (current.real_name != name))?" (as [current.real_name])":""]
" out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
" - out += "Assigned role: [assigned_role.title]. Edit
" + out += "Assigned role: [assigned_role.title]. Edit
" out += "Faction and special role: [special_role]
" - out += "Show Teams

" + out += "Show Teams

" var/special_statuses = get_special_statuses() if(length(special_statuses)) @@ -139,7 +139,7 @@ GLOBAL_VAR(antag_prototypes) continue //Let's skip subtypes of what we already shown. else if(prototype.show_in_antagpanel) if(prototype.can_be_owned(src)) - possible_admin_antags += "[prototype.name]" + possible_admin_antags += "[prototype.name]" else possible_admin_antags += "[prototype.name]" else @@ -156,8 +156,8 @@ GLOBAL_VAR(antag_prototypes) else //Show removal and current one priority_sections |= antag_category antag_header_parts += span_bad("[current_antag.name]") - antag_header_parts += "Remove" - antag_header_parts += "Open VV" + antag_header_parts += "Remove" + antag_header_parts += "Open VV" //We aren't antag of this category, grab first prototype to check the prefs (This is pretty vague but really not sure how else to do this) @@ -197,19 +197,19 @@ GLOBAL_VAR(antag_prototypes) var/datum/component/uplink/U = find_syndicate_uplink() if(U) if(!U.uplink_handler.has_objectives) - uplink_info += "take" + uplink_info += "take" if (check_rights(R_FUN, 0)) - uplink_info += ", [U.uplink_handler.telecrystals] TC" + uplink_info += ", [U.uplink_handler.telecrystals] TC" if(U.uplink_handler.has_progression) - uplink_info += ", [U.uplink_handler.progression_points] PR" + uplink_info += ", [U.uplink_handler.progression_points] PR" if(U.uplink_handler.has_objectives) - uplink_info += ", Force Give Objective" + uplink_info += ", Force Give Objective" else uplink_info += ", [U.uplink_handler.telecrystals] TC" if(U.uplink_handler.has_progression) uplink_info += ", [U.uplink_handler.progression_points] PR" else - uplink_info += "give" + uplink_info += "give" uplink_info += "." //hiel grammar out += uplink_info + "
" diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm index 0069ce27cedf..1965f15d0d15 100644 --- a/code/modules/admin/check_antagonists.dm +++ b/code/modules/admin/check_antagonists.dm @@ -5,9 +5,9 @@ if(!owner) return "Unassigned" if(owner.current) - return "[owner.current.real_name] " + return "[owner.current.real_name] " else - return "[owner.name] " + return "[owner.name] " //Whatever interesting things happened to the antag admins should know about //Include additional information about antag in this part @@ -28,12 +28,12 @@ if(!owner) return var/list/parts = list() - parts += "PM" + parts += "PM" if(owner.current) //There's body to follow - parts += "FLW" + parts += "FLW" else parts += "" - parts += "Show Objective" + parts += "Show Objective" return parts //Better as one cell or two/three //Builds table row for the antag @@ -95,26 +95,26 @@ tgui_alert(usr, "The game hasn't started yet!") return var/list/dat = list("Round Status

Round Status

") - dat += "Game Mode Panel
" + dat += "Game Mode Panel
" dat += "Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]
" dat += "Emergency shuttle
" if(EMERGENCY_IDLE_OR_RECALLED) - dat += "Call Shuttle
" + dat += "Call Shuttle
" else var/timeleft = SSshuttle.emergency.timeLeft() if(SSshuttle.emergency.mode == SHUTTLE_CALL) - dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" - dat += "Send Back
" + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" + dat += "Send Back
" else - dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" - dat += "End Round Now
" + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
" + dat += "End Round Now
" if(SSticker.delay_end) - dat += "Undelay Round End
" + dat += "Undelay Round End
" else - dat += "Delay Round End
" - dat += "Enable/Disable CTF
" - dat += "Reboot World
" - dat += "Check Teams" + dat += "Delay Round End
" + dat += "Enable/Disable CTF
" + dat += "Reboot World
" + dat += "Check Teams" var/connected_players = GLOB.clients.len var/lobby_players = 0 var/observers = 0 diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index f045f101de23..c4a67fbde586 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -47,7 +47,7 @@ * * (IE, no wacky hair styles / colors) */ -/proc/randomize_human_normie(mob/living/carbon/human/human, randomize_mutations = FALSE) +/proc/randomize_human_normie(mob/living/carbon/human/human, randomize_mutations = FALSE, update_body = TRUE) // Sorry enbys but statistically you are not average enough human.gender = human.dna.species.sexes ? pick(MALE, FEMALE) : PLURAL human.physique = human.gender @@ -69,4 +69,5 @@ // Normal DNA init stuff, these can generally be wacky but we care less, they're aliens after all human.dna.initialize_dna(newblood_type = random_blood_type(), create_mutation_blocks = randomize_mutations, randomize_features = TRUE) human.updatehealth() - human.updateappearance(mutcolor_update = TRUE) + if(update_body) + human.updateappearance(mutcolor_update = TRUE) diff --git a/code/modules/admin/greyscale_modify_menu.dm b/code/modules/admin/greyscale_modify_menu.dm index 54d98c14848c..b966c936c622 100644 --- a/code/modules/admin/greyscale_modify_menu.dm +++ b/code/modules/admin/greyscale_modify_menu.dm @@ -241,14 +241,24 @@ This is highly likely to cause massive amounts of lag as every object in the gam config.EnableAutoRefresh(config_owner_type) /datum/greyscale_modify_menu/proc/ReadColorsFromString(colorString) - var/list/new_split_colors = list() + //length validation var/list/colors = splittext(colorString, "#") - for(var/index in 2 to min(length(colors), config.expected_colors + 1)) + if(length(colors) <= 1) //doesn't even begin with a # so isn't even a color + return FALSE + colors.Cut(1, 2) //removes the white space as a consequence of the string beginning with a # + if(colors.len != config.expected_colors) //not the expected length + return FALSE + + //value validation + var/list/new_split_colors = list() + for(var/index in 1 to config.expected_colors) var/color = "#[colors[index]]" if(!findtext(color, GLOB.is_color) && (!unlocked || !findtext(color, GLOB.is_alpha_color))) return FALSE new_split_colors += color split_colors = new_split_colors + + //all good return TRUE /datum/greyscale_modify_menu/proc/randomize_color(color_index) diff --git a/code/modules/admin/known_alts.dm b/code/modules/admin/known_alts.dm index 4105c7f4edc9..3c51ca68bdf1 100644 --- a/code/modules/admin/known_alts.dm +++ b/code/modules/admin/known_alts.dm @@ -168,7 +168,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new) var/list/known_alts_html = list() for (var/known_alt in load_known_alts()) - known_alts_html += "\[-\] Delete [known_alt[1]] is an alt of [known_alt[2]] (added by [known_alt[3]])." + known_alts_html += "\[-\] Delete [known_alt[1]] is an alt of [known_alt[2]] (added by [known_alt[3]])." var/html = {" @@ -179,7 +179,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new)

Any two ckeys in this panel will not show in "banned connection history".

Sometimes players switch account, and it's customary to perma-ban the old one.

-

All Known Alts:

\[+\] Add
+

All Known Alts:

\[+\] Add
[known_alts_html.Join("
")] diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index 73987622202e..e474fcff0955 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -7,11 +7,11 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm return var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/group/permissions) asset_cache_datum.send(usr) - var/list/output = list("\[Permissions\]") + var/list/output = list("\[Permissions\]") if(action) - output += " | \[Log\] | \[Management\]
" + output += " | \[Log\] | \[Management\]
" else - output += "
\[Log\]
\[Management\]" + output += "
\[Log\]
\[Management\]" if(action == 1) var/logcount = 0 var/logssperpage = 20 @@ -30,7 +30,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm if(logcount > logssperpage) output += "
Page: " while(logcount > 0) - output += "|[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" + output += "|[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" logcount -= logssperpage pagecount++ output += "|" @@ -69,7 +69,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm while(query_check_admin_errors.NextRow()) var/admin_key = query_check_admin_errors.item[1] var/admin_rank = query_check_admin_errors.item[2] - output += "[admin_key] has non-existent rank [admin_rank] | \[Change Rank\] | \[Remove\]" + output += "[admin_key] has non-existent rank [admin_rank] | \[Change Rank\] | \[Remove\]" output += "
" qdel(query_check_admin_errors) output += "

Unused ranks

" @@ -79,7 +79,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm return while(query_check_unused_rank.NextRow()) var/admin_rank = query_check_unused_rank.item[1] - output += {"Rank [admin_rank] is not held by any admin | \[Remove\] + output += {"Rank [admin_rank] is not held by any admin | \[Remove\]
Permissions: [rights2text(text2num(query_check_unused_rank.item[2])," ")]
Denied: [rights2text(text2num(query_check_unused_rank.item[3])," ", "-")]
Allowed to edit: [rights2text(text2num(query_check_unused_rank.item[4])," ", "*")] @@ -95,7 +95,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
- + @@ -110,18 +110,18 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm if(D.owner) adm_ckey = D.owner.key if (D.deadmined) - deadminlink = " \[RA\]" + deadminlink = " \[RA\]" else - deadminlink = " \[DA\]" + deadminlink = " \[DA\]" var/verify_link = "" if (D.blocked_by_2fa) - verify_link += " | \[2FA VERIFY\]" + verify_link += " | \[2FA VERIFY\]" output += "" - output += "" - output += "" - output += "" + output += "" + output += "" + output += "" output += "" output += "
CKEY \[+\]CKEY \[+\] RANK PERMISSIONS
[adm_ckey]
[deadminlink]\[-\]\[SYNC TGDB\][verify_link]
[D.rank_names()][rights2text(D.rank_flags(), " ")][adm_ckey]
[deadminlink]\[-\]\[SYNC TGDB\][verify_link]
[D.rank_names()][rights2text(D.rank_flags(), " ")]
Search:
" if(QDELETED(usr)) @@ -140,9 +140,14 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm permissions_assets.send(usr.client) var/admin_key = href_list["key"] var/admin_ckey = ckey(admin_key) - var/datum/admins/D = GLOB.admin_datums[admin_ckey] - var/use_db + var/task = href_list["editrights"] + var/datum/admins/target_admin_datum = GLOB.admin_datums[admin_ckey] + if(!target_admin_datum) + target_admin_datum = GLOB.deadmins[admin_ckey] + if (!target_admin_datum && task != "add") + return + var/use_db var/skip var/legacy_only if(task == "activate" || task == "deactivate" || task == "sync" || task == "verify") @@ -152,7 +157,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm to_chat(usr, "Editing the rank of this admin is blocked by server configuration.", confidential = TRUE) return if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_ranks) && task == "permissions") - if((D.ranks & GLOB.protected_ranks).len > 0) + if((target_admin_datum.ranks & GLOB.protected_ranks).len > 0) to_chat(usr, "Editing the flags of this rank is blocked by server configuration.", confidential = TRUE) return if(CONFIG_GET(flag/load_legacy_ranks_only) && (task == "add" || task == "rank" || task == "permissions")) @@ -173,16 +178,11 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm use_db = FALSE if(QDELETED(usr)) return - if(task != "add") - D = GLOB.admin_datums[admin_ckey] - if(!D) - D = GLOB.deadmins[admin_ckey] - if(!D) - return - if((task != "sync") && !check_if_greater_rights_than_holder(D)) - message_admins("[key_name_admin(usr)] attempted to change the rank of [admin_key] without sufficient rights.") - log_admin("[key_name(usr)] attempted to change the rank of [admin_key] without sufficient rights.") - return + + if(target_admin_datum && (task != "sync" && task != "verify") && !check_if_greater_rights_than_holder(target_admin_datum)) + message_admins("[key_name_admin(usr)] attempted to change the rank of [admin_key] without sufficient rights.") + log_admin("[key_name(usr)] attempted to change the rank of [admin_key] without sufficient rights.") + return switch(task) if("add") admin_ckey = add_admin(admin_ckey, admin_key, use_db) @@ -194,24 +194,24 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm change_admin_rank(admin_ckey, admin_key, use_db, null, legacy_only) if("remove") - remove_admin(admin_ckey, admin_key, use_db, D) + remove_admin(admin_ckey, admin_key, use_db, target_admin_datum) if("rank") - change_admin_rank(admin_ckey, admin_key, use_db, D, legacy_only) + change_admin_rank(admin_ckey, admin_key, use_db, target_admin_datum, legacy_only) if("permissions") - change_admin_flags(admin_ckey, admin_key, D) + change_admin_flags(admin_ckey, admin_key, target_admin_datum) if("activate") - force_readmin(admin_key, D) + force_readmin(admin_key, target_admin_datum) if("deactivate") - force_deadmin(admin_key, D) + force_deadmin(admin_key, target_admin_datum) if("sync") - sync_lastadminrank(admin_ckey, admin_key, D) + sync_lastadminrank(admin_ckey, admin_key, target_admin_datum) if("verify") var/msg = "has authenticated [admin_ckey]" message_admins("[key_name_admin(usr)] [msg]") log_admin("[key_name(usr)] [msg]") - D.bypass_2fa = TRUE - D.associate(GLOB.directory[admin_ckey]) + target_admin_datum.bypass_2fa = TRUE + target_admin_datum.associate(GLOB.directory[admin_ckey]) edit_admin_permissions() /datum/admins/proc/add_admin(admin_ckey, admin_key, use_db) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 31c34957544e..ddb02b78b8ac 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -80,19 +80,19 @@ body += ""; - body += "PP - " - body += "N - " - body += "VV - " - body += "SP - " - body += "TP - " + body += "PP - " + body += "N - " + body += "VV - " + body += "SP - " + body += "TP - " if (job == "Cyborg") - body += "BP - " - body += "PM - " - body += "SM - " - body += "FLW - " - body += "LOGS
" + body += "BP - " + body += "PM - " + body += "SM - " + body += "FLW - " + body += "LOGS
" if(antagonist > 0) - body += "Antagonist"; + body += "Antagonist"; body += ""; @@ -198,7 +198,7 @@ Player panel
- Hover over a line to see more information - Check antagonists - Kick everyone/AFKers in lobby + Hover over a line to see more information - Check antagonists - Kick everyone/AFKers in lobby

diff --git a/code/modules/admin/poll_management.dm b/code/modules/admin/poll_management.dm index 86f075d31134..88a38c90166b 100644 --- a/code/modules/admin/poll_management.dm +++ b/code/modules/admin/poll_management.dm @@ -71,12 +71,12 @@ * */ /datum/admins/proc/poll_list_panel() - var/list/output = list("Current and future polls
Note when editing polls or their options changes are not saved until you press Submit Poll.
New PollReload Polls


") + var/list/output = list("Current and future polls
Note when editing polls or their options changes are not saved until you press Submit Poll.
New PollReload Polls
") for(var/p in GLOB.polls) var/datum/poll_question/poll = p output += {"[poll.question] - Edit - Delete + Edit + Delete "} if(poll.subtitle) output += "
[poll.subtitle]" @@ -204,20 +204,20 @@
"} if(poll.poll_type == POLLTYPE_TEXT) - output += "Clear poll responses [poll.poll_votes] players have responded" + output += "Clear poll responses [poll.poll_votes] players have responded" else - output += "Clear poll votes [poll.poll_votes] players have voted" + output += "Clear poll votes [poll.poll_votes] players have voted" if(poll.poll_type == POLLTYPE_TEXT) output += "" else - output += "
Add Option
" + output += "
Add Option
" if(length(poll.options)) for(var/o in poll.options) var/datum/poll_option/option = o option_count++ output += {"Option [option_count] - Edit - Delete + Edit + Delete
[option.text] "} if(poll.poll_type == POLLTYPE_RATING) diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index 9f1d430a46c0..165b882ab46e 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -61,16 +61,16 @@ /obj/effect/sound_emitter/proc/edit_emitter(mob/user) var/dat = "" - dat += "Label: [maptext ? maptext : "No label set!"]
" + dat += "Label: [maptext ? maptext : "No label set!"]
" dat += "
" - dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
" - dat += "Volume: [sound_volume]%
" + dat += "Sound File: [sound_file ? sound_file : "No file chosen!"]
" + dat += "Volume: [sound_volume]%
" dat += "
" - dat += "Mode: [motus_operandi]
" + dat += "Mode: [motus_operandi]
" if(motus_operandi != SOUND_EMITTER_LOCAL) - dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
" + dat += "Range: [emitter_range][emitter_range == SOUND_EMITTER_RADIUS ? "[play_radius]-tile radius" : ""]
" dat += "
" - dat += "Play Sound (interrupts other sound emitter sounds)" + dat += "Play Sound (interrupts other sound emitter sounds)" var/datum/browser/popup = new(user, "emitter", "", 500, 600) popup.set_content(dat) popup.open() diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 270907cb1abd..243f6de57c79 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -758,7 +758,7 @@ var/pagecount = 1 var/list/pagelist = list() while(bancount > 0) - pagelist += "[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" + pagelist += "[pagecount == page ? "\[[pagecount]\]" : "\[[pagecount]\]"]" bancount -= bansperpage pagecount++ output += pagelist.Join(" | ") @@ -844,13 +844,13 @@ var/un_or_reban_href if(unban_datetime) - un_or_reban_href = "Reban" + un_or_reban_href = "Reban" else - un_or_reban_href = "Unban" - output += "Edit
[un_or_reban_href]" + un_or_reban_href = "Unban" + output += "Edit
[un_or_reban_href]" if(edits) - output += "
Edit log" + output += "
Edit log" output += "" qdel(query_unban_search_bans) output += "" diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index c44853646e3e..4022f27240a0 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -378,10 +378,10 @@ var/list/output = list() var/ruler = "
" - var/list/navbar = list("All#") + var/list/navbar = list("All#") for(var/letter in GLOB.alphabet) - navbar += "[letter]" - navbar += "MemosWatchlist" + navbar += "[letter]" + navbar += "MemosWatchlist" navbar += "
\ \ [HrefTokenFormField()]\ @@ -392,14 +392,14 @@ if(type == "memo" || type == "watchlist entry") if(type == "memo") output += "

Admin memos

" - output += "Add memo
" + output += "Add memo" else if(type == "watchlist entry") output += "

Watchlist entries

" - output += "Add watchlist entry" + output += "Add watchlist entry" if(filter) - output += "Unfilter clients" + output += "Unfilter clients" else - output += "Filter offline clients" + output += "Filter offline clients" output += ruler var/datum/db_query/query_get_type_messages = SSdbcore.NewQuery(/* NOVA EDIT CHANGE - MULTISERVER */{" SELECT @@ -446,11 +446,11 @@ if(expire_timestamp) output += " | Expires [expire_timestamp]" output += "" - output += " Change Expiry Time" - output += " Delete" - output += " Edit" + output += " Change Expiry Time" + output += " Delete" + output += " Edit" if(editor_key) - output += " Last edit by [editor_key] (Click here to see edit log)" + output += " Last edit by [editor_key] (Click here to see edit log)" output += "
[text]
" qdel(query_get_type_messages) if(target_ckey) @@ -527,21 +527,21 @@ if(!linkless) if(type == "note") if(severity) - data += "[severity == "none" ? "No" : "[capitalize(severity)]"] Severity" + data += "[severity == "none" ? "No" : "[capitalize(severity)]"] Severity" else - data += "N/A Severity" - data += " Change Expiry Time" - data += " Delete" + data += "N/A Severity" + data += " Change Expiry Time" + data += " Delete" if(type == "note") - data += " [secret ? "Secret" : "Not secret"]" + data += " [secret ? "Secret" : "Not secret"]" if(type == "message sent") data += " Message has been sent" if(editor_key) data += "|" else - data += " Edit" + data += " Edit" if(editor_key) - data += " Last edit by [editor_key] (Click here to see edit log)" + data += " Last edit by [editor_key] (Click here to see edit log)" data += "" data += "

[text]


" switch(type) @@ -566,12 +566,12 @@ qdel(query_get_message_key) output += "

[target_key]

" if(!linkless) - output += "Add note" - output += " Add message" - output += " Add to watchlist" - output += " Refresh page
" + output += "Add note" + output += " Add message" + output += " Add to watchlist" + output += " Refresh page" else - output += " Refresh page" + output += " Refresh page" output += ruler if(messagedata) output += "

Messages

" @@ -585,14 +585,14 @@ if(!linkless) if (agegate) if (skipped) //the first skipped message is still shown so that we can put this link over it. - output += "
Show [skipped] hidden messages
" + output += "
Show [skipped] hidden messages
" else - output += "
Show All
" + output += "
Show All
" else - output += "
Hide Old
" + output += "
Hide Old
" if(index) var/search - output += "
Add messageAdd watchlist entryAdd note
" + output += "
Add messageAdd watchlist entryAdd note
" output += ruler switch(index) if(1) @@ -622,10 +622,10 @@ var/index_key = query_list_messages.item[2] if(!index_key) index_key = index_ckey - output += "[index_key]
" + output += "[index_key]
" qdel(query_list_messages) else if(!type && !target_ckey && !index) - output += "
Add messageAdd watchlist entryAdd note
" + output += "
Add messageAdd watchlist entryAdd note
" output += ruler var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500) notes_assets.send(usr.client) @@ -693,7 +693,7 @@ var/list/text = list() for(var/datum/admin_message/message in get_message_output("message", display_to.ckey)) text += "Admin message left by [span_prefix("[message.admin_key]")] on [message.timestamp]" - text += "
[message.text] (Click here to verify you have read this message)
" + text += "
[message.text] (Click here to verify you have read this message)
" if(length(text)) to_chat(display_to, text.Join()) @@ -710,7 +710,7 @@ for(var/datum/admin_message/message in get_message_output("memo", display_to.ckey)) text += "[span_memo("Memo by [message.admin_key]")] on [message.timestamp]" if(message.editor_key) - text += "
[span_memoedit("Last edit by [message.editor_key] (Click here to see edit log)")]" + text += "
[span_memoedit("Last edit by [message.editor_key] (Click here to see edit log)")]" text += "
[message.text]

" if(length(text)) to_chat(display_to, text.Join()) diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm index fede9724ab18..4295080c3f6c 100644 --- a/code/modules/admin/stickyban.dm +++ b/code/modules/admin/stickyban.dm @@ -348,15 +348,15 @@ return var/timeout if (SSdbcore.Connect()) - timeout = "\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]" + timeout = "\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]" else - timeout = "\[revert\]" + timeout = "\[revert\]" . = list({" - \[-\] + \[-\] [timeout] [ckey]
" - [ban["message"]] \[Edit\]
+ [ban["message"]] \[Edit\]
"}) if (ban["admin"]) . += "[ban["admin"]]
" @@ -366,12 +366,12 @@ for (var/key in ban["keys"]) if (ckey(key) == ckey) continue - . += "
  • \[-\][key]\[E\]
  • " + . += "
  • \[-\][key]\[E\]
  • " for (var/key in ban["whitelist"]) if (ckey(key) == ckey) continue - . += "
  • \[-\][key]\[UE\]
  • " + . += "
  • \[-\][key]\[UE\]
  • " . += "\n" @@ -390,7 +390,7 @@ Sticky Bans -

    All Sticky Bans:

    \[+\]
    +

    All Sticky Bans:

    \[+\]
    [banhtml.Join("")] "} diff --git a/code/modules/admin/tag.dm b/code/modules/admin/tag.dm index e52112eba149..eb4b83184db8 100644 --- a/code/modules/admin/tag.dm +++ b/code/modules/admin/tag.dm @@ -40,8 +40,8 @@ to_chat(owner, span_warning("[target_datum] was not already tagged.")) /// Quick define for readability -#define TAG_DEL(X) "(UNTAG)" -#define TAG_MARK(X) "(MARK)" +#define TAG_DEL(X) "(UNTAG)" +#define TAG_MARK(X) "(MARK)" #define TAG_SIMPLE_HEALTH(X) "Health: [X.health]" #define TAG_CARBON_HEALTH(X) "Health: [X.health] (\ [X.getBruteLoss()] \ @@ -51,12 +51,12 @@ ADMIN_VERB(display_tags, R_ADMIN, "View Tags", "Display all of the tagged datums.", ADMIN_CATEGORY_GAME) var/index = 0 - var/list/dat = list("
    Tag Menu

    ") + var/list/dat = list() var/list/tagged_datums = user.holder.tagged_datums var/list/marked_datum = user.holder.marked_datum - dat += "
    Refresh
    " + dat += "
    Refresh
    " if(LAZYLEN(tagged_datums)) for(var/datum/iter_datum as anything in tagged_datums) index++ @@ -91,8 +91,9 @@ ADMIN_VERB(display_tags, R_ADMIN, "View Tags", "Display all of the tagged datums else dat += "No datums tagged :(" - dat = dat.Join("
    ") - user << browse(dat, "window=tag;size=800x480") + var/datum/browser/browser = new(user.mob, "tag", "Tag Menu", 800, 480) + browser.set_content(dat.Join("
    ")) + browser.open() #undef TAG_DEL #undef TAG_MARK diff --git a/code/modules/admin/team_panel.dm b/code/modules/admin/team_panel.dm index 30311c491e6f..3eba8be94941 100644 --- a/code/modules/admin/team_panel.dm +++ b/code/modules/admin/team_panel.dm @@ -3,22 +3,22 @@ var/list/content = list() for(var/datum/team/T in GLOB.antagonist_teams) content += "

    [T.name] - [T.type]

    " - content += "Rename" - content += "Delete" - content += "Communicate" + content += "Rename" + content += "Delete" + content += "Communicate" for(var/command in T.get_admin_commands()) - content += "[command]" + content += "[command]" content += "
    " content += "Objectives:
      " for(var/datum/objective/O in T.objectives) - content += "
    1. [O.explanation_text] - Remove
    2. " - content += "
    Add Objective
    " + content += "
  • [O.explanation_text] - Remove
  • " + content += "Add Objective
    " content += "Members:
      " for(var/datum/mind/M in T.members) - content += "
    • [M.name] - Remove Member
    • " - content += "
    Add Member" + content += "
  • [M.name] - Remove Member
  • " + content += "Add Member" content += "
    " - content += "Create Team
    " + content += "Create Team
    " return content.Join() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 153ba139f895..e4dc9abaa041 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -891,7 +891,7 @@ exportable_text += "[special_role_description]
    " exportable_text += ADMIN_FULLMONTY_NONAME(subject) - to_chat(src.owner, examine_block(exportable_text), confidential = TRUE) + to_chat(src.owner, boxed_message(exportable_text), confidential = TRUE) else if(href_list["addjobslot"]) if(!check_rights(R_ADMIN)) @@ -1424,7 +1424,9 @@ var/list/dat = list("Related accounts by [uppertext(href_list["showrelatedacc"])]:") dat += thing_to_check - usr << browse(dat.Join("
    "), "window=related_[C];size=420x300") + var/datum/browser/browser = new(usr, "related_[C]", "[C.ckey] Related Accounts", 420, 300) + browser.set_content(dat.Join("
    ")) + browser.open() else if(href_list["centcomlookup"]) if(!check_rights(R_ADMIN)) @@ -1783,7 +1785,7 @@ if(FAX.fax_id != href_list["destination"]) continue FAX.receive(locate(href_list["print_fax"]), href_list["sender_name"]) - + return else if(href_list["play_internet"]) if(!check_rights(R_SOUND)) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 4ee2b79f0445..f74df7127210 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -722,7 +722,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null /datum/sdql2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE) if(isdatum(object)) - text_list += "[REF(object)] : [object]" + text_list += "[REF(object)] : [object]" if(istype(object, /atom)) var/atom/A = object var/turf/T = A.loc diff --git a/code/modules/admin/verbs/admin.dm b/code/modules/admin/verbs/admin.dm index f0fb0e648e9f..4748ebdfc95c 100644 --- a/code/modules/admin/verbs/admin.dm +++ b/code/modules/admin/verbs/admin.dm @@ -45,7 +45,7 @@ ADMIN_VERB(cmd_admin_check_player_exp, R_ADMIN, "Player Playtime", "View player var/list/msg = list() msg += "Playtime ReportPlaytime:
    " user << browse(msg.Join(), "window=Player_playtime_check") diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 76d814e8ee05..81e568be9032 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -12,17 +12,17 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "Options panel for [player]" if(player.client) body += " played by [player.client] " - body += "\[[player.client.holder ? player.client.holder.rank_names() : "Player"]\]" + body += "\[[player.client.holder ? player.client.holder.rank_names() : "Player"]\]" if(CONFIG_GET(flag/use_exp_tracking)) - body += "\[" + player.client.get_exp_living(FALSE) + "\]" + body += "\[" + player.client.get_exp_living(FALSE) + "\]" if(isnewplayer(player)) body += " Hasn't Entered Game " else - body += " \[Heal\] " + body += " \[Heal\] " if(player.ckey) - body += "
    \[Find Updated Panel\]" + body += "
    \[Find Updated Panel\]" if(player.client) body += "
    \[First Seen: [player.client.player_join_date]\]\[Byond account registered on: [player.client.account_join_date]\]" @@ -42,12 +42,12 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo // NOVA EDIT ADDITION END body += "

    CentCom Galactic Ban DB: " if(CONFIG_GET(string/centcom_ban_db)) - body += "Search" + body += "Search" else body += "Disabled" body += "

    Show related accounts by: " - body += "\[ CID | " - body += "IP \]" + body += "\[ CID | " + body += "IP \]" var/full_version = "Unknown" if(player.client.byond_version) full_version = "[player.client.byond_version].[player.client.byond_build ? player.client.byond_build : "xxx"]" @@ -55,24 +55,24 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "

    \[ " - body += "VV - " + body += "VV - " if(player.mind) - body += "TP - " - body += "SKILLS - " + body += "TP - " + body += "SKILLS - " else - body += "Init Mind - " + body += "Init Mind - " if (iscyborg(player)) - body += "BP - " - body += "PM - " - body += "SM - " + body += "BP - " + body += "PM - " + body += "SM - " if (ishuman(player) && player.mind) - body += "HM - " - body += "FLW - " + body += "HM - " + body += "FLW - " //Default to client logs if available var/source = LOGSRC_MOB if(player.ckey) source = LOGSRC_CKEY - body += "LOGS\]
    " + body += "LOGS\]
    " body += "Mob type = [player.type]

    " @@ -85,41 +85,41 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo body += "None?!" body += "

    " - body += "Kick | " + body += "Kick | " if(player.client) - body += "Ban | " + body += "Ban | " else - body += "Ban | " + body += "Ban | " - body += "Notes | Messages | Watchlist | " + body += "Notes | Messages | Watchlist | " if(player.client) - body += "| Prison | " - body += "\ Send back to Lobby | " + body += "| Prison | " + body += "\ Send back to Lobby | " var/muted = player.client.prefs.muted body += "
    Mute: " - body += "\[IC | " - body += "OOC | " - body += "PRAY | " - body += "ADMINHELP | " - //Nova Edit Addition Begin - LOOC muting again. - body += "DEADCHAT | " - body += "LOOC\]" - //Nova Edit Addition End - LOOC muting again. - body += "WEBREQ | " - body += "DEADCHAT\]" - body += "(toggle all)" + body += "\[IC | " + body += "OOC | " + body += "PRAY | " + body += "ADMINHELP | " + // NOVA EDIT ADDITION START + body += "DEADCHAT | " + body += "LOOC\]" + // NOVA EDIT ADDITION END + body += "WEBREQ | " + body += "DEADCHAT\]" + body += "(toggle all)" body += "

    " - body += "Jump to | " - body += "Get | " - body += "Send To" + body += "Jump to | " + body += "Get | " + body += "Send To" body += "

    " - body += "Traitor panel | " - body += "Narrate to | " - body += "Subtle message | " - body += "Play sound to | " - body += "Language Menu" + body += "Traitor panel | " + body += "Narrate to | " + body += "Subtle message | " + body += "Play sound to | " + body += "Language Menu" if(player.client) if(!isnewplayer(player)) @@ -128,39 +128,39 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo if(isobserver(player)) body += "Ghost | " else - body += "Make Ghost | " + body += "Make Ghost | " if(ishuman(player) && !ismonkey(player)) body += "Human | " else - body += "Make Human | " + body += "Make Human | " if(ismonkey(player)) body += "Monkey | " else - body += "Make Monkey | " + body += "Make Monkey | " if(iscyborg(player)) body += "Cyborg | " else - body += "Make Cyborg | " + body += "Make Cyborg | " if(isAI(player)) body += "AI" else - body += "Make AI" + body += "Make AI" body += "

    " body += "Other actions:" body += "
    " if(!isnewplayer(player)) - body += "Forcesay | " - body += "Apply Client Quirks | " - body += "Thunderdome 1 | " - body += "Thunderdome 2 | " - body += "Thunderdome Admin | " - body += "Thunderdome Observer | " - body += "Commend Behavior | " + body += "Forcesay | " + body += "Apply Client Quirks | " + body += "Thunderdome 1 | " + body += "Thunderdome 2 | " + body += "Thunderdome Admin | " + body += "Thunderdome Observer | " + body += "Commend Behavior | " body += "
    " body += "" @@ -343,15 +343,15 @@ ADMIN_VERB(manage_job_slots, R_ADMIN, "Manage Job Slots", "Manage the number of dat += "" dat += "" if(job.total_positions >= 0) - dat += "Custom | " - dat += "Add 1 | " + dat += "Custom | " + dat += "Add 1 | " if(job.total_positions > job.current_positions) - dat += "Remove | " + dat += "Remove | " else dat += "Remove | " - dat += "Unlimit" + dat += "Unlimit" else - dat += "Limit" + dat += "Limit" browser.height = min(100 + count * 20, 650) browser.set_content(dat.Join()) @@ -435,21 +435,21 @@ ADMIN_VERB(lag_switch_panel, R_ADMIN, "Show Lag Switches", "Display the controls to_chat(user, span_notice("The Lag Switch subsystem has not yet been initialized.")) return var/list/dat = list("Lag Switches

    Lag (Reduction) Switches

    ") - dat += "Automatic Trigger: [SSlag_switch.auto_switch ? "On" : "Off"]
    " - dat += "Population Threshold: [SSlag_switch.trigger_pop]
    " - dat += "Slowmode Cooldown (toggle On/Off below): [SSlag_switch.slowmode_cooldown/10] seconds
    " - dat += "
    SET ALL MEASURES: ON | OFF
    " - dat += "
    Disable ghosts zoom and t-ray verbs (except staff): [SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]
    " - dat += "Disable late joining: [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]
    " + dat += "Automatic Trigger: [SSlag_switch.auto_switch ? "On" : "Off"]
    " + dat += "Population Threshold: [SSlag_switch.trigger_pop]
    " + dat += "Slowmode Cooldown (toggle On/Off below): [SSlag_switch.slowmode_cooldown/10] seconds
    " + dat += "
    SET ALL MEASURES: ON | OFF
    " + dat += "
    Disable ghosts zoom and t-ray verbs (except staff): [SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]
    " + dat += "Disable late joining: [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]
    " dat += "
    ============! MAD GHOSTS ZONE !============
    " - dat += "Disable deadmob keyLoop (except staff, informs dchat): [SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]
    " + dat += "Disable deadmob keyLoop (except staff, informs dchat): [SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]
    " dat += "==========================================
    " dat += "
    Measures below can be bypassed with a special trait
    " - dat += "Slowmode say verb (informs world): [SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]
    " - dat += "Disable runechat: [SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
    " - dat += "Disable examine icons: [SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"] - trait applies to examiner
    " - dat += "Disable parallax: [SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"] - trait applies to character
    " - dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character
    " - dat += "Disable character creator: [SSlag_switch.measures[DISABLE_CREATOR] ? "On" : "Off"] - trait applies to all
    " // NOVA EDIT ADDITION + dat += "Slowmode say verb (informs world): [SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]
    " + dat += "Disable runechat: [SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
    " + dat += "Disable examine icons: [SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"] - trait applies to examiner
    " + dat += "Disable parallax: [SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"] - trait applies to character
    " + dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character
    " + dat += "Disable character creator: [SSlag_switch.measures[DISABLE_CREATOR] ? "On" : "Off"] - trait applies to all
    " // NOVA EDIT ADDITION dat += "" user << browse(dat.Join(), "window=lag_switch_panel;size=420x480") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index e19bd806327b..2eb09ba8d512 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -84,10 +84,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(!l2b) return var/list/dat = list("[title]") - dat += "Refresh

    " + dat += "Refresh

    " for(var/I in l2b) var/datum/admin_help/AH = I - dat += "[span_adminnotice("[span_adminhelp("Ticket #[AH.id]")]: [AH.initiator_key_name]: [AH.name]")]
    " + dat += "[span_adminnotice("[span_adminhelp("Ticket #[AH.id]")]: [AH.initiator_key_name]: [AH.name]")]
    " usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480") @@ -383,32 +383,32 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(!ref_src) ref_src = "[REF(src)]" . = ADMIN_FULLMONTY_NONAME(initiator.mob) - . += " (NOTES)" + . += " (NOTES)" if(state == AHELP_ACTIVE) if (CONFIG_GET(flag/popup_admin_pm)) - . += " (POPUP)" + . += " (POPUP)" . += ClosureLinks(ref_src) //private /datum/admin_help/proc/ClosureLinks(ref_src) if(!ref_src) ref_src = "[REF(src)]" - . = " (REJT)" - . += " (IC)" - . += " (CLOSE)" - . += " (RSLVE)" + . = " (REJT)" + . += " (IC)" + . += " (CLOSE)" + . += " (RSLVE)" //private /datum/admin_help/proc/LinkedReplyName(ref_src) if(!ref_src) ref_src = "[REF(src)]" - return "[initiator_key_name]" + return "[initiator_key_name]" //private /datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket") if(!ref_src) ref_src = "[REF(src)]" - return "[msg]" + return "[msg]" //message from the initiator without a target, all admins will see this //won't bug irc/discord @@ -416,7 +416,12 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) var/ref_src = "[REF(src)]" //Message to be sent to all admins - var/admin_msg = span_adminnotice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]: [span_linkify(keywords_lookup(msg))]")) + var/admin_msg = fieldset_block( + span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]"), + "[LinkedReplyName(ref_src)]\n\n\ + [span_linkify(keywords_lookup(msg))]\n\n\ + [FullMonty(ref_src)]", + "boxed_message red_box") AddInteraction("[LinkedReplyName(ref_src)]: [msg]", player_message = "[LinkedReplyName(ref_src)]: [msg]") log_admin_private("Ticket #[id]: [key_name(initiator)]: [msg]") @@ -610,7 +615,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) // Helper for opening directly to player ticket history dat += "

    Player Ticket History:" - dat += "[FOURSPACES]Open" + dat += "[FOURSPACES]Open" // Append any tickets also opened by this user if relevant var/list/related_tickets = GLOB.ahelp_tickets.TicketsByCKey(initiator_ckey) @@ -709,7 +714,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) dat += "CLOSED" else dat += "UNKNOWN" - dat += "\n[FOURSPACES]Refresh" + dat += "\n[FOURSPACES]Refresh" dat += "

    Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" if(closed_at) dat += "
    Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" @@ -851,7 +856,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) set category = "Admin" set name = "Adminhelp" GLOB.admin_help_ui_handler.ui_interact(mob) - to_chat(src, span_boldnotice("Adminhelp failing to open or work? Click here")) + to_chat(src, span_boldnotice("Adminhelp failing to open or work? Click here")) /client/verb/view_latest_ticket() set category = "Admin" @@ -1070,7 +1075,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) if(is_special_character(found)) is_antag = 1 founds += "Name: [found.name]([found.real_name]) Key: [found.key] Ckey: [found.ckey] [is_antag ? "(Antag)" : null] " - msg += "[original_word](?|F) " + msg += "[original_word](?|F) " continue msg += "[original_word] " if(external) @@ -1153,7 +1158,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) var/datum/datum_check = locate(word_with_brackets) if(!istype(datum_check)) continue - msglist[i] = "[word]" + msglist[i] = "[word]" modified = TRUE if("#") // check if we're linking a ticket @@ -1174,7 +1179,7 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new) if(AHELP_RESOLVED) state_word = "Resolved" - msglist[i]= "[word] ([state_word] | [ahelp_check.initiator_key_name])" + msglist[i]= "[word] ([state_word] | [ahelp_check.initiator_key_name])" modified = TRUE if(modified) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 1aacb1b30967..26e3571dd5c4 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -387,20 +387,11 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM recipient_ticket_id = recipient_ticket?.id SSblackbox.LogAhelp(recipient_ticket_id, "Ticket Opened", send_message, recipient.ckey, src.ckey) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = "-- Administrator private message --", - confidential = TRUE) - recipient.receive_ahelp( link_to_us, span_linkify(send_message), ) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = span_adminsay("Click on the administrator's name to reply."), - confidential = TRUE) to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_notice("Admin PM to-[their_name_with_link]: [span_linkify(send_message)]"), @@ -713,21 +704,11 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM message_admins("External message from [sender] to [recipient_name_linked] : [message]") log_admin_private("External PM: [sender] -> [recipient_name] : [message]") - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = "-- Administrator private message --", - confidential = TRUE) - recipient.receive_ahelp( - "[adminname]", + "[adminname]", message, ) - to_chat(recipient, - type = MESSAGE_TYPE_ADMINPM, - html = span_adminsay("Click on the administrator's name to reply."), - confidential = TRUE) - admin_ticket_log(recipient, "PM From [tgs_tagged]: [message]", log_in_blackbox = FALSE) window_flash(recipient, ignorepref = TRUE) @@ -772,8 +753,13 @@ ADMIN_VERB(cmd_admin_pm_panel, R_NONE, "Admin PM", "Show a list of clients to PM to_chat( src, type = MESSAGE_TYPE_ADMINPM, - html = "Admin PM from-[reply_to]: [message]", - confidential = TRUE, + html = fieldset_block( + span_adminhelp("Administrator private message"), + "Admin PM from-[reply_to]\n\n\ + [message]\n\n\ + Click on the administrator's name to reply.", + "boxed_message red_box"), + confidential = TRUE ) current_ticket?.player_replied = FALSE diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 13f1995c9ba3..fc054e9a9cb0 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -480,9 +480,11 @@ ADMIN_VERB(modify_goals, R_ADMIN, "Modify Goals", "Modify the station goals for /datum/admins/proc/modify_goals() var/dat = "" for(var/datum/station_goal/goal as anything in SSstation.get_station_goals()) - dat += "[goal.name] - Announce | Remove
    " - dat += "
    Add New Goal" - usr << browse(dat, "window=goals;size=400x400") + dat += "[goal.name] - Announce | Remove
    " + dat += "
    Add New Goal" + var/datum/browser/browser = new(usr, "goals", "Modify Goals", 400, 400) + browser.set_content(dat) + browser.open() ADMIN_VERB(debug_mob_lists, R_DEBUG, "Debug Mob Lists", "For when you just gotta know.", ADMIN_CATEGORY_DEBUG) var/chosen_list = tgui_input_list(user, "Which list?", "Select List", list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Clients","Joined Clients")) @@ -541,7 +543,9 @@ ADMIN_VERB(display_overlay_log, R_DEBUG, "Display Overlay Log", "Display SSoverl render_stats(SSoverlays.stats, user) ADMIN_VERB(init_log, R_DEBUG, "Display Initialize() Log", "Displays a list of things that didn't handle Initialize() properly.", ADMIN_CATEGORY_DEBUG) - user << browse(replacetext(SSatoms.InitLog(), "\n", "
    "), "window=initlog") + var/datum/browser/browser = new(user, "initlog", "Initialize Log", 500, 500) + browser.set_content(replacetext(SSatoms.InitLog(), "\n", "
    ")) + browser.open() ADMIN_VERB(debug_color_test, R_DEBUG, "Colorblind Testing", "Change your view to a budget version of colorblindness to test for usability.", ADMIN_CATEGORY_DEBUG) user.holder.color_test.ui_interact(user.mob) @@ -724,13 +728,15 @@ ADMIN_VERB(check_timer_sources, R_DEBUG, "Check Timer Sources", "Checks the sour var/bucket_list_output = generate_timer_source_output(SStimer.bucket_list) var/second_queue = generate_timer_source_output(SStimer.second_queue) - user << browse({" + var/datum/browser/browser = new(user, "check_timer_sources", "Timer Sources", 700, 700) + browser.set_content({"

    bucket_list

    [bucket_list_output]

    second_queue

    [second_queue] - "}, "window=check_timer_sources;size=700x700") + "}) + browser.open() ADMIN_VERB(reestablish_tts_connection, R_DEBUG, "Re-establish Connection To TTS", "Re-establishes connection to the TTS server if possible", ADMIN_CATEGORY_DEBUG) message_admins("[key_name_admin(user)] attempted to re-establish connection to the TTS HTTP server.") @@ -743,6 +749,14 @@ ADMIN_VERB(reestablish_tts_connection, R_DEBUG, "Re-establish Connection To TTS" message_admins("[key_name_admin(user)] successfully re-established the connection to the TTS HTTP server.") log_admin("[key_name(user)] successfully re-established the connection to the TTS HTTP server.") +ADMIN_VERB(allow_browser_inspect, R_DEBUG, "Allow Browser Inspect", "Allow browser debugging via inspect", ADMIN_CATEGORY_DEBUG) + if(user.byond_version < 516) + to_chat(user, span_warning("You can only use this on 516!")) + return + + to_chat(user, span_notice("You can now right click to use inspect on browsers.")) + winset(user, null, list("browser-options" = "+devtools")) + /proc/generate_timer_source_output(list/datum/timedevent/events) var/list/per_source = list() diff --git a/code/modules/admin/verbs/individual_logging.dm b/code/modules/admin/verbs/individual_logging.dm index d9df055ba1bb..eb665d35f658 100644 --- a/code/modules/admin/verbs/individual_logging.dm +++ b/code/modules/admin/verbs/individual_logging.dm @@ -75,4 +75,4 @@ slabel = "\[[label]\]" //This is necessary because num2text drops digits and rounds on big numbers. If more defines get added in the future it could break again. log_type = num2text(log_type, MAX_BITFLAG_DIGITS) - return "[slabel]" + return "[slabel]" diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index a27aca0f0147..3251e9febd27 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -61,8 +61,8 @@ ADMIN_VERB(map_template_upload, R_DEBUG, "Map Template - Upload", "Upload a map var/report_link if(report) report.show_to(user) - report_link = " - validation report" - to_chat(user, span_warning("Map template '[map]' failed validation."), confidential = TRUE) + report_link = " - validation report" + to_chat(user, span_warning("Map template '[map]' failed validation."), confidential = TRUE) if(report.loadable) var/response = tgui_alert(user, "The map failed validation, would you like to load it anyways?", "Map Errors", list("Cancel", "Upload Anyways")) if(response != "Upload Anyways") diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 8309eb79f38a..6227d09c09c9 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -84,7 +84,7 @@ ADMIN_VERB(show_map_reports, R_DEBUG, "Show Map Reports", "Displays a list of ma var/dat = {"List of all map reports:
    "} for(var/datum/map_report/report as anything in GLOB.map_reports) - dat += "[report.tag] ([report.original_path]) - View
    " + dat += "[report.tag] ([report.original_path]) - View
    " user << browse(dat, "window=map_reports") @@ -229,7 +229,7 @@ ADMIN_VERB(create_mapping_job_icons, R_DEBUG, "Generate job landmarks icons", "G ADMIN_VERB_VISIBILITY(debug_z_levels, ADMIN_VERB_VISIBLITY_FLAG_MAPPING_DEBUG) ADMIN_VERB(debug_z_levels, R_DEBUG, "Debug Z-Levels", "Displays a list of all z-levels and their linkages.", ADMIN_CATEGORY_MAPPING) - to_chat(user, examine_block(gather_z_level_information(append_grid = TRUE)), confidential = TRUE) + to_chat(user, boxed_message(gather_z_level_information(append_grid = TRUE)), confidential = TRUE) /// Returns all necessary z-level information. Argument `append_grid` allows the user to see a table showing all of the z-level linkages, which is only visible and useful in-game. /proc/gather_z_level_information(append_grid = FALSE) diff --git a/code/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index 38d7535758fc..1749e5a5b6ad 100644 --- a/code/modules/admin/verbs/maprotation.dm +++ b/code/modules/admin/verbs/maprotation.dm @@ -67,19 +67,12 @@ ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_ fdel("data/custom_map_json/[config_file]") if(!fcopy(config_file, "data/custom_map_json/[config_file]")) return - if (virtual_map.LoadConfig("data/custom_map_json/[config_file]", TRUE) != TRUE) + + json_value = virtual_map.LoadConfig("data/custom_map_json/[config_file]", TRUE) + + if(!json_value) to_chat(src, span_warning("Failed to load config: [config_file]. Check that the fields are filled out correctly. \"map_path\": \"custom\" and \"map_file\": \"your_map_name.dmm\"")) return - json_value = list( - "version" = MAP_CURRENT_VERSION, - "map_name" = virtual_map.map_name, - "map_path" = virtual_map.map_path, - "map_file" = virtual_map.map_file, - "shuttles" = virtual_map.shuttles, - "traits" = virtual_map.traits, - "job_changes" = virtual_map.job_changes, - "library_areas" = virtual_map.library_areas, - ) else virtual_map = load_map_config() virtual_map.map_name = input(user, "Choose the name for the map", "Map Name") as null|text diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 82c6bdc48043..4277cae7d81f 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -58,7 +58,7 @@ for(var/client/staff as anything in GLOB.admins) if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - to_chat(GLOB.admins, msg, confidential = TRUE) + to_chat(GLOB.admins, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE) for(var/obj/machinery/computer/communications/console in GLOB.shuttle_caller_list) console.override_cooldown() @@ -70,7 +70,7 @@ for(var/client/staff as anything in GLOB.admins) if(staff?.prefs.read_preference(/datum/preference/toggle/comms_notification)) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - to_chat(GLOB.admins, msg, confidential = TRUE) + to_chat(GLOB.admins, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE) for(var/obj/machinery/computer/communications/console in GLOB.shuttle_caller_list) console.override_cooldown() @@ -81,6 +81,6 @@ msg = span_adminnotice("NUKE CODE REQUEST:[ADMIN_FULLMONTY(sender)] [ADMIN_CENTCOM_REPLY(sender)] [ADMIN_SET_SD_CODE]: [msg]") for(var/client/staff as anything in GLOB.admins) SEND_SOUND(staff, sound('sound/misc/server-ready.ogg')) - to_chat(GLOB.admins, msg, confidential = TRUE) + to_chat(GLOB.admins, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE) for(var/obj/machinery/computer/communications/console in GLOB.shuttle_caller_list) console.override_cooldown() diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index e43164419d59..e13291ed2369 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -51,19 +51,23 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w switch(action) //Generic Buttons anyone can use. if("admin_log") - var/dat = "Admin Log
    " + var/dat for(var/l in GLOB.admin_activities) dat += "
  • [l]
  • " if(!GLOB.admin_activities.len) dat += "No-one has done anything this round!" - holder << browse(dat, "window=admin_log") + var/datum/browser/browser = new(holder, "admin_log", "Admin Logs", 600, 500) + browser.set_content(dat) + browser.open() if("show_admins") - var/dat = "Current admins:
    " + var/dat if(GLOB.admin_datums) for(var/ckey in GLOB.admin_datums) var/datum/admins/D = GLOB.admin_datums[ckey] dat += "[ckey] - [D.rank_names()]
    " - holder << browse(dat, "window=showadmins;size=600x500") + var/datum/browser/browser = new(holder, "showadmins", "Current admins", 600, 500) + browser.set_content(dat) + browser.open() //Buttons for debug. if("maint_access_engiebrig") if(!is_debugger) @@ -348,6 +352,34 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound()) else priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound()) + if("send_shuttle_back") + if (!is_funmin) + return + if (SSshuttle.emergency.mode != SHUTTLE_ESCAPE) + to_chat(usr, span_warning("Emergency shuttle not currently in transit!"), confidential = TRUE) + return + var/make_announcement = tgui_alert(usr, "Make a CentCom announcement?", "Emergency shuttle return", list("Yes", "Custom Text", "No")) || "No" + var/announcement_text = "Emergency shuttle trajectory overriden, rerouting course back to [station_name()]." + if (make_announcement == "Custom Text") + announcement_text = tgui_input_text(usr, "Custom CentCom announcement", "Emergency shuttle return", multiline = TRUE) || announcement_text + var/new_timer = tgui_input_number(usr, "How long should the shuttle remain in transit?", "When are we droppin' boys?", 180, 600) + if (isnull(new_timer) || SSshuttle.emergency.mode != SHUTTLE_ESCAPE) + return + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send Shuttle Back")) + message_admins("[key_name_admin(holder)] sent the escape shuttle back to the station") + if (make_announcement != "No") + priority_announce( + text = announcement_text, + title = "Shuttle Trajectory Override", + sound = 'sound/announcer/announcement/announce_dig.ogg', + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "grey", + ) + SSshuttle.emergency.timer = INFINITY + if (new_timer > 0) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(return_escape_shuttle), make_announcement), new_timer SECONDS) + else + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(return_escape_shuttle), make_announcement) if("blackout") if(!is_funmin) return @@ -673,6 +705,27 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w T.flick_overlay_static(portal_appearance[GET_TURF_PLANE_OFFSET(T) + 1], 15) playsound(T, 'sound/effects/magic/lightningbolt.ogg', rand(80, 100), TRUE) +/// Docks the emergency shuttle back to the station and resets its' state +/proc/return_escape_shuttle(make_announcement) + if (SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"), force = TRUE) != DOCKING_SUCCESS) + message_admins("Emergency shuttle was unable to dock back to the station!") + SSshuttle.emergency.timer = 1 // Prevents softlocks + return + if (make_announcement != "No") + priority_announce( + text = "[SSshuttle.emergency] has returned to the station.", + title = "Emergency Shuttle Override", + sound = ANNOUNCER_SHUTTLEDOCK, + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "grey", + ) + SSshuttle.emergency.mode = SHUTTLE_IDLE + SSshuttle.emergency.timer = 0 + // Docks the pods back (don't ask about physics) + for (var/obj/docking_port/mobile/pod/pod in SSshuttle.mobile_docking_ports) + if (pod.previous) + pod.initiate_docking(pod.previous, force = TRUE) + /datum/everyone_is_an_antag_controller var/chosen_antag = "" var/objective = "" diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index b5891686119b..ab440db5f0ff 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -66,6 +66,12 @@ ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", #undef HARDEST_RESTART #undef TGS_RESTART +ADMIN_VERB(cancel_reboot, R_SERVER, "Cancel Reboot", "Cancels a pending world reboot.", ADMIN_CATEGORY_SERVER) + if(!SSticker.cancel_reboot(user)) + return + log_admin("[key_name(user)] cancelled the pending world reboot.") + message_admins("[key_name_admin(user)] cancelled the pending world reboot.") + ADMIN_VERB(end_round, R_SERVER, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) var/confirm = tgui_alert(user, "End the round and restart the game world?", "End Round", list("Yes", "Cancel")) if(confirm != "Yes") @@ -131,6 +137,8 @@ ADMIN_VERB(delay_round_end, R_ADMIN, "Delay Round End", "Prevent the server from SSticker.delay_end = TRUE SSticker.admin_delay_notice = delay_reason + if(SSticker.reboot_timer) + SSticker.cancel_reboot(user) log_admin("[key_name(user)] delayed the round end for reason: [SSticker.admin_delay_notice]") message_admins("[key_name_admin(user)] delayed the round end for reason: [SSticker.admin_delay_notice]") diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index c5a367e83a06..537ef5e611b5 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -23,7 +23,7 @@ display_value = "[display_value]:[icon_state]" var/display_ref = get_vv_link_ref() - return "[display_name] ([display_value]) [display_ref]" + return "[display_name] ([display_value]) [display_ref]" /// Returns the ref string to use when displaying this image in the vv menu of something else /image/proc/get_vv_link_ref() diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index 835da1a0b39c..b776f1b5d797 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -18,10 +18,10 @@ var/name_part = VV_HTML_ENCODE(name) if(level > 0 || islist(owner)) //handling keys in assoc lists if(istype(name,/datum)) - name_part = "[VV_HTML_ENCODE(name)] [REF(name)]" + name_part = "[VV_HTML_ENCODE(name)] [REF(name)]" else if(islist(name)) var/list/list_value = name - name_part = " /list ([length(list_value)]) [REF(name)]" + name_part = " /list ([length(list_value)]) [REF(name)]" . = "[.][name_part] = " @@ -85,9 +85,9 @@ items += debug_variable(key, val, level + 1, sanitize = sanitize) - return "/list ([list_value.len])
      [items.Join()]
    " + return "/list ([list_value.len])
      [items.Join()]
    " else - return "/list ([list_value.len])" + return "/list ([list_value.len])" if(name in GLOB.bitfields) var/list/flags = list() @@ -103,13 +103,13 @@ /datum/proc/debug_variable_value(name, level, datum/owner, sanitize, display_flags) if("[src]" != "[type]") // If we have a name var, let's use it. - return "[src] [type] [REF(src)]" + return "[src] [type] [REF(src)]" else - return "[type] [REF(src)]" + return "[type] [REF(src)]" /datum/weakref/debug_variable_value(name, level, datum/owner, sanitize, display_flags) . = ..() - return "[.] (Resolve)" + return "[.] (Resolve)" /matrix/debug_variable_value(name, level, datum/owner, sanitize, display_flags) return {" diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 4f3636531270..52b87fda1251 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -37,7 +37,7 @@ if(!target) to_chat(usr, span_warning("The object you tried to expose to [C] no longer exists (nulled or hard-deled)"), confidential = TRUE) return - message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [target]") to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window", confidential = TRUE) C.debug_variables(target) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index 66ac70f3f62f..fbebccd44598 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -257,7 +257,7 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
    - Refresh