diff --git a/.github/alternate_byond_versions.txt b/.github/alternate_byond_versions.txt index e1496d438cdc4..abf48559d8f04 100644 --- a/.github/alternate_byond_versions.txt +++ b/.github/alternate_byond_versions.txt @@ -2,7 +2,11 @@ # 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 +# 516.1638: runtimestation;516 +# Lowest supported version 515.1627: runtimestation +# Beta version +516.1648: runtimestation;516 diff --git a/.github/guides/STANDARDS.md b/.github/guides/STANDARDS.md index c27c8ae7417ec..00fc1efc3849a 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 8995f8b179eef..9bda54f768561 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -187,7 +187,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 @@ -223,7 +223,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' diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index a52a428a8258a..5e219273e1368 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/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 125324bb07ea4..f8c5523c2cc1e 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -20930,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" = ( @@ -30567,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 @@ -33247,10 +33243,14 @@ pixel_x = -7; pixel_y = 15 }, -/obj/structure/sign/warning/no_smoking/circle/directional/north, /obj/effect/turf_decal/siding/wood/end{ dir = 8 }, +/obj/machinery/barsign{ + chosen_sign = "thecavern"; + icon_state = "thecavern"; + pixel_y = 32 + }, /turf/open/floor/iron/dark/diagonal, /area/station/service/bar) "lnI" = ( @@ -58691,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" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index e26e6bf08ce2d..c074600e53d3b 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -3248,6 +3248,19 @@ }, /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, @@ -7833,23 +7846,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{ @@ -17847,6 +17843,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{ @@ -40190,10 +40196,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, @@ -46853,6 +46855,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, @@ -49360,6 +49371,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 @@ -53106,19 +53134,6 @@ }, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat_interior) -"nmT" = ( -/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) "nmU" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -62200,17 +62215,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, @@ -62609,6 +62613,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 @@ -75221,15 +75236,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/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) "sOs" = ( /obj/structure/chair/pew/left, /turf/open/floor/iron/chapel{ @@ -79126,17 +79132,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/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) "tNV" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -82524,6 +82519,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, @@ -84088,16 +84095,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/effect/turf_decal/box/red, -/obj/structure/disposaloutlet{ - dir = 8 - }, -/turf/open/floor/engine/xenobio, -/area/station/science/xenobiology) "uYg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/green, @@ -85078,6 +85075,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, @@ -94585,14 +94590,6 @@ /obj/structure/plasticflaps, /turf/open/floor/plating, /area/station/cargo/storage) -"xES" = ( -/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) "xEV" = ( /obj/item/target, /obj/effect/decal/cleanable/dirt, @@ -116405,7 +116402,7 @@ rIb rIb xdn gCt -uXU +etv uhb uhb nCi @@ -133034,7 +133031,7 @@ vRB gch xMe kVP -bSp +mph jcv aWP qrP @@ -133289,9 +133286,9 @@ pPI kVP xiu uMT -jVP +giz kVP -pET +uEz vwr aWP rpZ @@ -137501,10 +137498,10 @@ pdl fOJ kuU tOS -xES +vkV jqJ jqJ -sOp +lFL qYL jNY llm @@ -138021,7 +138018,7 @@ uue jdf qYL qpU -tNU +pJI aNV hvf vid @@ -151065,7 +151062,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 6ee4db7790ea9..dae0787c5921c 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/planet) "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/planet) "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/planet) "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/planet) "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/planet) "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/planet) "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/planet) "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/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) "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/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) "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/planet) "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/planet) "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/planet) "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/planet) "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/planet) "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/planet) "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/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) "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/planet) "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/planet) "mNi" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -46005,13 +45946,6 @@ dir = 4 }, /area/station/hallway/secondary/entry) -"nqI" = ( -/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) "nqP" = ( /obj/machinery/camera/directional/north{ c_tag = "Research Division West"; @@ -46413,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, @@ -47598,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 @@ -48372,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, @@ -48464,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 @@ -50621,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/planet) "oDg" = ( /obj/structure/chair/stool/directional/west, /obj/effect/decal/cleanable/dirt, @@ -51274,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/planet) "oLz" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -53846,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/structure/sign/flag/terragov/directional/north, -/obj/structure/weightmachine/weightlifter, -/turf/open/floor/iron, -/area/station/commons/fitness) "pyn" = ( /obj/item/storage/photo_album/chapel, /obj/structure/noticeboard/directional/west, @@ -55101,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/planet) "pRj" = ( /turf/closed/wall, /area/station/maintenance/port/aft) @@ -56818,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, @@ -56949,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{ @@ -58094,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/planet) "qKQ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -58194,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 @@ -65059,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, @@ -65267,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; @@ -69853,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{ @@ -69861,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, @@ -71029,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/planet) "uyW" = ( /obj/machinery/washing_machine, /obj/effect/turf_decal/siding/blue{ @@ -73203,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, @@ -75091,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, @@ -75454,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" @@ -75940,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, @@ -77009,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 @@ -77468,19 +77468,6 @@ }, /turf/open/floor/plating, /area/station/cargo/storage) -"wyF" = ( -/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) "wyL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ @@ -78502,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, @@ -79923,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/planet) "xgK" = ( /obj/structure/table, /obj/item/transfer_valve{ @@ -79986,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" @@ -80848,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{ @@ -81094,10 +81098,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/detectives_office) -"xyg" = ( -/obj/structure/weightmachine, -/turf/open/floor/iron, -/area/station/commons/fitness) "xyl" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 @@ -176310,7 +176310,7 @@ agF tgP rGh iJE -wyF +lgE yiL cVV dhi @@ -189470,7 +189470,7 @@ jre fuH fuH btU -hvt +xhp luR mlT lqZ @@ -249326,7 +249326,7 @@ cGB cGB gsI tLL -nqI +vJZ kKL kKL kKL @@ -250350,7 +250350,7 @@ skl gaC vfW vfW -xyg +jBY vfW lvk crv @@ -250604,7 +250604,7 @@ ygS oGr pDA skl -pyl +ufw uRo uRo uRo @@ -252418,7 +252418,7 @@ oqY kKL kKL kKL -sIb +sLI uXd iiE oIj @@ -255796,11 +255796,11 @@ oRu ccR uKj dDw -fsz +imT qgu tYA vds -mrD +wrt liz txH mFE @@ -272760,9 +272760,9 @@ bln bln bln bln -mvE -oDd -mvE +mhP +ufM +mhP bln bln wNO @@ -273016,11 +273016,11 @@ bln bln bln bln -xgI -mvE -anO -mvE -xgI +qMg +mhP +nYF +mhP +qMg bln bln wNO @@ -273272,13 +273272,13 @@ bln bln bln bln -mvE -mvE -cJB -oDd -aWb -mvE -mvE +mhP +mhP +dRU +ufM +qqh +mhP +mhP bln bln wNO @@ -273528,15 +273528,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 @@ -273785,15 +273785,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 @@ -274042,15 +274042,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 @@ -274300,13 +274300,13 @@ wNO wNO bln bln -mvE -mvE -mMU -uyV -lhf -mvE -mvE +mhP +mhP +vSo +fRr +wav +mhP +mhP bln bln wNO @@ -274558,11 +274558,11 @@ wNO wNO bln bln -xgI -mvE -beZ -mvE -xgI +qMg +mhP +viM +mhP +qMg bln bln wNO @@ -274816,9 +274816,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 e6aabf579de2a..d3aa4c1b33e93 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/effect/spawner/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,19 +11415,6 @@ }, /turf/open/floor/iron, /area/station/security/warden) -"eew" = ( -/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) "eey" = ( /obj/machinery/firealarm/directional/west, /obj/structure/rack, @@ -12773,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/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) "eBU" = ( /obj/machinery/light/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -15054,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/effect/spawner/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 @@ -15176,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, @@ -19124,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 @@ -28912,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 @@ -30840,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 @@ -31340,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, @@ -31396,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, @@ -37302,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 @@ -53804,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, @@ -61152,18 +61158,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/effect/spawner/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{ @@ -67594,6 +67588,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, @@ -87448,13 +87446,13 @@ rke jUb nTn jUb -fpg +ldm snb kpV qOO gGK snb -dyq +nnE jUb iEm kym @@ -88752,7 +88750,7 @@ tck kHg nMf vDc -eBO +aRk nCc msC tBJ @@ -94408,7 +94406,7 @@ uYI iqz iaK hZV -vzt +kkx jBU kgx kgx @@ -96630,7 +96628,7 @@ aaa aeq pfs jcc -eew +frt fnO gHA kaC @@ -105921,7 +105919,7 @@ aEr sDs tUv obG -lbX +gUe yks okX tZX @@ -106178,7 +106176,7 @@ biV fRS tUv obG -sZa +kTq vRU gpf ouk @@ -106435,7 +106433,7 @@ vFB fRS tUv obG -dSJ +xLM wrZ aWq oph @@ -106949,7 +106947,7 @@ vFB fRS sGH obG -aEA +ajn mZc iUe dLT diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index 047b54e5fd4bb..a7a67eac11dfe 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/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) "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/effect/spawner/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,18 +10545,6 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/primary/port) -"bDU" = ( -/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) "bDW" = ( /obj/item/bikehorn/rubberducky, /turf/open/misc/asteroid/snow/airless, @@ -12769,10 +12736,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/engineering/atmos) -"bUo" = ( -/obj/structure/cable, -/turf/open/floor/iron/solarpanel/airless, -/area/station/solars/port/aft) "bUs" = ( /obj/structure/cable, /obj/effect/spawner/random/trash/cigbutt, @@ -27667,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{ @@ -45634,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 @@ -56575,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/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) "isT" = ( /obj/effect/turf_decal/siding/dark{ dir = 1 @@ -58284,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, @@ -62233,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/effect/spawner/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) @@ -62776,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/effect/spawner/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 @@ -63649,16 +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, -/obj/machinery/firealarm/directional/north, -/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, @@ -64545,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/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) "jCb" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -64698,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, @@ -65662,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, @@ -76682,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 @@ -81357,18 +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, -/obj/machinery/firealarm/directional/south, -/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{ @@ -83277,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, @@ -85752,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, -/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 @@ -89600,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{ @@ -92158,14 +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"; - icon_angle = -45 - }, -/obj/structure/ladder, -/turf/open/floor/plating, -/area/station/engineering/supermatter/room/upper) "nKG" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners{ dir = 1 @@ -98768,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, @@ -105481,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 @@ -106602,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 @@ -113590,14 +113583,6 @@ }, /turf/open/floor/engine/n2, /area/station/engineering/atmos) -"qOe" = ( -/obj/item/ammo_casing/c357/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, @@ -120906,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/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) "rUp" = ( /obj/structure/hedge, /obj/machinery/light/small/dim/directional/north, @@ -122523,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 @@ -129434,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 @@ -154097,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 @@ -154750,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" @@ -190957,7 +190957,7 @@ gkr gJT eof lcq -aeq +jDf gIv leM nVH @@ -195088,7 +195088,7 @@ gfs tGW gwl tEk -jBX +edG bPN kmm gsi @@ -200523,7 +200523,7 @@ eAq wwa kVz gTR -mLK +gMw suG nuR qWH @@ -204134,7 +204134,7 @@ qld unf kBp fHP -rUg +oIK gCL mpm odE @@ -204629,7 +204629,7 @@ eFd dFs eFd eFd -bDU +lpI ocC epY bmk @@ -243475,9 +243475,9 @@ txW pCa txW txW -bUo +pMb ccy -bUo +pMb txW txW pCa @@ -243732,9 +243732,9 @@ eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW eBg ccy @@ -243989,9 +243989,9 @@ eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb pCa eBg ccy @@ -244246,9 +244246,9 @@ eBg ccy eBg pCa -bUo +pMb ccy -bUo +pMb pCa eBg ccy @@ -244503,9 +244503,9 @@ eBg ccy eBg txW -bUo +pMb ccy -bUo +pMb txW eBg ccy @@ -245784,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 @@ -246041,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 @@ -246298,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 @@ -246555,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 @@ -246812,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 @@ -247034,7 +247034,7 @@ kHc kHc gMt sRw -tlp +pCC wKS dDs iHr @@ -254718,7 +254718,7 @@ anu hCZ uEd pMJ -qOe +xbu xBf hCZ hCZ @@ -257290,7 +257290,7 @@ knv rjP ueF tyt -isM +msl hCZ bHr wGz @@ -257804,7 +257804,7 @@ ltw lEq lzJ osd -adt +sgJ hCZ scC dmO @@ -260430,7 +260430,7 @@ kTT etc qtr hrd -nKF +iFJ cAe cAe cAe @@ -261132,7 +261132,7 @@ lFg lkH nnA kqR -mcB +wVM qNb lzo sZB @@ -261368,7 +261368,7 @@ xrX vSf geL mPk -jwC +nqF mjo qzk qzk @@ -264739,7 +264739,7 @@ snn ddY ead hEC -jql +jLm bNT kFF xGM @@ -271979,7 +271979,7 @@ iBs pSA oSh fsP -jkv +bhq czf jsj hxD diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 5701e877f72ae..61a2572b0c3a2 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/asteriod) "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/asteriod) "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/asteriod) "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/asteriod) "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/asteriod) -"ael" = ( -/obj/effect/turf_decal/sand/plating, -/obj/structure/cable/layer1, -/obj/structure/cable, -/turf/open/floor/plating/airless, -/area/station/solars/port/asteriod) -"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/asteriod) "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/maintenance/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/maintenance/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/maintenance/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,18 +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/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) "bKs" = ( /obj/structure/table, /obj/item/fuel_pellet, @@ -8795,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, @@ -9557,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/maintenance/solars/starboard/fore) "ckr" = ( /obj/structure/table, /obj/item/assembly/timer{ @@ -10289,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, @@ -10556,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/maintenance/solars/starboard/fore) "cCr" = ( /obj/structure/cable, /obj/machinery/light/warm/directional/east, @@ -10577,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, @@ -10950,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/maintenance/solars/starboard/fore) "cII" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -11076,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{ @@ -12231,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/maintenance/solars/starboard/fore) "deU" = ( /obj/structure/closet/emcloset, /obj/machinery/light/dim/directional/west, @@ -12370,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"; @@ -12434,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 @@ -13983,11 +13953,12 @@ /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/maintenance/solars/port) "dMw" = ( @@ -14375,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 @@ -14948,11 +14929,17 @@ }, /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, +"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{ @@ -15147,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, @@ -15508,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/maintenance/solars/port) "eqK" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -16125,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/maintenance/solars/starboard/fore) "eBd" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 9 @@ -16607,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 @@ -16793,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 @@ -16863,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 @@ -16911,9 +16918,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/tram/right) -"eSh" = ( -/turf/closed/wall, -/area/station/solars/starboard/fore/asteriod) "eSj" = ( /obj/structure/table, /obj/item/storage/box/firingpins, @@ -17500,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/maintenance/solars/port) "feP" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 5 @@ -18484,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/maintenance/solars/starboard/fore) "fvM" = ( /obj/structure/stairs/north, /turf/open/floor/iron/stairs/medium, @@ -19368,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, @@ -19612,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/maintenance/solars/port) "fSM" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 10 @@ -19925,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, @@ -20058,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/maintenance/solars/port) "gbl" = ( /obj/structure/chair/office{ dir = 1 @@ -20160,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, @@ -21059,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/maintenance/solars/starboard/fore) "gtZ" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/machinery/airalarm/directional/south, @@ -21119,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, @@ -21361,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/maintenance/solars/port) "gAH" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 1 @@ -21758,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/asteriod) "gGV" = ( /obj/structure/table, /obj/item/instrument/harmonica, @@ -22188,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 @@ -22495,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 @@ -23357,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/asteriod) "hmb" = ( /obj/effect/turf_decal/tile/bar{ dir = 8 @@ -24055,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/asteriod) "hDF" = ( /obj/machinery/computer/apc_control{ dir = 1 @@ -26216,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 @@ -26763,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, @@ -27788,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/maintenance/solars/starboard/fore) "iXx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible/layer2, /obj/structure/lattice, @@ -28124,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/asteriod) "jde" = ( /obj/machinery/door/airlock/engineering{ name = "Vacant Office A" @@ -28323,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/maintenance/solars/starboard/fore) "jgn" = ( /obj/structure/table/reinforced, /obj/structure/displaycase/forsale/kitchen{ @@ -28352,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{ @@ -30054,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{ @@ -30211,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, @@ -30589,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) @@ -31464,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/maintenance/solars/port) "kgG" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -31893,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/maintenance/solars/starboard/fore) "koq" = ( /obj/machinery/air_sensor/oxygen_tank, /turf/open/floor/engine/o2, @@ -32958,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 @@ -34024,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"; @@ -34217,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{ @@ -34490,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/maintenance/solars/starboard/fore) "lhV" = ( /obj/structure/displaycase/trophy, /obj/machinery/light/warm/directional/west, @@ -35152,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/maintenance/solars/port) "lsx" = ( /obj/structure/chair/stool/directional/north, /obj/effect/turf_decal/trimline/dark_blue/corner{ @@ -35576,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/maintenance/solars/starboard/fore) "lzo" = ( /obj/machinery/door/window/left/directional/south, /turf/open/floor/grass, @@ -36313,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/maintenance/solars/port) "lMJ" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/turf_decal/siding/thinplating/dark{ @@ -36349,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/asteriod) "lMZ" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 8 @@ -36731,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{ @@ -37263,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 @@ -37908,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/maintenance/solars/port) "mns" = ( /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 1 @@ -38020,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, @@ -38186,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, @@ -38280,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/maintenance/solars/port) "muZ" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -38739,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 @@ -38894,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/effect/spawner/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" @@ -39083,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/maintenance/solars/starboard/fore) "mJG" = ( /obj/structure/chair/stool/bar/directional/north, /obj/effect/turf_decal/siding/thinplating{ @@ -39104,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/maintenance/solars/port) "mKh" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -39181,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 @@ -39521,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 @@ -39575,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/maintenance/solars/starboard/fore) "mWC" = ( /obj/machinery/holopad, /obj/machinery/firealarm/directional/north, @@ -39915,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/asteriod) "ncF" = ( /turf/closed/wall, /area/station/maintenance/tram/left) @@ -39946,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, @@ -40036,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/maintenance/solars/starboard/fore) "neC" = ( /obj/structure/railing{ dir = 1 @@ -40464,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/asteriod) "nle" = ( /obj/machinery/door/airlock/security{ name = "Evidence Storage" @@ -40575,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, @@ -41327,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/asteriod) "nzO" = ( /mob/living/carbon/human/species/monkey, /turf/open/misc/dirt/jungle{ @@ -41352,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 @@ -42034,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/maintenance/solars/port) "nNz" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -42070,9 +42038,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) -"nOd" = ( -/turf/open/openspace, -/area/station/maintenance/solars/starboard/fore) "nOe" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 6 @@ -43119,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, @@ -43246,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/maintenance/solars/port) "ojQ" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/effect/turf_decal/trimline/blue/filled/corner{ @@ -44013,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/maintenance/solars/starboard/fore) "oAn" = ( /obj/machinery/airlock_sensor/incinerator_ordmix{ pixel_x = 23; @@ -45269,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, @@ -45335,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/asteriod) "pdf" = ( /obj/machinery/camera/directional/north{ network = list("ss13","engineering","Security"); @@ -45653,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 @@ -45764,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/maintenance/solars/starboard/fore) "pln" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 8 @@ -46039,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/maintenance/solars/port) "ppU" = ( /obj/structure/railing, /obj/effect/turf_decal/trimline/tram/filled/line{ @@ -46957,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"; @@ -46971,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, @@ -47354,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/maintenance/solars/starboard/fore) "pKZ" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -48145,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/maintenance/solars/port) "pZH" = ( /obj/structure/lattice/catwalk, /turf/open/space/basic, @@ -49042,9 +48981,10 @@ /obj/machinery/microwave, /turf/open/floor/iron/white, /area/station/commons/vacant_room) -"qoG" = ( -/turf/closed/wall, -/area/station/solars/port/asteriod) +"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 @@ -50667,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 @@ -51030,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/maintenance/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, @@ -52192,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) @@ -52287,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 @@ -52339,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, @@ -52399,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, @@ -53600,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{ @@ -54006,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, @@ -54148,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/maintenance/solars/port) "sgB" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/structure/cable, @@ -54670,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, @@ -54817,9 +54812,6 @@ }, /turf/closed/wall/r_wall, /area/station/engineering/supermatter/room) -"srF" = ( -/turf/open/openspace, -/area/station/maintenance/solars/port) "srN" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/structure/cable, @@ -55233,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{ @@ -55567,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/maintenance/solars/starboard/fore) "sFc" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -55638,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/maintenance/solars/starboard/fore) "sGO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -58184,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 @@ -58242,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{ @@ -59959,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, @@ -61833,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/maintenance/solars/port) "uIk" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible, /obj/effect/turf_decal/trimline/purple/filled/line{ @@ -62280,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/effect/spawner/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/fore) "uPv" = ( /obj/machinery/washing_machine, /turf/open/floor/iron/cafeteria, @@ -63584,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/maintenance/solars/port) "vob" = ( /obj/structure/bookcase/random/religion, /turf/open/floor/iron/dark, @@ -63876,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, @@ -64113,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 @@ -64144,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/maintenance/solars/port) "vwT" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -64304,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/maintenance/solars/starboard/fore) -"vAx" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/solars/port) "vAF" = ( /obj/structure/chair, /obj/effect/turf_decal/trimline/neutral/filled/line, @@ -65357,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/maintenance/solars/starboard/fore) "vTj" = ( /obj/effect/turf_decal/trimline/neutral/warning, /obj/machinery/door/window/brigdoor/left/directional/north{ @@ -65652,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, @@ -65668,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/maintenance/solars/starboard/fore) "vZZ" = ( /obj/machinery/duct, /obj/structure/cable, @@ -65877,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, @@ -66434,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, @@ -69753,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/maintenance/solars/port) "xCm" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/blue/anticorner/contrasted, @@ -69794,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/maintenance/solars/starboard/fore) "xDJ" = ( /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/freezer, @@ -70036,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, @@ -70393,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) @@ -70553,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/maintenance/solars/port) "xTM" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/nitrogen_output{ dir = 1 @@ -70626,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, @@ -70967,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, @@ -70983,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/effect/spawner/surgery_tray/full, -/turf/open/floor/iron/white, -/area/station/medical/surgery/aft) "yct" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 4 @@ -71311,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{ @@ -71362,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 @@ -71534,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, @@ -71576,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 @@ -87688,13 +87694,13 @@ abM aaa aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg xRm xRm xRm @@ -87948,7 +87954,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -88203,11 +88209,11 @@ aaa aac aac aac -aek -ncE -jcT -jcT -aek +ndg +vZd +ryc +ryc +ndg aac aac vXM @@ -88462,7 +88468,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -88716,13 +88722,13 @@ aaa aaa aac aac -aek -jcT -jcT -jcT -jcT -jcT -aek +ndg +ryc +ryc +ryc +ryc +ryc +ndg aac aac vXM @@ -88976,7 +88982,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -89233,7 +89239,7 @@ aac aac aac aac -ncE +vZd aac aac aac @@ -89488,13 +89494,13 @@ aaa aaa aac aac -aek -ncE -ncE -ncE -jcT -jcT -aek +ndg +vZd +vZd +vZd +ryc +ryc +ndg xRm xRm xRm @@ -89748,7 +89754,7 @@ aac aac aac aac -ncE +vZd aac aac aac @@ -90003,11 +90009,11 @@ aaa aaa aac aac -aek -ncE -ncE -ncE -aek +ndg +vZd +vZd +vZd +ndg aac aac vXM @@ -90262,7 +90268,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -90516,13 +90522,13 @@ aaa aaa aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg aac vXM vXM @@ -90776,7 +90782,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -91033,8 +91039,8 @@ aac aac aac aac -gGy -qoG +eQc +pjw aac aac aac @@ -91288,13 +91294,13 @@ aaa aac aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg aac vXM vXM @@ -91548,7 +91554,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -91803,11 +91809,11 @@ aac aac aac aac -aek -jcT -jcT -jcT -aek +ndg +ryc +ryc +ryc +ndg aac aac vXM @@ -92062,7 +92068,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -92316,13 +92322,13 @@ aaa aac aac aac -aek -jcT -jcT -jcT -jcT -ncE -aek +ndg +ryc +ryc +ryc +ryc +vZd +ndg xRm xRm xRm @@ -92576,7 +92582,7 @@ aac aac aac aac -jcT +ryc aac aac aac @@ -92831,11 +92837,11 @@ aaa aac aac aac -ncE -ncE -ncE -jcT -jcT +vZd +vZd +vZd +ryc +ryc aac aac aac @@ -93087,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 @@ -93342,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 @@ -93599,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 @@ -93856,19 +93862,19 @@ aaa aaa aaa aac -ael -mKe -ppQ -gAC -eqJ -muV -lst -dMv -aST -ncE -ncE -ncE -jcT +uhd +guG +vrP +jUY +pbI +ybZ +kXV +jLR +xKt +vZd +vZd +vZd +ryc oQf oQf oQf @@ -94113,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 @@ -94370,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 @@ -94627,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 @@ -94884,14 +94890,14 @@ aac aac aac aac -lMS +iED aac aac -ncE -ncE -ncE -ncE -ncE +vZd +vZd +vZd +vZd +vZd aac aac aac @@ -95139,9 +95145,9 @@ aac aac aac aac -lMS -lMS -lMS +iED +iED +iED aac aac aac @@ -107129,7 +107135,7 @@ aac aac aac aac -eSh +gVY aac aac aac @@ -107383,13 +107389,13 @@ xRm xRm xRm aac -aam -hlS -hlS -pcZ -hlS -hlS -aam +vwk +ylq +ylq +dha +ylq +ylq +vwk aac aac aaa @@ -107643,7 +107649,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -107898,11 +107904,11 @@ vXM vXM aac aac -aam -hlS -hlS -hlS -aam +vwk +ylq +ylq +ylq +vwk aac aac aac @@ -108157,7 +108163,7 @@ aac aac aac aac -nkU +mbM aat aac aac @@ -108411,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 @@ -108672,7 +108678,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -108927,11 +108933,11 @@ vXM vXM aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -109186,7 +109192,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -109440,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 @@ -109701,7 +109707,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -109956,11 +109962,11 @@ vXM vXM aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -110215,7 +110221,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -110469,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 @@ -110729,8 +110735,8 @@ aac aac aac aac -eSh -nkU +gVY +mbM aac aac aac @@ -110987,7 +110993,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -111244,7 +111250,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -111499,11 +111505,11 @@ aac aac aac aac -nkU -nkU -nkU -nkU -nkU +mbM +mbM +mbM +mbM +mbM aac aac aac @@ -111754,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 @@ -112011,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 @@ -112268,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 @@ -112523,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 @@ -112782,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 @@ -113039,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 @@ -113296,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 @@ -113311,7 +113317,7 @@ aac aac aac aac -aaC +xPX aac aac aac @@ -113319,8 +113325,8 @@ aac aac aaa aaa -aaC -aaC +xPX +xPX aac aac aac @@ -113555,11 +113561,11 @@ vXM aac aac aac -nkU -nkU -nkU -nkU -nkU +mbM +mbM +mbM +mbM +mbM aac aac aac @@ -113568,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 @@ -113814,7 +113820,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -114071,7 +114077,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -114328,8 +114334,8 @@ aac aac aac aac -hlS -eSh +ylq +gVY aac aac aac @@ -114582,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 @@ -114843,7 +114849,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -115098,11 +115104,11 @@ vXM aac aac aac -aam -nkU -nkU -nkU -aam +vwk +mbM +mbM +mbM +vwk aac aac aac @@ -115357,7 +115363,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -115611,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 @@ -115872,7 +115878,7 @@ aac aac aac aaw -nkU +mbM aac aac aac @@ -116127,11 +116133,11 @@ aac aac aac aac -aam -nkU -hlS -hlS -aam +vwk +mbM +ylq +ylq +vwk aac aac aac @@ -116386,7 +116392,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -116640,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 @@ -116901,7 +116907,7 @@ aac aac aac aac -nkU +mbM aac aac aac @@ -117156,11 +117162,11 @@ aac aac aac aac -aam -hlS -hlS -nkU -aam +vwk +ylq +ylq +mbM +vwk aac aac aac @@ -117415,7 +117421,7 @@ aac aac aac aac -hlS +ylq aac aac aac @@ -117669,13 +117675,13 @@ xRm aac aac aac -aam -nkU -nkU -aau -nkU -nkU -aam +vwk +mbM +mbM +eRe +mbM +mbM +vwk aac aac aac @@ -117929,7 +117935,7 @@ aac aac aac aac -eSh +gVY aac aac aac @@ -155963,7 +155969,7 @@ dEv dEv dEv dEv -bKl +tAN oBY htq avg @@ -158625,9 +158631,9 @@ aac aac tMW tMW -aST -aST -aST +xKt +xKt +xKt mAG mAG mAG @@ -158881,12 +158887,12 @@ aac aac aac tMW -aST -aST -uHW -aST -aST -aST +xKt +xKt +dSs +xKt +xKt +xKt mAG mAG mAG @@ -159138,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 @@ -159395,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 @@ -159652,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 @@ -159909,12 +159915,12 @@ aac aac aac aac -aST -aST -ojP -aST -aST -aST +xKt +xKt +eiZ +xKt +xKt +xKt tMW tMW tMW @@ -160167,9 +160173,9 @@ aac aac aac aac -aST -aST -aST +xKt +xKt +xKt tMW tMW tMW @@ -166312,9 +166318,9 @@ hjz xRx aLw pVk -uPo +xUY xRx -ycs +cyj hou aNr apC @@ -171155,7 +171161,7 @@ eDV pnD iZn dME -evW +pEf sRA hrF wLd @@ -173502,7 +173508,7 @@ hiZ wTP sFA uKP -mHm +wdx qfS gNN whz @@ -177293,9 +177299,9 @@ saH uRv iCA iCA -plk -plk -plk +lTs +lTs +lTs fZL fZL pMW @@ -177549,11 +177555,11 @@ pMW iCA iCA iCA -plk -plk -vAj -plk -plk +lTs +lTs +eMH +lTs +lTs fZL pMW pMW @@ -177804,13 +177810,13 @@ uRv uRv uRv iCA -sEZ -sEZ -sEZ -nOd -cIH -nOd -plk +qZj +qZj +qZj +dMg +mUm +dMg +lTs uAZ hNg pMW @@ -178061,13 +178067,13 @@ viR viR viR bwT -lzc -sGN -cko -iXe -gtU -nOd -plk +rvB +wpq +rtF +nAl +mpp +dMg +lTs ceQ rNO pMW @@ -178318,13 +178324,13 @@ uRv uRv uRv iCA -sEZ -sEZ -sEZ -nOd -vZX -nOd -plk +qZj +qZj +qZj +dMg +mEo +dMg +lTs jPo mdl pMW @@ -178577,11 +178583,11 @@ pMW iCA iCA iCA -plk -plk -neB -plk -plk +lTs +lTs +rUX +lTs +lTs fZL pMW pMW @@ -178835,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 01d06908ce85d..6a10ba0e99ab0 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -146,21 +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/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) "acA" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -557,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, @@ -2166,11 +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/effect/spawner/surgery_tray/full/morgue/deployed, -/turf/open/floor/iron/dark/textured, -/area/station/medical/morgue) "aJP" = ( /obj/machinery/door/airlock/external/glass{ name = "Mining Dock Airlock" @@ -4660,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/c357/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) @@ -5691,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, @@ -6249,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, @@ -8070,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, @@ -20254,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, @@ -21690,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/c357/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 @@ -34386,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/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) "mhO" = ( /obj/structure/table/reinforced, /obj/item/storage/box/beakers{ @@ -34665,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, @@ -34885,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/c357/spent, -/turf/open/floor/iron/white/small, -/area/station/science/lobby) "moU" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -36263,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) @@ -38134,14 +38148,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/glass/reinforced, /area/station/security/prison) -"nvT" = ( -/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) "nwc" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/camera/autoname/directional/south, @@ -46862,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, @@ -56386,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" @@ -56640,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, @@ -58322,13 +58352,6 @@ "uxt" = ( /turf/open/openspace, /area/station/hallway/secondary/exit/departure_lounge) -"uxw" = ( -/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) "uxy" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/effect/decal/cleanable/dirt, @@ -63771,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, @@ -63873,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, @@ -65380,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/old, -/turf/open/misc/asteroid, -/area/station/asteroid) "xad" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/science/robotics, @@ -68224,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, -/turf/open/floor/plating, -/area/station/maintenance/department/medical/central) "ybh" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -80361,9 +80362,9 @@ rnk rnk xBS xBS -uxw +mNQ dBM -nvT +caq xBS tUo tUo @@ -80615,7 +80616,7 @@ dnO qvA qvA qvA -mhI +clA xBS nvp tZO @@ -92681,7 +92682,7 @@ uWr hRB hmg ghQ -wyj +ait xYz gqX qzu @@ -150757,7 +150758,7 @@ pCT ydC pWg jLV -hGy +mlh jpx aLE vOu @@ -150983,7 +150984,7 @@ fye uaT ccI cPP -aco +tTz hED vxX fYe @@ -151042,7 +151043,7 @@ xYG sQD kod iMq -aJM +wxi hru vIt vWH @@ -157731,7 +157732,7 @@ bzj eMq dwI uqI -yaX +hgA rnk cvn rnk @@ -168459,8 +168460,8 @@ hhX fYe fYe jam -bFP -moT +cVt +qFa wny gOc gOc @@ -168717,7 +168718,7 @@ fYe uif jam iBs -moT +qFa wny gOc gOc @@ -169288,7 +169289,7 @@ lQL pVB pHr mpc -wZU +tOw vxX vxX vxX diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index 410cad31a81c7..659a066347b53 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/virtual_domains/stairs_and_cliffs.dmm b/_maps/virtual_domains/stairs_and_cliffs.dmm index 4c1d364d7778d..e95f96ffe5166 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/chat.dm b/code/__DEFINES/chat.dm index 80fb1a07eccf3..21901a9344564 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" 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 2e42957aa3a08..586a67e23954c 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/fish.dm b/code/__DEFINES/fish.dm index abaa2224029ba..41a9268e0aa13 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 @@ -272,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/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index 5fce59b17fb72..62b7e19c0b60b 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -207,6 +207,7 @@ DEFINE_BITFIELD(smoothing_junction, list( #define SMOOTH_GROUP_SPIDER_WEB_WALL_MIRROR S_OBJ(74) // /obj/structure/spider/stickyweb/sealed/reflector #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/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 60be4d01182a7..6308ad94c8979 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -303,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/maths.dm b/code/__DEFINES/maths.dm index 35c8d3edaf632..a96a950559aef 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 42f45c2a2aa6d..7407bdf65565b 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -871,6 +871,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/reagents.dm b/code/__DEFINES/reagents.dm index bf3fd32918943..4eefbf2e53a36 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. diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 51ab61c84dce7..580baa5dd31b4 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -12,7 +12,7 @@ #define CHANNEL_ELEVATOR 1014 #define CHANNEL_ESCAPEMENU 1013 // BANDASTATION ADDITION START -#define CHANNEL_TTS_RADIO 1013 +#define CHANNEL_TTS_RADIO 1012 // BANDASTATION EDIT END //THIS SHOULD ALWAYS BE THE LOWEST ONE! //KEEP IT UPDATED @@ -20,6 +20,43 @@ #define MAX_INSTRUMENT_CHANNELS (128 * 6) +/// 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/tgs.dm b/code/__DEFINES/tgs.dm index 42f2d5fc31fee..7e1ba820dd8b7 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 46fef90160aaf..7ebf1ad659046 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 32718ae4784da..c1957c3581a79 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -806,6 +806,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. @@ -838,6 +840,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 @@ -917,6 +921,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" @@ -1028,6 +1034,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" diff --git a/code/__DEFINES/turbine_defines.dm b/code/__DEFINES/turbine_defines.dm index 4dc2bde1b8fe6..2a985ddb7b633 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/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 1bacd0ce2c774..8843a59af302e 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/machinery/turretid, /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/maths.dm b/code/__HELPERS/maths.dm index 27d3c5d38ab60..fbd76a1d0befd 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/paths/path.dm b/code/__HELPERS/paths/path.dm index da1c9917b6be2..5e29757e9f861 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/_experiments.dm b/code/_experiments.dm index 8cc5edb429c3c..c7fdad2f78875 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/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index cb180abf20864..429322447584d 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -79,6 +79,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "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, @@ -491,6 +492,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, @@ -666,6 +668,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, ), @@ -674,6 +677,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 78d0ecbe4a702..c781112ba567e 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -379,6 +379,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/alert.dm b/code/_onclick/hud/alert.dm index 6b6c6bc9050ab..373e9534ec526 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -319,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 diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 69ba4996fd5e9..721920111e253 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -327,7 +327,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie init_stage_completed = 0 var/mc_started = FALSE - to_chat(world, span_boldannounce("Initializing subsystems...")) + to_chat(world, span_boldannounce("Initializing subsystems..."), MESSAGE_TYPE_DEBUG) var/list/stage_sorted_subsystems = new(INITSTAGE_MAX) for (var/i in 1 to INITSTAGE_MAX) @@ -367,7 +367,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) @@ -461,7 +461,7 @@ ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "Vie var/chat_message = chat_warning ? span_boldwarning(message) : span_boldannounce(message) if(result != SS_INIT_NO_MESSAGE) - to_chat(world, chat_message) + to_chat(world, chat_message, MESSAGE_TYPE_DEBUG) log_world(message) /datum/controller/master/proc/SetRunLevel(new_runlevel) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 4ee68a714230b..31a30e6984f7a 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -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 @@ -907,7 +907,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) @@ -925,7 +925,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/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm index d38d7fa372e25..8d9bc48390838 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 0000000000000..62fe8dfdfa090 --- /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/datums/actions/cooldown_action.dm b/code/datums/actions/cooldown_action.dm index 974009727870f..c45fbda9fed57 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 c5271033bc6b7..b907ba6195798 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/components/aquarium.dm b/code/datums/components/aquarium.dm index 69939cb67b92e..36c3c2a1f53f7 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -129,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 @@ -156,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) diff --git a/code/datums/components/electrified_buckle.dm b/code/datums/components/electrified_buckle.dm index d641cf320e190..f0a5ab8579121 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 92404e3903e8e..f6ee85c23729d 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -187,6 +187,7 @@ 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() diff --git a/code/datums/components/ground_sinking.dm b/code/datums/components/ground_sinking.dm index d29e84908a438..4e846b4cf704e 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/leanable.dm b/code/datums/components/leanable.dm index b823cf5ec503c..bc0994dcdcd9d 100644 --- a/code/datums/components/leanable.dm +++ b/code/datums/components/leanable.dm @@ -4,6 +4,8 @@ var/leaning_offset = 11 /// 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(mob/living/leaner, leaning_offset = 11) . = ..() @@ -13,15 +15,32 @@ /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 @@ -42,6 +61,8 @@ var/turf/checked_turf = get_step(leaner, REVERSE_DIR(leaner.dir)) 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)) @@ -118,3 +139,11 @@ 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 26484674e8080..98858f61c3cb0 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -123,22 +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)]" - holder.pixel_y = mob_parent.get_cached_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 - holder.pixel_y = mob_parent.get_cached_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/pet_commands/pet_command.dm b/code/datums/components/pet_commands/pet_command.dm index fab3de70b79f1..84b288a5cd80a 100644 --- a/code/datums/components/pet_commands/pet_command.dm +++ b/code/datums/components/pet_commands/pet_command.dm @@ -75,7 +75,7 @@ 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)) @@ -85,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(commander = caller, radial_command = FALSE)) + 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 /** @@ -174,13 +174,12 @@ SIGNAL_HANDLER if(!can_see(source, target, 9)) return COMSIG_MOB_CANCEL_CLICKON - on_target_set(source, target) + 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() - var/manual_emote_text = generate_emote_command(target) - if(!isnull(manual_emote_text)) - INVOKE_ASYNC(source, TYPE_PROC_REF(/atom, manual_emote), manual_emote_text) return COMSIG_MOB_CANCEL_CLICKON /datum/pet_command/proc/point_on_target(mob/living/friend, atom/potential_target) @@ -214,11 +213,12 @@ /datum/pet_command/proc/on_target_set(mob/living/friend, atom/potential_target) var/mob/living/parent = weak_parent.resolve() if (!parent) - return + return FALSE parent.ai_controller.CancelActions() if(!look_for_target(friend, potential_target) || !set_command_target(parent, potential_target)) - return + 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 06d11d353e8d5..cd535b33ecaba 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -147,16 +147,16 @@ // Refuse to target things we can't target, chiefly other friends /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) @@ -186,16 +186,16 @@ /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/breed/execute_action(datum/ai_controller/controller) @@ -274,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 diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm index ed916c29edf94..5bf95b747e3cf 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -337,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 4f2acf4710a7e..f095f07262b51 100644 --- a/code/datums/components/plumbing/reaction_chamber.dm +++ b/code/datums/components/plumbing/reaction_chamber.dm @@ -8,13 +8,29 @@ 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 //cannot give when we outselves are requesting or reacting the reagents - if(!reaction_chamber.emptying || reagents.is_reacting) - return FALSE + 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 - return ..() + //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 diff --git a/code/datums/components/plumbing/simple_components.dm b/code/datums/components/plumbing/simple_components.dm index d1f8a4c3ca637..1378780353a40 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 a788ef6e8611f..23b860ac566e7 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]" @@ -56,7 +56,7 @@ seethrough.unhide_plane(fool) render_source_atom.pixel_x = -fool.pixel_x - render_source_atom.pixel_y = (fool.get_cached_height() - ICON_SIZE_Y * 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/tackle.dm b/code/datums/components/tackle.dm index ed7f3f340c1a3..5f5ac41a57e2d 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? @@ -594,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) @@ -628,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 @@ -637,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 @@ -664,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/throwbonus_on_windup.dm b/code/datums/components/throwbonus_on_windup.dm index a96d9294e8010..56e3de5cd815f 100644 --- a/code/datums/components/throwbonus_on_windup.dm +++ b/code/datums/components/throwbonus_on_windup.dm @@ -52,7 +52,7 @@ return if(throw_text) to_chat(our_holder, span_warning(throw_text)) - var/x_position = CEILING(our_holder.get_cached_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/drift_handler.dm b/code/datums/drift_handler.dm index dcf0771d8a5e8..559ea9e13ca82 100644 --- a/code/datums/drift_handler.dm +++ b/code/datums/drift_handler.dm @@ -241,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 @@ -264,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/can_shatter.dm b/code/datums/elements/can_shatter.dm index df19e4ef12344..5d8824121931e 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/fish_safe_storage.dm b/code/datums/elements/fish_safe_storage.dm index ec5c59848646d..ec543313bc25a 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/squish.dm b/code/datums/elements/squish.dm index 2e8e273eb35f8..872f837d96e1e 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/embed_data.dm b/code/datums/embed_data.dm index a82d305c8e6eb..865b285d09bab 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 ceaa53e045523..1e8870ddf3e49 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/map_config.dm b/code/datums/map_config.dm index 2a128e79f10d3..6d39ce88bd17c 100644 --- a/code/datums/map_config.dm +++ b/code/datums/map_config.dm @@ -242,7 +242,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 be93e9668e547..ec27a7d4b8fa3 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -126,7 +126,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) @@ -203,7 +203,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) @@ -296,7 +296,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) @@ -319,7 +319,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 @@ -330,7 +330,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/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index cdd28c1855ee8..ca523984d59cf 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/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 34eae9515ff7c..006a2a527dfb3 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -347,19 +347,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) - 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 @@ -369,6 +383,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 diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 856c1204c720f..b8bfcf80382de 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/game/atom/_atom.dm b/code/game/atom/_atom.dm index d73579c8f366e..79102a70804e1 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -723,7 +723,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) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 0c44e35a74643..e32d09309c193 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -166,70 +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)]" - holder.pixel_y = get_cached_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 - - holder.pixel_y = get_cached_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/virus_threat = check_virus() - holder.pixel_y = get_cached_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. @@ -238,28 +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] - holder.pixel_y = get_cached_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. @@ -268,43 +257,31 @@ 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] - holder.pixel_y = get_cached_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() /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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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() @@ -312,38 +289,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] - holder.pixel_y = get_cached_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) @@ -388,156 +360,131 @@ Diagnostic HUDs! //Sillycone hooks /mob/living/silicon/proc/diag_hud_set_health() - var/image/holder = hud_list[DIAG_HUD] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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] - holder.pixel_y = get_cached_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! @@ -575,3 +522,46 @@ Diagnostic HUDs! #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/airlock_control.dm b/code/game/machinery/airlock_control.dm index 9e089eeaf2be8..3b01c40403d8c 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 cfe2ba137cbb1..7cb87326eb86b 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/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index d51e197a0bcdd..6aa3368341215 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -30,6 +30,11 @@ . = ..() 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(.) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 7e9ef45e8f5cf..6ad2833a3784e 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -203,6 +203,9 @@ var/new_sec_level = SSsecurity_level.text_level_to_number(params["newSecurityLevel"]) if (new_sec_level != SEC_LEVEL_GREEN && new_sec_level != SEC_LEVEL_BLUE) 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 diff --git a/code/game/machinery/dna_infuser/infuser_actions.dm b/code/game/machinery/dna_infuser/infuser_actions.dm index 466bed9e17efe..9613854627f0f 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/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c3657c6cac391..b562713fe3713 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1226,8 +1226,9 @@ prying_so_hard = FALSE return + prying_so_hard = FALSE + if(check_electrified && shock(user, 100)) - prying_so_hard = FALSE return open(BYPASS_DOOR_CHECKS) @@ -1354,7 +1355,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 +1363,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 diff --git a/code/game/machinery/flatpacker.dm b/code/game/machinery/flatpacker.dm index c26d9ad036d53..d675173253386 100644 --- a/code/game/machinery/flatpacker.dm +++ b/code/game/machinery/flatpacker.dm @@ -326,160 +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 - -/obj/item/flatpack/flatpacker // a roundstart flatpacker is NICE you can gahdamn tell the time and everythin' - board = /obj/item/circuitboard/machine/flatpacker - -/obj/item/flatpack/mailsorter // to have a roundstart mail sorter at cargo - board = /obj/item/circuitboard/machine/mailsorter diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 76653c43ddf96..61547259d4d7b 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 diff --git a/code/game/machinery/modular_shield.dm b/code/game/machinery/modular_shield.dm index b4fa6bed17bb0..2e8fa632e42bf 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/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 796ee58984565..fd106ce10cdd7 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -730,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 diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 0df5c1baee624..491ab61d3f427 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -443,7 +443,7 @@ var/size_matrix = matrix() if(size_calc_target) layer = size_calc_target.layer + 0.01 - size_matrix = matrix() * (size_calc_target.get_cached_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 01c506d6fd708..d88993ae95997 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -764,7 +764,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 diff --git a/code/game/objects/items/flatpacks.dm b/code/game/objects/items/flatpacks.dm new file mode 100644 index 0000000000000..054d51e6c154b --- /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/mail.dm b/code/game/objects/items/mail.dm index e11310b57e868..26a2e9a5416e2 100644 --- a/code/game/objects/items/mail.dm +++ b/code/game/objects/items/mail.dm @@ -342,6 +342,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 1bba4f5b651de..5389f7723b982 100644 --- a/code/game/objects/items/maintenance_loot.dm +++ b/code/game/objects/items/maintenance_loot.dm @@ -33,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/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index c32919094391a..3ccb06c3c018e 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/boxes/engineering_boxes.dm b/code/game/objects/items/storage/boxes/engineering_boxes.dm index 09f641ec31520..b30aaed9f6820 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/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index e48a19743c137..829de0594931a 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) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 5ee9723dd6b9b..c26d312f1844a 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 @@ -78,19 +78,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) @@ -98,8 +107,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) @@ -166,7 +175,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 @@ -214,7 +223,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 @@ -241,7 +252,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 @@ -261,6 +274,7 @@ can_buckle = FALSE buildstackamount = 1 item_chair = /obj/item/chair/stool + max_integrity = 300 MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0) @@ -281,6 +295,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) @@ -307,7 +322,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 @@ -326,11 +341,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) @@ -369,6 +389,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) @@ -387,19 +408,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 @@ -409,7 +454,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" @@ -423,7 +468,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 @@ -433,11 +479,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 @@ -522,7 +568,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 @@ -558,7 +604,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 7ff735750481d..36b95e9515e3f 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 edfbe8e38c0e4..30a2c4e9efd2f 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 @@ -486,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 @@ -1032,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 @@ -1053,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() @@ -1076,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) @@ -1129,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.")) @@ -1212,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/electricchair.dm b/code/game/objects/structures/electricchair.dm index 8df558169f82e..70fb5b57ae236 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 389e8dcbd743d..b337bbb9bacb4 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 @@ -394,15 +399,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 @@ -410,9 +421,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" @@ -425,6 +440,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) @@ -494,8 +512,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 b36e35245c202..a329f70750de4 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 0a52c3cd9f638..f22ef3f7e2b4c 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -162,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/shower.dm b/code/game/objects/structures/shower.dm index 26d05f6edd178..d3852bb856900 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -193,7 +193,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) diff --git a/code/game/sound.dm b/code/game/sound.dm index 8259a027dfea5..8d761a40d2f68 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] = 0 //Room setting, 0 means normal reverb sound_to_use.echo[4] = 0 //RoomHF setting, 0 means normal reverb. + 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/closed/walls.dm b/code/game/turfs/closed/walls.dm index 618c6f3eb914a..924c63be716d4 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -50,6 +50,14 @@ 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) //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 @@ -65,7 +73,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) @@ -325,3 +335,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/chasm.dm b/code/game/turfs/open/chasm.dm index 2699b4933626d..003719d3bdf61 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 e918cd72e8c7e..8c3e395b4d42c 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/misc.dm b/code/game/turfs/open/misc.dm index f00e6ed6ded6e..f99d453874893 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 9b9c739f397cd..e9f8beadf0d65 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 ddc322185d291..1142afb4e4d17 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/turf.dm b/code/game/turfs/turf.dm index b3cf3761e1d8b..bd78317799fa6 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -735,16 +735,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/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index 38d7535758fc7..1749e5a5b6ad1 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/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index 02af10227e8df..4b82067ddc569 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -49,14 +49,12 @@ /obj/item/organ/heart/gland/proc/update_gland_hud() if(!owner) return - var/image/holder = owner.hud_list[GLAND_HUD] - holder.pixel_y = owner.get_cached_height() - ICON_SIZE_Y if(active_mind_control) - holder.icon_state = "hudgland_active" + owner.set_hud_image_state(GLAND_HUD, "hudgland_active") else if(mind_control_uses) - holder.icon_state = "hudgland_ready" + owner.set_hud_image_state(GLAND_HUD, "hudgland_ready") else - holder.icon_state = "hudgland_spent" + owner.set_hud_image_state(GLAND_HUD, "hudgland_spent") /obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user) if(!ownerCheck() || !mind_control_uses || active_mind_control) diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index b13b07f7f360d..20519d2d8b734 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -139,10 +139,9 @@ /obj/item/changeling/id/equipped(mob/user, slot, initial) . = ..() - if(hud_icon) - var/image/holder = user.hud_list[ID_HUD] - holder.pixel_y = user.get_cached_height() - ICON_SIZE_Y - holder.icon_state = hud_icon + if(!hud_icon) + return + user.set_hud_image_state(ID_HUD, hud_icon) /** * Returns cached flat icon of the ID, creates one if there is not one already cached diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index d4350a9c67966..13d39753fa5e3 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -243,12 +243,12 @@ enable_text = span_cult("You prepare to horrify a target...") disable_text = span_cult("You dispel the magic...") -/datum/action/innate/cult/blood_spell/horror/InterceptClickOn(mob/living/caller, params, atom/clicked_on) - var/turf/caller_turf = get_turf(caller) +/datum/action/innate/cult/blood_spell/horror/InterceptClickOn(mob/living/clicker, params, atom/clicked_on) + var/turf/caller_turf = get_turf(clicker) if(!isturf(caller_turf)) return FALSE - if(!ishuman(clicked_on) || get_dist(caller, clicked_on) > 7) + if(!ishuman(clicked_on) || get_dist(clicker, clicked_on) > 7) return FALSE var/mob/living/carbon/human/human_clicked = clicked_on @@ -257,16 +257,16 @@ return ..() -/datum/action/innate/cult/blood_spell/horror/do_ability(mob/living/caller, mob/living/carbon/human/clicked_on) +/datum/action/innate/cult/blood_spell/horror/do_ability(mob/living/clicker, mob/living/carbon/human/clicked_on) clicked_on.set_hallucinations_if_lower(240 SECONDS) - SEND_SOUND(caller, sound('sound/effects/ghost.ogg', FALSE, TRUE, 50)) + SEND_SOUND(clicker, sound('sound/effects/ghost.ogg', FALSE, TRUE, 50)) var/image/sparkle_image = image('icons/effects/cult.dmi', clicked_on, "bloodsparkles", ABOVE_MOB_LAYER) clicked_on.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/has_antagonist/cult, "cult_apoc", sparkle_image, NONE) addtimer(CALLBACK(clicked_on, TYPE_PROC_REF(/atom/, remove_alt_appearance), "cult_apoc", TRUE), 4 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE) - to_chat(caller, span_cult_bold("[clicked_on] has been cursed with living nightmares!")) + to_chat(clicker, span_cult_bold("[clicked_on] has been cursed with living nightmares!")) charges-- desc = base_desc @@ -274,7 +274,7 @@ build_all_button_icons() SSblackbox.record_feedback("tally", "cult_spell_invoke", 1, "[name]") if(charges <= 0) - to_chat(caller, span_cult("You have exhausted the spell's power!")) + to_chat(clicker, span_cult("You have exhausted the spell's power!")) qdel(src) return TRUE diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index 7a8e2fa535fd4..b0f3e5a6d3697 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -293,18 +293,18 @@ /datum/action/innate/cult/master/cultmark/IsAvailable(feedback = FALSE) return ..() && COOLDOWN_FINISHED(src, cult_mark_cooldown) -/datum/action/innate/cult/master/cultmark/InterceptClickOn(mob/caller, params, atom/clicked_on) - var/turf/caller_turf = get_turf(caller) - if(!isturf(caller_turf)) +/datum/action/innate/cult/master/cultmark/InterceptClickOn(mob/clicker, params, atom/clicked_on) + var/turf/clicker_turf = get_turf(clicker) + if(!isturf(clicker_turf)) return FALSE - if(!(clicked_on in view(7, caller_turf))) + if(!(clicked_on in view(7, clicker_turf))) return FALSE return ..() -/datum/action/innate/cult/master/cultmark/do_ability(mob/living/caller, atom/clicked_on) - var/datum/antagonist/cult/cultist = caller.mind.has_antag_datum(/datum/antagonist/cult, TRUE) +/datum/action/innate/cult/master/cultmark/do_ability(mob/living/clicker, atom/clicked_on) + var/datum/antagonist/cult/cultist = clicker.mind.has_antag_datum(/datum/antagonist/cult, TRUE) if(!cultist) CRASH("[type] was casted by someone without a cult antag datum.") @@ -313,17 +313,17 @@ CRASH("[type] was casted by a cultist without a cult team datum.") if(cult_team.blood_target) - to_chat(caller, span_cult("The cult has already designated a target!")) + to_chat(clicker, span_cult("The cult has already designated a target!")) return FALSE - if(cult_team.set_blood_target(clicked_on, caller, cult_mark_duration)) - unset_ranged_ability(caller, span_cult("The marking rite is complete! It will last for [DisplayTimeText(cult_mark_duration)] seconds.")) + if(cult_team.set_blood_target(clicked_on, clicker, cult_mark_duration)) + unset_ranged_ability(clicker, span_cult("The marking rite is complete! It will last for [DisplayTimeText(cult_mark_duration)] seconds.")) COOLDOWN_START(src, cult_mark_cooldown, cult_mark_cooldown_duration) build_all_button_icons() addtimer(CALLBACK(src, PROC_REF(build_all_button_icons)), cult_mark_cooldown_duration + 1) return TRUE - unset_ranged_ability(caller, span_cult("The marking rite failed!")) + unset_ranged_ability(clicker, span_cult("The marking rite failed!")) return TRUE /datum/action/innate/cult/ghostmark //Ghost version @@ -423,44 +423,44 @@ /datum/action/innate/cult/master/pulse/IsAvailable(feedback = FALSE) return ..() && COOLDOWN_FINISHED(src, pulse_cooldown) -/datum/action/innate/cult/master/pulse/InterceptClickOn(mob/living/caller, params, atom/clicked_on) - var/turf/caller_turf = get_turf(caller) - if(!isturf(caller_turf)) +/datum/action/innate/cult/master/pulse/InterceptClickOn(mob/living/clicker, params, atom/clicked_on) + var/turf/clicker_turf = get_turf(clicker) + if(!isturf(clicker_turf)) return FALSE - if(!(clicked_on in view(7, caller_turf))) + if(!(clicked_on in view(7, clicker_turf))) return FALSE - if(clicked_on == caller) + if(clicked_on == clicker) return FALSE return ..() -/datum/action/innate/cult/master/pulse/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/cult/master/pulse/do_ability(mob/living/clicker, atom/clicked_on) var/atom/throwee = throwee_ref?.resolve() if(QDELETED(throwee)) - to_chat(caller, span_cult("You lost your target!")) + to_chat(clicker, span_cult("You lost your target!")) throwee = null throwee_ref = null return FALSE if(throwee) if(get_dist(throwee, clicked_on) >= 16) - to_chat(caller, span_cult("You can't teleport [clicked_on.p_them()] that far!")) + to_chat(clicker, span_cult("You can't teleport [clicked_on.p_them()] that far!")) return FALSE var/turf/throwee_turf = get_turf(throwee) playsound(throwee_turf, 'sound/effects/magic/exit_blood.ogg') - new /obj/effect/temp_visual/cult/sparks(throwee_turf, caller.dir) + new /obj/effect/temp_visual/cult/sparks(throwee_turf, clicker.dir) throwee.visible_message( span_warning("A pulse of magic whisks [throwee] away!"), span_cult("A pulse of blood magic whisks you away..."), ) if(!do_teleport(throwee, clicked_on, channel = TELEPORT_CHANNEL_CULT)) - to_chat(caller, span_cult("The teleport fails!")) + to_chat(clicker, span_cult("The teleport fails!")) throwee.visible_message( span_warning("...Except they don't go very far"), span_cult("...Except you don't appear to have moved very far."), @@ -468,15 +468,15 @@ return FALSE throwee_turf.Beam(clicked_on, icon_state = "sendbeam", time = 0.4 SECONDS) - new /obj/effect/temp_visual/cult/sparks(get_turf(clicked_on), caller.dir) + new /obj/effect/temp_visual/cult/sparks(get_turf(clicked_on), clicker.dir) throwee.visible_message( span_warning("[throwee] appears suddenly in a pulse of magic!"), span_cult("...And you appear elsewhere."), ) COOLDOWN_START(src, pulse_cooldown, pulse_cooldown_duration) - to_chat(caller, span_cult("A pulse of blood magic surges through you as you shift [throwee] through time and space.")) - caller.click_intercept = null + to_chat(clicker, span_cult("A pulse of blood magic surges through you as you shift [throwee] through time and space.")) + clicker.click_intercept = null throwee_ref = null build_all_button_icons() addtimer(CALLBACK(src, PROC_REF(build_all_button_icons)), pulse_cooldown_duration + 1) @@ -488,13 +488,13 @@ var/mob/living/living_clicked = clicked_on if(!IS_CULTIST(living_clicked)) return FALSE - SEND_SOUND(caller, sound('sound/items/weapons/thudswoosh.ogg')) - to_chat(caller, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! Click anywhere nearby to teleport [clicked_on.p_them()]!")) + SEND_SOUND(clicker, sound('sound/items/weapons/thudswoosh.ogg')) + to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! Click anywhere nearby to teleport [clicked_on.p_them()]!")) throwee_ref = WEAKREF(clicked_on) return TRUE if(istype(clicked_on, /obj/structure/destructible/cult)) - to_chat(caller, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! Click anywhere nearby to teleport it!")) + to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! Click anywhere nearby to teleport it!")) throwee_ref = WEAKREF(clicked_on) return TRUE diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 494a8d30521b9..dead537d18d96 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -85,6 +85,7 @@ /obj/effect/visible_heretic_influence/Initialize(mapload) . = ..() addtimer(CALLBACK(src, PROC_REF(show_presence)), 15 SECONDS) + AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/dimensional_rift]) var/image/silicon_image = image('icons/effects/eldritch.dmi', src, null, OBJ_LAYER) silicon_image.override = TRUE @@ -175,6 +176,7 @@ AddElement(/datum/element/block_turf_fingerprints) AddComponent(/datum/component/redirect_attack_hand_from_turf, interact_check = CALLBACK(src, PROC_REF(verify_user_can_see))) + AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/dimensional_rift]) /obj/effect/heretic_influence/proc/verify_user_can_see(mob/user) return (user.mind in GLOB.reality_smash_track.tracked_heretics) diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm index 6fec632e5102f..4238b54f91543 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm @@ -109,9 +109,10 @@ bloodiest_wound.adjust_blood_flow(-0.5 * seconds_between_ticks) /// Torment the target with a frightening hand -/proc/fire_curse_hand(mob/living/carbon/victim) +/proc/fire_curse_hand(mob/living/carbon/victim, turf/forced_turf) var/grab_dir = turn(victim.dir, pick(-90, 90, 180, 180)) // Not in front, favour behind var/turf/spawn_turf = get_ranged_target_turf(victim, grab_dir, 8) + spawn_turf = forced_turf ? forced_turf : spawn_turf if (isnull(spawn_turf)) return new /obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, victim.dir) diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index 8fd0c5a5713f3..4973be945af8f 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -25,6 +25,39 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) cost = 0 is_starting_knowledge = TRUE +// Heretics can enhance their fishing rods to fish better - fishing content. +// Lasts until succesfully fishing something up. +/datum/heretic_knowledge/spell/basic/on_gain(mob/user, datum/antagonist/heretic/our_heretic) + ..() + RegisterSignal(user, COMSIG_TOUCH_HANDLESS_CAST, PROC_REF(on_grasp_cast)) + +/datum/heretic_knowledge/spell/basic/proc/on_grasp_cast(mob/living/carbon/cast_on, datum/action/cooldown/spell/touch/touch_spell) + SIGNAL_HANDLER + + // Not a grasp, we dont want this to activate with say star or mending touch. + if(!istype(touch_spell, action_to_add)) + return NONE + + var/obj/item/fishing_rod/held_rod = cast_on.get_active_held_item() + if(!istype(held_rod, /obj/item/fishing_rod) || HAS_TRAIT(held_rod, TRAIT_ROD_MANSUS_INFUSED)) + return NONE + + INVOKE_ASYNC(cast_on, TYPE_PROC_REF(/atom/movable, say), message = "R'CH T'H F'SH!", forced = "fishing rod infusion invocation") + playsound(cast_on, /datum/action/cooldown/spell/touch/mansus_grasp::sound, 15) + cast_on.visible_message(span_notice("[cast_on] snaps [cast_on.p_their()] fingers next to [held_rod], covering it in a burst of purple flames!")) + + ADD_TRAIT(held_rod, TRAIT_ROD_MANSUS_INFUSED, REF(held_rod)) + held_rod.difficulty_modifier -= 20 + RegisterSignal(held_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, PROC_REF(unfuse)) + held_rod.add_filter("mansus_infusion", 2, list("type" = "outline", "color" = COLOR_VOID_PURPLE, "size" = 1)) + return COMPONENT_CAST_HANDLESS + +/datum/heretic_knowledge/spell/basic/proc/unfuse(obj/item/fishing_rod/item, reward, mob/user) + if(reward == FISHING_INFLUENCE || prob(35)) + item.remove_filter("mansus_infusion") + REMOVE_TRAIT(item, TRAIT_ROD_MANSUS_INFUSED, REF(item)) + item.difficulty_modifier += 20 + /** * The Living Heart heretic knowledge. * diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm index d72c7fc7c04e9..4f2bb2dd7f108 100644 --- a/code/modules/antagonists/heretic/magic/furious_steel.dm +++ b/code/modules/antagonists/heretic/magic/furious_steel.dm @@ -45,12 +45,12 @@ unset_click_ability(source, refund_cooldown = TRUE) -/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/clicker, params, atom/target) // Let the caster prioritize using items like guns over blade casts - if(caller.get_active_held_item()) + if(clicker.get_active_held_item()) return FALSE // Let the caster prioritize melee attacks like punches and shoves over blade casts - if(get_dist(caller, target) <= 1) + if(get_dist(clicker, target) <= 1) return FALSE return ..() diff --git a/code/modules/antagonists/heretic/magic/rust_construction.dm b/code/modules/antagonists/heretic/magic/rust_construction.dm index f8d6a2ff2be44..72546f66592f5 100644 --- a/code/modules/antagonists/heretic/magic/rust_construction.dm +++ b/code/modules/antagonists/heretic/magic/rust_construction.dm @@ -23,7 +23,7 @@ /** * Overrides 'aim assist' because we always want to hit just the turf we clicked on. */ -/datum/action/cooldown/spell/pointed/rust_construction/aim_assist(mob/living/caller, atom/target) +/datum/action/cooldown/spell/pointed/rust_construction/aim_assist(mob/living/clicker, atom/target) return get_turf(target) /datum/action/cooldown/spell/pointed/rust_construction/is_valid_target(atom/cast_on) diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm index 362e9750b49c1..d42626871bbff 100644 --- a/code/modules/antagonists/heretic/status_effects/buffs.dm +++ b/code/modules/antagonists/heretic/status_effects/buffs.dm @@ -284,7 +284,7 @@ /datum/status_effect/caretaker_refuge/on_apply() animate(owner, alpha = 45,time = 0.5 SECONDS) - owner.density = FALSE + owner.set_density(FALSE) RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost)) RegisterSignal(owner, COMSIG_MOB_BEFORE_SPELL_CAST, PROC_REF(prevent_spell_usage)) RegisterSignal(owner, COMSIG_ATOM_HOLYATTACK, PROC_REF(nullrod_handler)) diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index 1776371bae9fe..65d12fcb25ac4 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -445,12 +445,12 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) . = ..() desc = "[desc] It has [uses] use\s remaining." -/datum/action/innate/ai/ranged/override_machine/do_ability(mob/living/caller, atom/clicked_on) - if(caller.incapacitated) - unset_ranged_ability(caller) +/datum/action/innate/ai/ranged/override_machine/do_ability(mob/living/clicker, atom/clicked_on) + if(clicker.incapacitated) + unset_ranged_ability(clicker) return FALSE if(!ismachinery(clicked_on)) - to_chat(caller, span_warning("You can only animate machines!")) + to_chat(clicker, span_warning("You can only animate machines!")) return FALSE var/obj/machinery/clicked_machine = clicked_on @@ -459,14 +459,14 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) clicked_machine = clicked_turret.parent_turret if((clicked_machine.resistance_flags & INDESTRUCTIBLE) || is_type_in_typecache(clicked_machine, GLOB.blacklisted_malf_machines)) - to_chat(caller, span_warning("That machine can't be overridden!")) + to_chat(clicker, span_warning("That machine can't be overridden!")) return FALSE - caller.playsound_local(caller, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE) + clicker.playsound_local(clicker, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE) clicked_machine.audible_message(span_userdanger("You hear a loud electrical buzzing sound coming from [clicked_machine]!")) - addtimer(CALLBACK(src, PROC_REF(animate_machine), caller, clicked_machine), 5 SECONDS) //kabeep! - unset_ranged_ability(caller, span_danger("Sending override signal...")) + addtimer(CALLBACK(src, PROC_REF(animate_machine), clicker, clicked_machine), 5 SECONDS) //kabeep! + unset_ranged_ability(clicker, span_danger("Sending override signal...")) adjust_uses(-1) //adjust after we unset the active ability since we may run out of charges, thus deleting the ability if(uses) @@ -474,11 +474,11 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) build_all_button_icons() return TRUE -/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(mob/living/caller, obj/machinery/to_animate) +/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(mob/living/clicker, obj/machinery/to_animate) if(QDELETED(to_animate)) return - new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(to_animate), to_animate, caller, TRUE) + new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(to_animate), to_animate, clicker, TRUE) /// Destroy RCDs: Detonates all non-cyborg RCDs on the station. /datum/ai_module/malf/destructive/destroy_rcd @@ -527,23 +527,23 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) ..() desc = "[desc] It has [uses] use\s remaining." -/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(mob/living/caller, obj/machinery/to_explode) +/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(mob/living/clicker, obj/machinery/to_explode) if(QDELETED(to_explode)) return var/turf/machine_turf = get_turf(to_explode) - message_admins("[ADMIN_LOOKUPFLW(caller)] overloaded [to_explode.name] ([to_explode.type]) at [ADMIN_VERBOSEJMP(machine_turf)].") - caller.log_message("overloaded [to_explode.name] ([to_explode.type])", LOG_ATTACK) + message_admins("[ADMIN_LOOKUPFLW(clicker)] overloaded [to_explode.name] ([to_explode.type]) at [ADMIN_VERBOSEJMP(machine_turf)].") + clicker.log_message("overloaded [to_explode.name] ([to_explode.type])", LOG_ATTACK) explosion(to_explode, heavy_impact_range = 2, light_impact_range = 3) if(!QDELETED(to_explode)) //to check if the explosion killed it before we try to delete it qdel(to_explode) -/datum/action/innate/ai/ranged/overload_machine/do_ability(mob/living/caller, atom/clicked_on) - if(caller.incapacitated) - unset_ranged_ability(caller) +/datum/action/innate/ai/ranged/overload_machine/do_ability(mob/living/clicker, atom/clicked_on) + if(clicker.incapacitated) + unset_ranged_ability(clicker) return FALSE if(!ismachinery(clicked_on)) - to_chat(caller, span_warning("You can only overload machines!")) + to_chat(clicker, span_warning("You can only overload machines!")) return FALSE var/obj/machinery/clicked_machine = clicked_on @@ -552,18 +552,18 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) clicked_machine = clicked_turret.parent_turret if((clicked_machine.resistance_flags & INDESTRUCTIBLE) || is_type_in_typecache(clicked_machine, GLOB.blacklisted_malf_machines)) - to_chat(caller, span_warning("You cannot overload that device!")) + to_chat(clicker, span_warning("You cannot overload that device!")) return FALSE - caller.playsound_local(caller, SFX_SPARKS, 50, 0) + clicker.playsound_local(clicker, SFX_SPARKS, 50, 0) adjust_uses(-1) if(uses) desc = "[initial(desc)] It has [uses] use\s remaining." build_all_button_icons() clicked_machine.audible_message(span_userdanger("You hear a loud electrical buzzing sound coming from [clicked_machine]!")) - addtimer(CALLBACK(src, PROC_REF(detonate_machine), caller, clicked_machine), 5 SECONDS) //kaboom! - unset_ranged_ability(caller, span_danger("Overcharging machine...")) + addtimer(CALLBACK(src, PROC_REF(detonate_machine), clicker, clicked_machine), 5 SECONDS) //kaboom! + unset_ranged_ability(clicker, span_danger("Overcharging machine...")) return TRUE /// Blackout: Overloads a random number of lights across the station. Three uses. @@ -1079,7 +1079,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) . = ..() desc = "[desc] It has [uses] use\s remaining." -/datum/action/innate/ai/ranged/emag/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/ai/ranged/emag/do_ability(mob/living/clicker, atom/clicked_on) // Only things with of or subtyped of any of these types may be remotely emagged var/static/list/compatable_typepaths = list( @@ -1091,59 +1091,59 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) /mob/living/silicon, ) - if (!isAI(caller)) + if (!isAI(clicker)) return FALSE - var/mob/living/silicon/ai/ai_caller = caller + var/mob/living/silicon/ai/ai_clicker = clicker - if(ai_caller.incapacitated) - unset_ranged_ability(caller) + if(ai_clicker.incapacitated) + unset_ranged_ability(clicker) return FALSE - if (!ai_caller.can_see(clicked_on)) - clicked_on.balloon_alert(ai_caller, "can't see!") + if (!ai_clicker.can_see(clicked_on)) + clicked_on.balloon_alert(ai_clicker, "can't see!") return FALSE if (ismachinery(clicked_on)) var/obj/machinery/clicked_machine = clicked_on if (!clicked_machine.is_operational) - clicked_machine.balloon_alert(ai_caller, "not operational!") + clicked_machine.balloon_alert(ai_clicker, "not operational!") return FALSE if (!(is_type_in_list(clicked_on, compatable_typepaths))) - clicked_on.balloon_alert(ai_caller, "incompatable!") + clicked_on.balloon_alert(ai_clicker, "incompatable!") return FALSE if (istype(clicked_on, /obj/machinery/door/airlock)) // I HATE THIS CODE SO MUCHHH var/obj/machinery/door/airlock/clicked_airlock = clicked_on - if (!clicked_airlock.canAIControl(ai_caller)) - clicked_airlock.balloon_alert(ai_caller, "unable to interface!") + if (!clicked_airlock.canAIControl(ai_clicker)) + clicked_airlock.balloon_alert(ai_clicker, "unable to interface!") return FALSE if (istype(clicked_on, /obj/machinery/airalarm)) var/obj/machinery/airalarm/alarm = clicked_on if (alarm.aidisabled) - alarm.balloon_alert(ai_caller, "unable to interface!") + alarm.balloon_alert(ai_clicker, "unable to interface!") return FALSE if (istype(clicked_on, /obj/machinery/power/apc)) var/obj/machinery/power/apc/clicked_apc = clicked_on if (clicked_apc.aidisabled) - clicked_apc.balloon_alert(ai_caller, "unable to interface!") + clicked_apc.balloon_alert(ai_clicker, "unable to interface!") return FALSE - if (!clicked_on.emag_act(ai_caller)) - to_chat(ai_caller, span_warning("Hostile software insertion failed!")) // lets not overlap balloon alerts + if (!clicked_on.emag_act(ai_clicker)) + to_chat(ai_clicker, span_warning("Hostile software insertion failed!")) // lets not overlap balloon alerts return FALSE - to_chat(ai_caller, span_notice("Software package successfully injected.")) + to_chat(ai_clicker, span_notice("Software package successfully injected.")) adjust_uses(-1) if(uses) desc = "[initial(desc)] It has [uses] use\s remaining." build_all_button_icons() else - unset_ranged_ability(ai_caller, span_warning("Out of uses!")) + unset_ranged_ability(ai_clicker, span_warning("Out of uses!")) return TRUE @@ -1176,35 +1176,35 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) . = ..() desc = "[desc] It has [uses] use\s remaining." -/datum/action/innate/ai/ranged/core_tilt/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/ai/ranged/core_tilt/do_ability(mob/living/clicker, atom/clicked_on) if (!COOLDOWN_FINISHED(src, time_til_next_tilt)) - caller.balloon_alert(caller, "on cooldown!") + clicker.balloon_alert(clicker, "on cooldown!") return FALSE - if (!isAI(caller)) + if (!isAI(clicker)) return FALSE - var/mob/living/silicon/ai/ai_caller = caller + var/mob/living/silicon/ai/ai_clicker = clicker - if (ai_caller.incapacitated || !isturf(ai_caller.loc)) + if (ai_clicker.incapacitated || !isturf(ai_clicker.loc)) return FALSE var/turf/target = get_turf(clicked_on) if (isnull(target)) return FALSE - if (target == ai_caller.loc) - target.balloon_alert(ai_caller, "can't roll on yourself!") + if (target == ai_clicker.loc) + target.balloon_alert(ai_clicker, "can't roll on yourself!") return FALSE - var/picked_dir = get_dir(ai_caller, target) + var/picked_dir = get_dir(ai_clicker, target) if (!picked_dir) return FALSE - var/turf/temp_target = get_step(ai_caller, picked_dir) // we can move during the timer so we cant just pass the ref + var/turf/temp_target = get_step(ai_clicker, picked_dir) // we can move during the timer so we cant just pass the ref new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(temp_target, roll_over_time) - ai_caller.balloon_alert_to_viewers("rolling...") - addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), roll_over_time) + ai_clicker.balloon_alert_to_viewers("rolling...") + addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_clicker, picked_dir), roll_over_time) adjust_uses(-1) if(uses) @@ -1213,22 +1213,22 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown) -/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir) - if (ai_caller.incapacitated || !isturf(ai_caller.loc)) // prevents bugs where the ai is carded and rolls +/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_clicker, picked_dir) + if (ai_clicker.incapacitated || !isturf(ai_clicker.loc)) // prevents bugs where the ai is carded and rolls return - var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf + var/turf/target = get_step(ai_clicker, picked_dir) // in case we moved we pass the dir not the target turf if (isnull(target)) return var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (roll_over_cooldown * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls - return ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir)) + return ai_clicker.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir)) /// Used in our radial menu, state-checking proc after the radial menu sleeps -/datum/action/innate/ai/ranged/core_tilt/proc/radial_check(mob/living/silicon/ai/caller) - if (QDELETED(caller) || caller.incapacitated || caller.stat == DEAD) +/datum/action/innate/ai/ranged/core_tilt/proc/radial_check(mob/living/silicon/ai/clicker) + if (QDELETED(clicker) || clicker.incapacitated || clicker.stat == DEAD) return FALSE if (uses <= 0) @@ -1269,42 +1269,42 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) . = ..() desc = "[desc] It has [uses] use\s remaining." -/datum/action/innate/ai/ranged/remote_vendor_tilt/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/ai/ranged/remote_vendor_tilt/do_ability(mob/living/clicker, atom/clicked_on) - if (!isAI(caller)) + if (!isAI(clicker)) return FALSE - var/mob/living/silicon/ai/ai_caller = caller + var/mob/living/silicon/ai/ai_clicker = clicker - if(ai_caller.incapacitated) - unset_ranged_ability(caller) + if(ai_clicker.incapacitated) + unset_ranged_ability(clicker) return FALSE if(!isvendor(clicked_on)) - clicked_on.balloon_alert(ai_caller, "not a vendor!") + clicked_on.balloon_alert(ai_clicker, "not a vendor!") return FALSE var/obj/machinery/vending/clicked_vendor = clicked_on if (clicked_vendor.tilted) - clicked_vendor.balloon_alert(ai_caller, "already tilted!") + clicked_vendor.balloon_alert(ai_clicker, "already tilted!") return FALSE if (!clicked_vendor.tiltable) - clicked_vendor.balloon_alert(ai_caller, "cannot be tilted!") + clicked_vendor.balloon_alert(ai_clicker, "cannot be tilted!") return FALSE if (!clicked_vendor.is_operational) - clicked_vendor.balloon_alert(ai_caller, "inoperable!") + clicked_vendor.balloon_alert(ai_clicker, "inoperable!") return FALSE - var/picked_dir_string = show_radial_menu(ai_caller, clicked_vendor, GLOB.all_radial_directions, custom_check = CALLBACK(src, PROC_REF(radial_check), caller, clicked_vendor)) + var/picked_dir_string = show_radial_menu(ai_clicker, clicked_vendor, GLOB.all_radial_directions, custom_check = CALLBACK(src, PROC_REF(radial_check), clicker, clicked_vendor)) if (isnull(picked_dir_string)) return FALSE var/picked_dir = text2dir(picked_dir_string) var/turf/target = get_step(clicked_vendor, picked_dir) - if (!ai_caller.can_see(target)) - to_chat(ai_caller, span_warning("You can't see the target tile!")) + if (!ai_clicker.can_see(target)) + to_chat(ai_clicker, span_warning("You can't see the target tile!")) return FALSE new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target, time_to_tilt) @@ -1317,7 +1317,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) desc = "[initial(desc)] It has [uses] use\s remaining." build_all_button_icons() - unset_ranged_ability(caller, span_danger("Tilting...")) + unset_ranged_ability(clicker, span_danger("Tilting...")) return TRUE /datum/action/innate/ai/ranged/remote_vendor_tilt/proc/do_vendor_tilt(obj/machinery/vending/vendor, turf/target) @@ -1330,8 +1330,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) vendor.tilt(target, MALF_VENDOR_TIPPING_CRIT_CHANCE) /// Used in our radial menu, state-checking proc after the radial menu sleeps -/datum/action/innate/ai/ranged/remote_vendor_tilt/proc/radial_check(mob/living/silicon/ai/caller, obj/machinery/vending/clicked_vendor) - if (QDELETED(caller) || caller.incapacitated || caller.stat == DEAD) +/datum/action/innate/ai/ranged/remote_vendor_tilt/proc/radial_check(mob/living/silicon/ai/clicker, obj/machinery/vending/clicked_vendor) + if (QDELETED(clicker) || clicker.incapacitated || clicker.stat == DEAD) return FALSE if (QDELETED(clicked_vendor)) @@ -1340,8 +1340,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) if (uses <= 0) return FALSE - if (!caller.can_see(clicked_vendor)) - to_chat(caller, span_warning("Lost sight of [clicked_vendor]!")) + if (!clicker.can_see(clicked_vendor)) + to_chat(clicker, span_warning("Lost sight of [clicked_vendor]!")) return FALSE return TRUE diff --git a/code/modules/basketball/referee.dm b/code/modules/basketball/referee.dm index 2c0a28d7331e1..c515730455855 100644 --- a/code/modules/basketball/referee.dm +++ b/code/modules/basketball/referee.dm @@ -14,33 +14,33 @@ disable_text = span_cult("You decide it was a bad call...") COOLDOWN_DECLARE(whistle_cooldown_minigame) -/datum/action/innate/timeout/InterceptClickOn(mob/living/caller, params, atom/clicked_on) - var/turf/caller_turf = get_turf(caller) - if(!isturf(caller_turf)) +/datum/action/innate/timeout/InterceptClickOn(mob/living/clicker, params, atom/clicked_on) + var/turf/clicker_turf = get_turf(clicker) + if(!isturf(clicker_turf)) return FALSE - if(!ishuman(clicked_on) || get_dist(caller, clicked_on) > 7) + if(!ishuman(clicked_on) || get_dist(clicker, clicked_on) > 7) return FALSE - if(clicked_on == caller) // can't call a foul on yourself + if(clicked_on == clicker) // can't call a foul on yourself return FALSE if(!COOLDOWN_FINISHED(src, whistle_cooldown_minigame)) - caller.balloon_alert(caller, "cant cast for [COOLDOWN_TIMELEFT(src, whistle_cooldown_minigame) *0.1] seconds!") - unset_ranged_ability(caller) + clicker.balloon_alert(clicker, "cant cast for [COOLDOWN_TIMELEFT(src, whistle_cooldown_minigame) *0.1] seconds!") + unset_ranged_ability(clicker) return FALSE return ..() -/datum/action/innate/timeout/do_ability(mob/living/caller, mob/living/carbon/human/target) - caller.say("FOUL BY [target]!", forced = "whistle") - playsound(caller, 'sound/items/whistle/whistle.ogg', 30, FALSE, 4) +/datum/action/innate/timeout/do_ability(mob/living/clicker, mob/living/carbon/human/target) + clicker.say("FOUL BY [target]!", forced = "whistle") + playsound(clicker, 'sound/items/whistle/whistle.ogg', 30, FALSE, 4) - new /obj/effect/timestop(get_turf(target), 0, 5 SECONDS, list(caller), TRUE, TRUE) + new /obj/effect/timestop(get_turf(target), 0, 5 SECONDS, list(clicker), TRUE, TRUE) COOLDOWN_START(src, whistle_cooldown_minigame, 1 MINUTES) - unset_ranged_ability(caller) + unset_ranged_ability(clicker) - to_chat(target, span_bold("[caller] has given you a timeout for a foul!")) - to_chat(caller, span_bold("You put [target] in a timeout!")) + to_chat(target, span_bold("[clicker] has given you a timeout for a foul!")) + to_chat(clicker, span_bold("You put [target] in a timeout!")) return TRUE diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 5c628c0a47990..69a30a4dd5097 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -259,7 +259,10 @@ return ///Called by the drop pods that return captured crewmembers from the ninja den. -/obj/structure/closet/supplypod/proc/return_from_capture(mob/living/victim, turf/destination = get_safe_random_station_turf()) +/obj/structure/closet/supplypod/proc/return_from_capture( + mob/living/victim, + turf/destination = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE) +) if(isnull(destination)) //Uuuuh, something went wrong. This is gonna hurt. to_chat(victim, span_hypnophrase("A million voices echo in your head... \"Seems where you got sent won't \ be able to handle our pod... as if we wanted the occupant to survive. Brace yourself, corporate dog.\"")) diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index 7520e6e769b3e..c1898c0ab9dbe 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -27,3 +27,8 @@ AddElement(/datum/element/earhealing) AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS)) AddComponent(/datum/component/adjust_fishing_difficulty, -2) + +/obj/item/clothing/ears/earmuffs/debug + name = "debug earmuffs" + desc = "Wearing these sends a chat message for every sound played. Walking to ignore footsteps is highly recommended." + clothing_traits = list(TRAIT_SOUND_DEBUGGED) diff --git a/code/modules/clothing/gloves/insulated.dm b/code/modules/clothing/gloves/insulated.dm index 10791ad09f762..9d6f2d13d72e4 100644 --- a/code/modules/clothing/gloves/insulated.dm +++ b/code/modules/clothing/gloves/insulated.dm @@ -105,6 +105,13 @@ . = ..() siemens_coefficient = pick(0,0.5,0.5,0.5,0.5,0.75,1.5) +/obj/item/clothing/gloves/color/fyellow/examine_tags(mob/user) + . = ..() + // Pretend we're always insulated + if (.["partially insulated"]) + . -= "partially insulated" + .["insulated"] = "It is made from a robust electrical insulator and will block any electricity passing through it!" + /obj/item/clothing/gloves/color/fyellow/old desc = "Old and worn out insulated gloves, hopefully they still work." name = "worn out insulated gloves" diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 2ac7db70225f4..2bfab4bb3df13 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -72,6 +72,7 @@ greyscale_config_worn = /datum/greyscale_config/beret/worn greyscale_colors = "#972A2A" dog_fashion = /datum/dog_fashion/head/beret + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM /obj/item/clothing/head/collectable/welding name = "collectable welding helmet" diff --git a/code/modules/clothing/head/frenchberet.dm b/code/modules/clothing/head/frenchberet.dm index de63c6fddfdd1..d876f95dc6c82 100644 --- a/code/modules/clothing/head/frenchberet.dm +++ b/code/modules/clothing/head/frenchberet.dm @@ -5,6 +5,7 @@ greyscale_config = /datum/greyscale_config/beret greyscale_config_worn = /datum/greyscale_config/beret/worn greyscale_colors = "#972A2A" + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM /obj/item/clothing/head/frenchberet/Initialize(mapload) . = ..() diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm index a8247a55603e2..b81971a1ce923 100644 --- a/code/modules/clothing/head/hat.dm +++ b/code/modules/clothing/head/hat.dm @@ -50,6 +50,7 @@ icon_state = "mailman" desc = "'Right-on-time' mail service head wear." clothing_traits = list(TRAIT_HATED_BY_DOGS) + custom_premium_price = PAYCHECK_CREW /obj/item/clothing/head/bio_hood/plague name = "plague doctor's hat" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 640867a7c9334..5afa32ea3918c 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -128,6 +128,7 @@ greyscale_config = /datum/greyscale_config/beret_badge greyscale_config_worn = /datum/greyscale_config/beret_badge/worn greyscale_colors = "#0070B7#FFCE5B" + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM //Head of Personnel /obj/item/clothing/head/hats/hopcap @@ -392,6 +393,7 @@ greyscale_config_worn = /datum/greyscale_config/beret/worn greyscale_colors = "#972A2A" flags_1 = IS_PLAYER_COLORABLE_1 + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM //Security /obj/item/clothing/head/hats/hos @@ -447,6 +449,7 @@ greyscale_config = /datum/greyscale_config/beret_badge greyscale_config_worn = /datum/greyscale_config/beret_badge/worn greyscale_colors = "#39393f#f0cc8f" + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM /obj/item/clothing/head/hats/hos/beret/navyhos name = "head of security's formal beret" diff --git a/code/modules/clothing/spacesuits/specialops.dm b/code/modules/clothing/spacesuits/specialops.dm index dbe02400aa664..1db1448bab92d 100644 --- a/code/modules/clothing/spacesuits/specialops.dm +++ b/code/modules/clothing/spacesuits/specialops.dm @@ -14,6 +14,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF fishing_modifier = 0 + hair_mask = HAIR_MASK_HIDE_ABOVE_45_DEG_MEDIUM /datum/armor/space_beret melee = 80 diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index 9cca1cfc3af08..55a95c3a29795 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -143,12 +143,12 @@ GLOBAL_LIST_INIT(syndicate_space_suits_to_helmets,list( //Black medical syndicate space suit /obj/item/clothing/head/helmet/space/syndicate/black/med - name = "black space helmet" + name = "black medical space helmet" icon_state = "syndicate-helm-black-med" inhand_icon_state = "syndicate-helm-black" /obj/item/clothing/suit/space/syndicate/black/med - name = "green space suit" + name = "black medical space suit" icon_state = "syndicate-black-med" inhand_icon_state = "syndicate-black" helmet_type = /obj/item/clothing/head/helmet/space/syndicate/black/med @@ -198,7 +198,7 @@ GLOBAL_LIST_INIT(syndicate_space_suits_to_helmets,list( //Black with yellow/red engineering syndicate space suit /obj/item/clothing/head/helmet/space/syndicate/black/engie - name = "black space helmet" + name = "black engineering space helmet" icon_state = "syndicate-helm-black-engie" inhand_icon_state = "syndicate-helm-black" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 2c428f1c35c1a..ba7a6b8c0ba6d 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -27,6 +27,7 @@ icon_state = "mailman" inhand_icon_state = "b_suit" clothing_traits = list(TRAIT_HATED_BY_DOGS) + custom_premium_price = PAYCHECK_CREW /obj/item/clothing/under/misc/psyche name = "psychedelic jumpsuit" diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index a263059fa7211..c3abb3d2bd132 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -14,7 +14,8 @@ return for(var/obj/machinery/atmospherics/components/unary/vent_pump/vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) var/turf/vent_turf = get_turf(vent) - if(vent_turf && is_station_level(vent_turf.z) && !vent.welded) + var/area/vent_area = get_area(vent) + if(vent_turf && is_station_level(vent_turf.z) && !vent.welded && istype(vent_area, /area/station)) return TRUE //make sure we have a valid vent to spawn from. return FALSE @@ -92,7 +93,8 @@ var/list/vent_list = list() for(var/obj/machinery/atmospherics/components/unary/vent_pump/vent as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/atmospherics/components/unary/vent_pump)) var/turf/vent_turf = get_turf(vent) - if(vent_turf && is_station_level(vent_turf.z) && !vent.welded && !vent_turf.is_blocked_turf_ignore_climbable()) + var/area/vent_area = get_area(vent) + if(vent_turf && is_station_level(vent_turf.z) && !vent.welded && istype(vent_area, /area/station) && !vent_turf.is_blocked_turf_ignore_climbable()) vent_list += vent if(!length(vent_list)) diff --git a/code/modules/experisci/destructive_scanner.dm b/code/modules/experisci/destructive_scanner.dm index c742aaa68c028..e641fb07a3083 100644 --- a/code/modules/experisci/destructive_scanner.dm +++ b/code/modules/experisci/destructive_scanner.dm @@ -46,6 +46,8 @@ return var/atom/pickup_zone = drop_location() for(var/atom/movable/to_pickup in pickup_zone) + if(to_pickup == src) + continue to_pickup.forceMove(src) flick("tube_down", src) scanning = TRUE diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 8f838ea339bc9..ab64652adb14b 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -386,6 +386,9 @@ bites_amount++ var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR adjust_health(health - (initial(health) / bites_to_finish) * 3) + flinch_on_eat(eater, feeder) + +/obj/item/fish/proc/flinch_on_eat(mob/living/eater, mob/living/feeder) if(status == FISH_ALIVE && prob(50) && feeder.is_holding(src) && feeder.dropItemToGround(src)) to_chat(feeder, span_warning("[src] slips out of your hands in pain!")) var/turf/target_turf = get_ranged_target_turf(get_turf(src), pick(GLOB.alldirs), 2) @@ -459,7 +462,7 @@ return ..() /obj/item/fish/update_icon_state() - if(status == FISH_DEAD && icon_state_dead) + if((status == FISH_DEAD || HAS_TRAIT(src, TRAIT_FISH_STASIS)) && icon_state_dead) icon_state = icon_state_dead else icon_state = base_icon_state @@ -480,7 +483,7 @@ /obj/item/fish/examine(mob/user) . = ..() - if(HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH)) + if(HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH) || HAS_TRAIT(loc, TRAIT_EXAMINE_FISH)) . += span_notice("It's [size] cm long.") . += span_notice("It weighs [weight] g.") @@ -827,6 +830,7 @@ /obj/item/fish/proc/enter_stasis(datum/source) SIGNAL_HANDLER stop_flopping() + update_appearance() STOP_PROCESSING(SSobj, src) /// Start processing again when the stasis trait is removed @@ -918,7 +922,7 @@ // Do additional stuff // Start flopping if outside of fish container - var/should_be_flopping = status == FISH_ALIVE && !HAS_TRAIT(src, TRAIT_FISH_STASIS) && loc && !HAS_TRAIT(loc, TRAIT_IS_AQUARIUM) + var/should_be_flopping = status == FISH_ALIVE && (loc && !HAS_TRAIT(loc, TRAIT_STOP_FISH_FLOPPING)) if(should_be_flopping) start_flopping() @@ -926,6 +930,9 @@ stop_flopping() /obj/item/fish/process(seconds_per_tick) + do_fish_process(seconds_per_tick) + +/obj/item/fish/proc/do_fish_process(seconds_per_tick) if(HAS_TRAIT(src, TRAIT_FISH_STASIS) || status != FISH_ALIVE) return @@ -1502,6 +1509,14 @@ . = ..() aquarium_vc_color = color || initial(aquarium_vc_color) +///Proc called in trophy_fishes.dm, when a fish is mounted on persistent trophy mounts +/obj/item/fish/proc/persistence_save(list/data) + return + +///Proc called in trophy_fishes.dm, when a persistent fishing trophy mount is spawned and the fish instantiated +/obj/item/fish/proc/persistence_load(list/data) + return + /// Returns random fish, using random_case_rarity probabilities. /proc/random_fish_type(required_fluid) var/static/probability_table diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index 7211041915418..aef5dd583f17a 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /// Proc used by both the predator and necrophage traits. /datum/fish_trait/proc/eat_fish(obj/item/fish/predator, obj/item/fish/prey) - var/message = prey.status == FISH_DEAD ? "[src] eats [prey]'s carcass." : "[src] hunts down and eats [prey]." + var/message = prey.status == FISH_DEAD ? "[predator] eats [prey]'s carcass." : "[predator] hunts down and eats [prey]." predator.loc.visible_message(span_warning(message)) SEND_SIGNAL(prey, COMSIG_FISH_EATEN_BY_OTHER_FISH, predator) qdel(prey) @@ -286,11 +286,13 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/emulsijack name = "Emulsifier" catalog_description = "This fish emits an invisible toxin that emulsifies other fish for it to feed on." + var/list/resistance_traits = list(TRAIT_RESIST_EMULSIFY, TRAIT_FISH_TOXIN_IMMUNE) + var/trait_to_add = TRAIT_RESIST_EMULSIFY /datum/fish_trait/emulsijack/apply_to_fish(obj/item/fish/fish) . = ..() RegisterSignal(fish, COMSIG_FISH_LIFE, PROC_REF(emulsify)) - ADD_TRAIT(fish, TRAIT_RESIST_EMULSIFY, FISH_TRAIT_DATUM) + ADD_TRAIT(fish, trait_to_add, FISH_TRAIT_DATUM) /datum/fish_trait/emulsijack/proc/emulsify(obj/item/fish/source, seconds_per_tick) SIGNAL_HANDLER @@ -298,8 +300,9 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) return var/emulsified = FALSE for(var/obj/item/fish/victim in source.loc) - if(HAS_TRAIT(victim, TRAIT_RESIST_EMULSIFY) || HAS_TRAIT(victim, TRAIT_FISH_TOXIN_IMMUNE)) //no team killing - continue + for(var/trait in resistance_traits) + if(HAS_TRAIT(victim, trait)) + continue victim.adjust_health(victim.health - 3 * seconds_per_tick) //the victim may heal a bit but this will quickly kill emulsified = TRUE if(emulsified) diff --git a/code/modules/fishing/fish/types/air_space.dm b/code/modules/fishing/fish/types/air_space.dm index e25a3d7819b2e..5b73b08513192 100644 --- a/code/modules/fishing/fish/types/air_space.dm +++ b/code/modules/fishing/fish/types/air_space.dm @@ -89,6 +89,7 @@ grind_results = list(/datum/reagent/bluespace = 10) fillet_type = null fish_traits = list(/datum/fish_trait/antigrav, /datum/fish_trait/mixotroph) + compatible_types = list(/obj/item/fish/starfish/chrystarfish) beauty = FISH_BEAUTY_GREAT /obj/item/fish/starfish/Initialize(mapload, apply_qualities = TRUE) @@ -97,8 +98,11 @@ /obj/item/fish/starfish/update_overlays() . = ..() + . += add_emissive() + +/obj/item/fish/starfish/proc/add_emissive() if(status == FISH_ALIVE) - . += emissive_appearance(icon, "starfish_emissive", src) + return emissive_appearance(icon, "starfish_emissive", src) ///It spins, and dimly glows in the dark. /obj/item/fish/starfish/flop_animation() @@ -226,3 +230,13 @@ SIGNAL_HANDLER //yes, this means that if we use a spraycan on the fish, the resulting space carp will be of spraycan color result.set_greyscale(colors = list(color)) + +#define PERSISTENCE_FISH_CARP_COLOR "carp_color" + +/obj/item/fish/baby_carp/persistence_save(list/data) + data[PERSISTENCE_FISH_CARP_COLOR] = color + +/obj/item/fish/baby_carp/persistence_load(list/data) + add_atom_colour(data[PERSISTENCE_FISH_CARP_COLOR], FIXED_COLOUR_PRIORITY) + +#undef PERSISTENCE_FISH_CARP_COLOR diff --git a/code/modules/fishing/fish/types/freshwater.dm b/code/modules/fishing/fish/types/freshwater.dm index 8f39d7aa2c86a..64ddb98918b56 100644 --- a/code/modules/fishing/fish/types/freshwater.dm +++ b/code/modules/fishing/fish/types/freshwater.dm @@ -211,10 +211,17 @@ /obj/item/fish/tadpole/set_status(new_status, silent = FALSE) . = ..() if(status == FISH_DEAD) - del_timerid = QDEL_IN_STOPPABLE(src, 12 SECONDS) + if(!istype(loc, /obj/structure/fish_mount)) + del_timerid = QDEL_IN_STOPPABLE(src, 12 SECONDS) else deltimer(del_timerid) +/obj/item/fish/tadpole/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) + . = ..() + if(QDELETED(src) || status != FISH_DEAD || !istype(old_loc, /obj/structure/fish_mount)) + return + qdel(src) + /obj/item/fish/tadpole/proc/growth_checks(datum/source, seconds_per_tick, growth, result_path) SIGNAL_HANDLER var/hunger = get_hunger() diff --git a/code/modules/fishing/fish/types/rift.dm b/code/modules/fishing/fish/types/rift.dm new file mode 100644 index 0000000000000..ce7046c1f0c3a --- /dev/null +++ b/code/modules/fishing/fish/types/rift.dm @@ -0,0 +1,395 @@ +/obj/item/fish/starfish/chrystarfish + name = "chrystarfish" + fish_id = "chrystarfish" + desc = "This is what happens when a cosmostarfish sneaks into the bluespace compartment of a hyperspace engine. Very pointy and damaging - leading cause of spaceship explosions in 2554." + icon = 'icons/obj/aquarium/rift.dmi' + dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi' + icon_state = "chrystarfish" + force = 12 + sharpness = SHARP_POINTY + wound_bonus = -10 + bare_wound_bonus = 15 + armour_penetration = 6 + demolition_mod = 1.2 + throwforce = 11 + throw_range = 8 + throw_speed = 4 + embed_type = /datum/embed_data/chrystarfish + attack_verb_continuous = list("stabs", "jabs") + attack_verb_simple = list("stab", "jab") + hitsound = SFX_SHATTER + pickup_sound = 'sound/items/handling/materials/glass_pick_up.ogg' + drop_sound = 'sound/items/handling/materials/glass_drop.ogg' + + sprite_width = 7 + sprite_height = 9 + + average_size = 40 + average_weight = 1500 + food = /datum/reagent/bluespace + feeding_frequency = 10 MINUTES + health = 50 + death_text = "%SRC splinters apart into shards!" + random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS + fillet_type = /obj/item/stack/ore/bluespace_crystal + num_fillets = 3 + stable_population = 3 + compatible_types = list(/obj/item/fish/starfish) + fish_traits = list(/datum/fish_trait/antigrav) + beauty = FISH_BEAUTY_EXCELLENT + fish_movement_type = /datum/fish_movement/accelerando + fishing_difficulty_modifier = 15 + favorite_bait = list(/obj/item/stack/ore/bluespace_crystal) + // something something bluespace + electrogenesis_power = 9 MEGA JOULES + +// Basically a ninja star that's highly likely to embed and teleports you around if you don't stop to remove it. However it doesn't deal that much damage! +/datum/embed_data/chrystarfish + pain_mult = 1 + embed_chance = 85 + fall_chance = 3 + pain_chance = 9 + impact_pain_mult = 1 + remove_pain_mult = 2 + rip_time = 1.5 SECONDS + ignore_throwspeed_threshold = TRUE // basically shaped like a shuriken + jostle_chance = 15 + jostle_pain_mult = 1 + // about to be set! + jostle_callback = null + +/datum/embed_data/chrystarfish/New() + ..() + jostle_callback = CALLBACK(src, PROC_REF(teleport)) + +/datum/embed_data/chrystarfish/proc/teleport(mob/victim, atom/embed_parent, datum/embed_data/real_data) + do_teleport(victim, get_turf(victim), 3, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) + victim.visible_message(span_danger("[victim] teleports as [embed_parent] jostles inside [victim.p_them()]!")) + +/obj/item/fish/starfish/chrystarfish/set_status(new_status, silent) + . = ..() + if(new_status == FISH_DEAD) + new fillet_type(get_turf(src)) + playsound(src, SFX_SHATTER, 50) + qdel(src) + +/obj/item/fish/starfish/chrystarfish/add_emissive() + return + +/obj/item/fish/starfish/chrystarfish/get_base_edible_reagents_to_add() + var/list/return_list = ..() + return_list[/datum/reagent/bluespace] = 5 + return return_list + +/obj/item/fish/starfish/chrystarfish/flinch_on_eat(mob/living/eater, mob/living/feeder) + if(status != FISH_ALIVE) + return + to_chat(feeder, span_warning("[src] slips out of the spacetime in pain!")) + + var/tp_range = 6 * clamp(weight/average_weight, 3, 9) // usually 6, plus or minus fish weight + // teleports itself if on a turf otherwise its container - whatever it is + do_teleport(isturf(loc) ? src : loc, get_turf(feeder), tp_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) + +/obj/item/fish/starfish/chrystarfish/suicide_act(mob/living/user) + visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!")) + forceMove(user) + // *everything* + for(var/obj/thing in user.get_contents()) + if(QDELETED(thing) || istype(thing, /obj/item/bodypart/chest)) + continue // don't want a gib + stoplag(0.1 SECONDS) + playsound(src, 'sound/effects/phasein.ogg', 15, TRUE) + do_teleport(thing, get_turf(user), 2, asoundin = null, channel = TELEPORT_CHANNEL_BLUESPACE) + qdel(src) + return MANUAL_SUICIDE + +// Prevents the first 2 messages from spamming on each patience update. +#define PATIENCE_FLINCH "PATIENCE_FLINCH" +#define PATIENCE_UNCOMFY "PATIENCE_UNCOMFY" + +/obj/item/fish/dolphish + name = "walro-dolphish" + fish_id = "walro-dolphish" + desc = "Strange bloodthirsty apex predator from beyond. A powerful weapon, but it -hates- being held." + icon = 'icons/obj/aquarium/wide.dmi' + dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi' + icon_state = "dolphish" + lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fish_righthand.dmi' + force = 19 + sharpness = SHARP_POINTY + wound_bonus = -5 + bare_wound_bonus = 20 + armour_penetration = 12 + block_chance = 33 + throwforce = 7 + throw_range = 4 + attack_verb_continuous = list("bites", "impales", "rams") + attack_verb_simple = list("bite", "impale", "ram") + hitsound = 'sound/items/weapons/bladeslice.ogg' + block_sound = 'sound/items/weapons/parry.ogg' + drop_sound = 'sound/mobs/non-humanoids/fish/fish_drop1.ogg' + pickup_sound = SFX_FISH_PICKUP + sound_vary = TRUE + + base_pixel_x = -16 + pixel_x = -16 + sprite_width = 13 + sprite_height = 9 + + required_fluid_type = AQUARIUM_FLUID_AIR + required_temperature_min = BODYTEMP_COLD_DAMAGE_LIMIT // you mean just like a human? that's odd... + required_temperature_max = BODYTEMP_HEAT_DAMAGE_LIMIT + food = /datum/reagent/blood + health = 600 // apex predator + random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS + fillet_type = /obj/item/food/fishmeat/fish_tail + num_fillets = 1 + stable_population = 3 + fish_traits = list(/datum/fish_trait/wary, /datum/fish_trait/carnivore, /datum/fish_trait/necrophage, /datum/fish_trait/predator, /datum/fish_trait/territorial, /datum/fish_trait/stinger) + fish_movement_type = /datum/fish_movement/choppy + fishing_difficulty_modifier = 30 + favorite_bait = list() + disliked_bait = list() + average_size = 150 + average_weight = 2750 + weight_size_deviation = 0.5 + safe_air_limits = list( + /datum/gas/oxygen = list(12, 100), + /datum/gas/nitrogen, + /datum/gas/carbon_dioxide = list(0, 10), + ) + min_pressure = HAZARD_LOW_PRESSURE + max_pressure = HAZARD_HIGH_PRESSURE + beauty = FISH_BEAUTY_GREAT + /// Maximum patience for below var. + var/max_patience = 20 + /// Counter of how much patience the fish currently has before it attacks its wielder. + var/patience = 20 + /// Ensures the last warning fx isn't repeated + var/last_effect + +/obj/item/fish/dolphish/get_force_rank() + var/multiplier = 1 + switch(w_class) + if(WEIGHT_CLASS_TINY) + multiplier = 0.35 + if(WEIGHT_CLASS_SMALL) + multiplier = 0.5 + if(WEIGHT_CLASS_NORMAL) + multiplier = 0.75 + // bulky is avergae + if(WEIGHT_CLASS_HUGE) + multiplier = 1.15 + if(WEIGHT_CLASS_GIGANTIC) + multiplier = 1.35 + + if(status == FISH_DEAD) + multiplier -= 0.35 // huge nerf if dead + + force *= multiplier + attack_speed *= multiplier + demolition_mod *= multiplier + block_chance *= multiplier + armour_penetration *= multiplier + wound_bonus *= multiplier + bare_wound_bonus *= multiplier + +/obj/item/fish/dolphish/do_fish_process(seconds_per_tick) + . = ..() + var/patience_reduction = 1 + + var/turf/onturf = get_turf(loc) + //gas check + var/datum/gas_mixture/turf_gasmix = onturf.return_air() + // likes water, gets sleepy, gets very sleepy + if(turf_gasmix.gases[/datum/gas/water_vapor] && turf_gasmix.gases[/datum/gas/water_vapor][MOLES] >= 5) + patience_reduction *= 0.5 + if(turf_gasmix.gases[/datum/gas/nitrous_oxide] && turf_gasmix.gases[/datum/gas/nitrous_oxide][MOLES] >= 5) + patience_reduction *= 0.25 + if(turf_gasmix.gases[/datum/gas/healium] && turf_gasmix.gases[/datum/gas/healium][MOLES] >= 5) + patience_reduction *= 0.1 + + if(!ismob(loc)) + // dividing by the multiplier nets us an increasing value. happy dolphish gain patience quicker + var/patience_bonus = (1 / patience_reduction) + patience = clamp(patience + patience_bonus * seconds_per_tick, 0, max_patience) + return + + var/mob/living/moc = loc + if(moc.mob_biotypes & MOB_AQUATIC) + patience_reduction *= 0.6 + if(HAS_TRAIT(moc, TRAIT_IS_WET)) + patience_reduction *= 0.6 + + patience = clamp(patience - (patience_reduction * seconds_per_tick), 0, max_patience) + + switch(patience) + if(0) + // No check, we always want sharky to bite jerky on 0 + moc.visible_message(span_bolddanger("[src] bites directly into [moc] and squirms away from [moc.p_their()] grasp!"), span_userdanger("[src] sinks its fangs into you!!")) + moc.apply_damage(force, BRUTE, moc.get_active_hand(), wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attacking_item = src) + forceMove(moc.drop_location()) + moc.painful_scream() + patience = max_patience + playsound(src, hitsound, 45) + if(1 to 10) + // No check, final warning as they struggle, also funny. + visible_message(span_bolddanger("[src] thrashes against [moc]'s grasp!")) + moc.shake_up_animation() + if(10 to 15) + if(last_effect == PATIENCE_FLINCH) + return + visible_message(span_danger("[src] flinches away from [moc]!")) + moc.shake_up_animation() + last_effect = PATIENCE_FLINCH + if(15 to 20) + if(last_effect == PATIENCE_UNCOMFY) + return + visible_message(span_notice("[src] seems uncomfortable in [moc]'s grasp.")) + last_effect = PATIENCE_UNCOMFY + + return + +#undef PATIENCE_FLINCH +#undef PATIENCE_UNCOMFY + +/obj/item/fish/flumpulus + name = "flumpulus" + fish_id = "flumpulus" + desc = "You can hardly even guess as to how this possibly counts as a fish. Inexplicably, you get the feeling that it could serve as a fantastic way to cushion a fall." + icon = 'icons/obj/aquarium/rift.dmi' + dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi' + icon_state = "flumpulus" + lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fish_righthand.dmi' + attack_verb_continuous = list("splats", "splorts") + attack_verb_simple = list("splat", "splort") + + sprite_width = 10 + sprite_height = 9 + + required_fluid_type = AQUARIUM_FLUID_AIR + required_temperature_min = 0 + required_temperature_max = INFINITY + food = /datum/reagent/consumable/nutriment/fat + random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS + fillet_type = /obj/item/food/meat/slab/human/mutant/slime + num_fillets = 2 + stable_population = 2 + fish_traits = list() + fish_movement_type = /datum/fish_movement/slow + fishing_difficulty_modifier = 22 + favorite_bait = list() + disliked_bait = list() + // twice as big, half as heavy + average_size = 100 + average_weight = 500 + material_weight_mult = 1 + weight_size_deviation = 0.6 + safe_air_limits = list( + /datum/gas/nitrogen, + ) + min_pressure = 0 + max_pressure = HAZARD_HIGH_PRESSURE + beauty = FISH_BEAUTY_UGLY + +/obj/item/fish/flumpulus/suicide_act(mob/living/user) + visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!")) + forceMove(user) + . = MANUAL_SUICIDE + for(var/i in 1 to rand(5, 15)) + addtimer(CALLBACK(src, PROC_REF(flump_attack), user), 0.4 SECONDS * i) + +/obj/item/fish/flumpulus/proc/flump_attack(mob/living/user) + var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES) + var/obj/item/organ/eyes/new_eyes = pick(list(/obj/item/organ/eyes/snail, /obj/item/organ/eyes/night_vision/mushroom)) + new_eyes = new new_eyes(user) + new_eyes.Insert(user) + playsound(user, 'sound/effects/cartoon_sfx/cartoon_pop.ogg', 50, TRUE) + user.visible_message("[user]'s [eyes ? eyes : "eye holes"] suddenly sprout stalks and turn into [new_eyes]!") + ASYNC + user.emote("scream") + sleep(5 SECONDS) + if(!QDELETED(eyes)) + eyes.visible_message(span_danger("[eyes] rapidly turn to dust.")) + eyes.dust() + +/obj/item/fish/flumpulus/get_base_edible_reagents_to_add() + var/list/return_list = ..() + //return_list[/datum/reagent/flumpulus_extract] = 10 + return_list[/datum/reagent/medicine/oculine/flumpuline] = 10 + return return_list + +/obj/item/fish/flumpulus/intercept_zImpact(list/falling_movables, levels) + . = ..() + if(status == FISH_DEAD) + return . + + for(var/mob/living/fallen_mob in falling_movables) + visible_message(span_danger("[src] flattens like a pancake as [fallen_mob] lands on top of it!")) + adjust_health(initial(health) * 0.1) // very durable + AddElement(/datum/element/squish, 15 SECONDS) + fallen_mob.Paralyze(0.5 SECONDS) + playsound(src, 'sound/effects/cartoon_sfx/cartoon_splat.ogg', 75) + + return FALL_INTERCEPTED | FALL_NO_MESSAGE + +/obj/item/fish/gullion + name = "gullion" + fish_id = "gullion" + desc = "This crystalline fish is actually one of only two known silicon-based lifeforms.\ + It avoids death via oxygen-silicate reactions by organically shielding its exterior, allowing the thick scales to calcify into quartz and diamond, at the cost of rendering the fish functionally blind. \ + How xenomorphs manage is a complete mystery bordering on bullshit." + icon = 'icons/obj/aquarium/rift.dmi' + dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi' + icon_state = "gullion" + lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi' + righthand_file = 'icons/mob/inhands/fish_righthand.dmi' + attack_verb_continuous = list("stabs", "jabs") + attack_verb_simple = list("stab", "jab") + hitsound = SFX_DEFAULT_FISH_SLAP + pickup_sound = 'sound/items/handling/materials/glass_pick_up.ogg' + drop_sound = 'sound/items/handling/materials/glass_drop.ogg' + sprite_width = 7 + sprite_height = 5 + + food = /datum/reagent/silicon + feeding_frequency = 30 SECONDS + health = 160 + death_text = "%SRC calcifies." + random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS + fillet_type = /obj/item/stack/sheet/mineral/diamond + num_fillets = 2 + stable_population = 3 + fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/parthenogenesis) // this thing is a diamond farm + beauty = FISH_BEAUTY_EXCELLENT + fish_movement_type = /datum/fish_movement/slow + favorite_bait = list(/obj/item/stack/sheet/mineral/diamond) + fishing_difficulty_modifier = 22 + average_size = 30 + average_weight = 2000 + weight_size_deviation = 0.3 + safe_air_limits = list( + /datum/gas/oxygen = list(0, 2), // does NOT like oxygen + /datum/gas/water_vapor, + ) + required_fluid_type = AQUARIUM_FLUID_SULPHWATEVER + required_temperature_min = 0 + required_temperature_max = BODYTEMP_HEAT_DAMAGE_LIMIT + min_pressure = HAZARD_LOW_PRESSURE + max_pressure = WARNING_HIGH_PRESSURE + +/obj/item/fish/gullion/suicide_act(mob/living/user) + visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!")) + forceMove(user) + var/datum/gas_mixture/environment = user.loc.return_air() + var/oxygen_in_air = check_gases(environment.gases, list(/datum/gas/oxygen)) + if(!oxygen_in_air || (status == FISH_DEAD)) + visible_message(span_suicide("[user] chokes and dies! (Wait, from the fish or from lack of air?)")) + return OXYLOSS + + user.petrify(statue_timer = INFINITY) + visible_message(span_suicide("[user]'s skin turns into quartz upon contact with the oxygen in the air!'")) + qdel(src) + return MANUAL_SUICIDE diff --git a/code/modules/fishing/fish/types/station.dm b/code/modules/fishing/fish/types/station.dm index ca7306038a60f..f8078579a5311 100644 --- a/code/modules/fishing/fish/types/station.dm +++ b/code/modules/fishing/fish/types/station.dm @@ -207,18 +207,27 @@ /obj/item/fish/fryish/fritterish/Initialize(mapload, apply_qualities = TRUE) . = ..() variant = pick(FISH_FRITTERISH, FISH_BERNARD, FISH_MATTHEW) + load_variant(pick(FISH_FRITTERISH, FISH_BERNARD, FISH_MATTHEW)) + +/obj/item/fish/fryish/fritterish/proc/load_variant(new_variant) + variant = new_variant switch(variant) if(FISH_BERNARD) - name = "bernard-fish" - desc = "A deliciously extremophile alien fish shaped like a dinosaur. Children love it." - base_icon_state = icon_state = "bernardfish" sprite_width = 4 sprite_height = 6 if(FISH_MATTHEW) - name = "matthew-fish" - desc = "A deliciously extremophile alien fish shaped like a pterodactyl. Children love it." - base_icon_state = icon_state = "matthewfish" sprite_width = 6 + update_appearance() + +#define PERSISTENCE_FISH_FRITTERISH_VARIANT "fritterish_variant" + +/obj/item/fish/fryish/fritterish/persistence_save(list/data) + data[PERSISTENCE_FISH_FRITTERISH_VARIANT] = variant + +/obj/item/fish/fryish/fritterish/persistence_load(list/data) + load_variant(data[PERSISTENCE_FISH_FRITTERISH_VARIANT]) + +#undef PERSISTENCE_FISH_FRITTERISH_VARIANT /obj/item/fish/fryish/fritterish/update_name() switch(variant) diff --git a/code/modules/fishing/fish_mount.dm b/code/modules/fishing/fish_mount.dm new file mode 100644 index 0000000000000..c3de8bc5a5036 --- /dev/null +++ b/code/modules/fishing/fish_mount.dm @@ -0,0 +1,211 @@ +/obj/item/wallframe/fish + name = "fish mount" + desc = "The frame of a mount for trophy fish, to show off your proudest catch." + icon = 'icons/obj/wallmounts.dmi' + icon_state = "fish_mount_item" + result_path = /obj/structure/fish_mount + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT) + pixel_shift = 31 + ///Reference to the persistent_id of the mount this was spawned from. + var/persistence_id + +/obj/item/wallframe/fish/after_attach(obj/structure/fish_mount/mount) + . = ..() + mount.persistence_id = persistence_id + +///A wallmounted structure on which a fish can be attached to be used as room decoration. +/obj/structure/fish_mount + name = "fish mount" + desc = "A mount for trophy fish, to show off your proudest catch." + icon = 'icons/obj/wallmounts.dmi' + icon_state = "fish_mount" + anchored = TRUE + opacity = FALSE + density = FALSE + layer = SIGN_LAYER + max_integrity = 100 + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT) + armor_type = /datum/armor/structure_sign + resistance_flags = FLAMMABLE + /// The instance of the fish mounted on this. + var/obj/item/fish/mounted_fish + /// The identifier for mounts that carry the trophy between rounds. + var/persistence_id + /// Trophies from persistence are dusted if removed to be safe. + var/persistence_loaded_fish = FALSE + /// String containing the name of whoever caught the fish + var/catcher_name + /// The date of when the fish was mounted (which should coincide with the day when it was actually caught) + var/catch_date + +/obj/structure/fish_mount/Initialize(mapload, floor_to_wall_dir) + . = ..() + //Mounted fish shouldn't flop. It should also show size and weight to everyone. + add_traits(list(TRAIT_STOP_FISH_FLOPPING, TRAIT_EXAMINE_FISH), INNATE_TRAIT) + if(floor_to_wall_dir) + setDir(floor_to_wall_dir) + find_and_hang_on_wall() + if(!persistence_id) + return + if(SSfishing.initialized) + load_trophy_fish() + else + RegisterSignal(SSfishing, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(load_trophy_fish)) + +/obj/structure/fish_mount/proc/load_trophy_fish(datum/source) + SIGNAL_HANDLER + SSpersistence.load_trophy_fish(src) + UnregisterSignal(SSfishing, COMSIG_SUBSYSTEM_POST_INITIALIZE) + if(!mounted_fish) + add_first_fish() + +/obj/structure/fish_mount/screwdriver_act(mob/living/user, obj/item/item) + . = ..() + balloon_alert(user, "removing mount...") + if(!item.use_tool(src, user, 3 SECONDS, volume = 50)) + return ITEM_INTERACT_BLOCKING + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + balloon_alert_to_viewers("fish mount removed") + deconstruct() + return ITEM_INTERACT_SUCCESS + +/obj/structure/fish_mount/proc/add_first_fish() + var/obj/item/fish/fish_path = pick(subtypesof(/obj/item/fish) - typesof(/obj/item/fish/holo)) + if(fish_path.fish_id_redirect_path) + fish_path = fish_path.fish_id_redirect_path + var/fluff_name = pick("John Trasen III", "a nameless intern", "Pun Pun", AQUARIUM_COMPANY, "Unknown", "Central Command") + add_fish(new fish_path(src), from_persistence = TRUE, catcher = fluff_name) + mounted_fish.randomize_size_and_weight() + mounted_fish.set_status(FISH_DEAD) + SSpersistence.save_trophy_fish(src) + +/obj/structure/fish_mount/atom_deconstruct(disassembled = TRUE) + . = ..() + if(disassembled) + var/obj/item/wallframe/fish/frame = new (loc) + frame.persistence_id = persistence_id + mounted_fish?.forceMove(loc) + +/obj/structure/fish_mount/item_interaction(mob/living/user, obj/item/item, list/modifiers) + if(!isfish(item) || user.combat_mode) + return ..() + if(mounted_fish) + balloon_alert(user, "remove other fish first!") + return ITEM_INTERACT_BLOCKING + if(item.flags_1 & HOLOGRAM_1) + balloon_alert(user, "fish not mountable!") + return ITEM_INTERACT_BLOCKING + balloon_alert(user, "mounting fish...") + if(!do_after(user, 3 SECONDS, src) || mounted_fish) + return ITEM_INTERACT_BLOCKING + add_fish(item, catcher = user.name) + balloon_alert_to_viewers("fish mounted") + playsound(loc, 'sound/machines/click.ogg', 30, TRUE) + return ITEM_INTERACT_SUCCESS + +/obj/structure/fish_mount/proc/add_fish(obj/item/fish/fish, from_persistence = FALSE, catcher) + if(mounted_fish) + mounted_fish.forceMove(loc) + fish.forceMove(src) + vis_contents += fish + fish.flags_1 |= IS_ONTOP_1 + fish.vis_flags |= (VIS_INHERIT_PLANE|VIS_INHERIT_LAYER) + fish.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP + fish.obj_flags &= ~UNIQUE_RENAME + fish.anchored = TRUE + mounted_fish = fish + + catcher_name = catcher + catch_date = "[time2text(world.realtime, "Day, Month DD")], [CURRENT_STATION_YEAR]" + + AddElement(/datum/element/beauty, get_fish_beauty()) + RegisterSignal(fish, COMSIG_ATOM_EXAMINE, PROC_REF(on_fish_examined)) + RegisterSignals(fish, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW), PROC_REF(on_fish_attack_hand)) + rotate_fish(dir) + if(from_persistence) + persistence_loaded_fish = TRUE + fish.remove_fillet_type() + fish.fillet_type = null + else if(persistence_id) + SSpersistence.save_trophy_fish(src) + +/obj/structure/fish_mount/proc/get_fish_beauty() + var/beauty = 100 + mounted_fish.beauty * 1.2 + var/datum/material/main_material = mounted_fish.get_master_material() + if(main_material) + beauty += main_material.beauty_modifier * mounted_fish.weight + return round(beauty) + +/obj/structure/fish_mount/proc/rotate_fish(direction, old_direction) + var/rotation = angle2dir(REVERSE_DIR(direction)) + if(old_direction) + rotation -= angle2dir(REVERSE_DIR(old_direction)) + + if(!rotation) + return + mounted_fish.transform = mounted_fish.transform.Turn(rotation) + +/obj/structure/fish_mount/setDir(newdir) + var/old_dir = dir + . = ..() + rotate_fish(dir, old_dir) + +/obj/structure/fish_mount/proc/on_fish_examined(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += span_boldnicegreen("Caught by [catcher_name] on [catch_date].") + +/obj/structure/fish_mount/proc/on_fish_attack_hand(datum/source, mob/living/user) + SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(remove_fish), user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/fish_mount/attack_hand_secondary(mob/living/user, list/modifiers) + . = ..() + if(!mounted_fish) + balloon_alert(user, "no fish mounted!") + else + remove_fish(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/fish_mount/proc/remove_fish(mob/living/user) + balloon_alert(user, "removing fish...") + if(!do_after(user, 3 SECONDS, src) || !mounted_fish) + return + var/obj/item/fish/fish_reference = mounted_fish + //remove it before trying to put it in hands so we don't end up with a lingering in-hand overlay if the fish is deleted. + fish_reference.moveToNullspace() + if(QDELETED(fish_reference)) + var/ash_type = /obj/effect/decal/cleanable/ash + if(fish_reference.w_class >= WEIGHT_CLASS_BULKY) + ash_type = /obj/effect/decal/cleanable/ash/large + new ash_type(loc) + visible_message("[fish_reference] turns into dust as [fish_reference.p_theyre()] removed from [src].") + else + user.put_in_hands(mounted_fish) + balloon_alert_to_viewers("fish removed") + +/obj/structure/fish_mount/Exited(atom/movable/gone) + if(gone != mounted_fish) + return ..() + RemoveElement(/datum/element/beauty, get_fish_beauty()) + if(persistence_loaded_fish) + if(!QDELETED(mounted_fish)) + qdel(mounted_fish) + else + rotate_fish(0, dir) + UnregisterSignal(mounted_fish, list(COMSIG_ATOM_EXAMINE, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW)) + mounted_fish.flags_1 &= ~IS_ONTOP_1 + mounted_fish.vis_flags &= ~(VIS_INHERIT_PLANE|VIS_INHERIT_LAYER) + mounted_fish.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP + mounted_fish.obj_flags |= UNIQUE_RENAME + mounted_fish.anchored = FALSE + persistence_loaded_fish = FALSE + catcher_name = null + catch_date = null + mounted_fish = null + return ..() + +/obj/structure/fish_mount/bar + persistence_id = "Bar" + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fish_mount/bar, /obj/item/wallframe/fish::pixel_shift) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 8190b21c84c4d..f527db6e6c350 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -132,6 +132,13 @@ . += "" //add a new line . += span_notice("Thanks to your fishing skills, you can examine it again for more in-depth information.") return + if(HAS_TRAIT(src, TRAIT_ROD_MANSUS_INFUSED)) + if(IS_HERETIC(user)) + . += span_purple("This rod has been infused by a heretic, improving its ability to catch glimpses of the Mansus. And fish.") + else + . += span_purple("It's glowing an eerie purple...") + else if(IS_HERETIC(user)) + . += span_purple("As a Heretic, you can infuse this fishing rod with your Mansus Grasp by activating the spell while wielding it, to enhance its fishing power.") /obj/item/fishing_rod/examine_more(mob/user) . = ..() diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index cb0eaecc9890d..00387c1cffe9e 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -504,6 +504,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) /datum/fish_source/proc/spawn_reward_from_explosion(atom/location, severity) SIGNAL_HANDLER + if(fish_source_flags & FISH_SOURCE_FLAG_EXPLOSIVE_NONE) + return var/multiplier = 1 if(fish_source_flags & FISH_SOURCE_FLAG_EXPLOSIVE_MALUS) if(explosive_fishing_score <= 0) diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index 8177651973546..2c3833080f1b9 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -159,6 +159,7 @@ radial_name = "Chasm" overlay_state = "portal_chasm" radial_state = "ground_hole" + fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_NONE /datum/fish_source/portal/ocean fish_table = list( @@ -295,7 +296,7 @@ mover.long_jump_velocity_limit += rand(-100, 100) ///Cherry on top, fish caught from the randomizer portal also have (almost completely) random traits -/datum/fish_source/portal/random/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) +/datum/fish_source/portal/random/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod) if(!ispath(reward_path, /obj/item/fish)) return ..() @@ -342,9 +343,6 @@ return rod.hook.chasm_detritus_type -/datum/fish_source/chasm/spawn_reward_from_explosion(atom/location, severity) - return //Spawned content would immediately fall back into the chasm, so it wouldn't matter. - /datum/fish_source/lavaland catalog_description = "Lava vents" background = "background_lavaland" @@ -582,7 +580,7 @@ return return ..() -/datum/fish_source/hydro_tray/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) +/datum/fish_source/hydro_tray/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod) if(reward_path != FISHING_RANDOM_SEED) var/mob/living/created_reward = ..() if(istype(created_reward)) @@ -662,7 +660,7 @@ //The range for waiting is also a bit narrower, so it cannot take as few as 3 seconds or as many as 25 to snatch an organ. wait_time_range = list(6 SECONDS, 12 SECONDS) -/datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) +/datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod) if(istype(fishing_spot, /obj/machinery/fishing_portal_generator)) var/obj/machinery/fishing_portal_generator/portal = fishing_spot fishing_spot = portal.current_linked_atom @@ -707,7 +705,7 @@ fish_table = list( FISHING_DUD = 10, ) - fish_source_flags = FISH_SOURCE_FLAG_NO_BLUESPACE_ROD|FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG + fish_source_flags = FISH_SOURCE_FLAG_NO_BLUESPACE_ROD|FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG|FISH_SOURCE_FLAG_EXPLOSIVE_NONE fishing_difficulty = FISHING_EASY_DIFFICULTY + 5 #undef RANDOM_AQUARIUM_FISH @@ -725,9 +723,6 @@ return fish_table return table -/datum/fish_source/aquarium/spawn_reward_from_explosion(atom/location, severity) - return //If the aquarium breaks, all fish are released anyway. - /datum/fish_source/aquarium/generate_wiki_contents(datum/autowiki/fish_sources/wiki) var/list/data = list() @@ -775,3 +770,77 @@ ) fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 20 fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_MALUS + +/datum/fish_source/dimensional_rift + catalog_description = null //it's a secret (sorta, I know you're reading this) + radial_state = "cursed" // placeholder + overlay_state = "portal_rift_2" // yeah good luck adaptin the rift sprite to this template. recolored randomizer's the best you're getting + fish_table = list( + FISHING_INFLUENCE = 6, + /obj/item/fish/starfish/chrystarfish = 7, + /obj/item/fish/dolphish = 7, + /obj/item/fish/flumpulus = 7, + /obj/item/fish/gullion = 7, + /mob/living/basic/heretic_summon/fire_shark/wild = 3, + /obj/item/eldritch_potion/crucible_soul = 1, + /obj/item/eldritch_potion/duskndawn = 1, + /obj/item/eldritch_potion/wounded = 1, + /obj/item/reagent_containers/cup/beaker/eldritch = 2, + ) + fish_counts = list( + /mob/living/basic/heretic_summon/fire_shark/wild = 3, + /obj/item/eldritch_potion/crucible_soul = 1, + /obj/item/eldritch_potion/duskndawn = 1, + /obj/item/eldritch_potion/wounded = 1, + /obj/item/reagent_containers/cup/beaker/eldritch = 2, + ) + fish_count_regen = list( + /mob/living/basic/heretic_summon/fire_shark/wild = 3 MINUTES, + /obj/item/eldritch_potion/crucible_soul = 5 MINUTES, + /obj/item/eldritch_potion/duskndawn = 5 MINUTES, + /obj/item/eldritch_potion/wounded = 5 MINUTES, + /obj/item/reagent_containers/cup/beaker/eldritch = 2.5 MINUTES, + ) + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 35 + fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_NONE + +/datum/fish_source/dimensional_rift/on_challenge_completed(mob/user, datum/fishing_challenge/challenge, success) + . = ..() + + if(challenge.reward_path != FISHING_INFLUENCE) + return + var/mob/living/carbon/human/human_user + if(ishuman(user)) + human_user = user + + user.visible_message(span_danger("[user] reels [user.p_their()] [challenge.used_rod] in, catching.. nothing?"), span_notice("You catch.. a glimpse into the workings of the Mansus itself!")) + // Heretics that fish in the rift gain knowledge. + if(IS_HERETIC(user)) + human_user?.add_mood_event("rift fishing", /datum/mood_event/rift_fishing) + var/obj/effect/heretic_influence/fishfluence = challenge.location + // But only if it's an open rift + if(!istype(fishfluence)) + to_chat(user, span_notice("You glimpse something fairly uninteresting.")) + return + fishfluence.after_drain(user) + var/datum/antagonist/heretic/heretic_datum = GET_HERETIC(user) + if(heretic_datum) + heretic_datum.knowledge_points++ + to_chat(user, "[span_hear("You hear a whisper...")] [span_hypnophrase("THE HIGHER I RISE, THE MORE I FISH.")]") + // They can also gain an extra influence point if they infused their rod. + if(HAS_TRAIT(challenge.used_rod, TRAIT_ROD_MANSUS_INFUSED)) + heretic_datum.knowledge_points++ + to_chat(user, span_boldnotice("Your infused rod improves your knowledge gain!")) + return + + // Non-heretics instead go crazy + human_user?.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 190) + human_user?.add_mood_event("gates_of_mansus", /datum/mood_event/gates_of_mansus) + // Hand fires at them from the location + fire_curse_hand(user, get_turf(challenge.location)) + +// Handled above +/datum/fish_source/dimensional_rift/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) + if(reward_path != FISHING_INFLUENCE) + return ..() + return diff --git a/code/modules/food_and_drinks/machinery/coffeemaker.dm b/code/modules/food_and_drinks/machinery/coffeemaker.dm index 51280fd87d6d8..489a548cc56df 100644 --- a/code/modules/food_and_drinks/machinery/coffeemaker.dm +++ b/code/modules/food_and_drinks/machinery/coffeemaker.dm @@ -3,12 +3,13 @@ /obj/machinery/coffeemaker name = "coffeemaker" desc = "A Modello 3 Coffeemaker that brews coffee and holds it at the perfect temperature of 176 fahrenheit. Made by Piccionaia Home Appliances." - icon = 'icons/obj/medical/chemical.dmi' + icon = 'icons/obj/machines/coffeemaker.dmi' icon_state = "coffeemaker_nopot_nocart" base_icon_state = "coffeemaker" resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/coffeemaker anchored_tabletop_offset = 4 + interaction_flags_machine = parent_type::interaction_flags_machine | INTERACT_MACHINE_OFFLINE var/obj/item/reagent_containers/cup/coffeepot/coffeepot = null var/brewing = FALSE var/brew_time = 20 SECONDS @@ -148,7 +149,10 @@ /obj/machinery/coffeemaker/proc/overlay_checks() . = list() if(coffeepot) - . += "coffeemaker_pot" + if(istype(coffeepot, /obj/item/reagent_containers/cup/coffeepot/bluespace)) + . += "coffeemaker_pot_bluespace" + else + . += "coffeemaker_pot_[coffeepot.reagents.total_volume ? "full" : "empty"]" if(cartridge) . += "coffeemaker_cartidge" return . @@ -418,6 +422,7 @@ operate_for(brew_time) coffeepot.reagents.add_reagent_list(cartridge.drink_type) cartridge.charges-- + update_appearance(UPDATE_OVERLAYS) //Coffee Cartridges: like toner, but for your coffee! /obj/item/coffee_cartridge @@ -501,7 +506,6 @@ /obj/machinery/coffeemaker/impressa name = "impressa coffeemaker" desc = "An industry-grade Impressa Modello 5 Coffeemaker of the Piccionaia Home Appliances premium coffeemakers product line. Makes coffee from fresh dried whole beans." - icon = 'icons/obj/machines/coffeemaker.dmi' icon_state = "coffeemaker_impressa" circuit = /obj/item/circuitboard/machine/coffeemaker/impressa initial_cartridge = null //no cartridge, just coffee beans @@ -536,10 +540,10 @@ /obj/machinery/coffeemaker/impressa/overlay_checks() . = list() if(coffeepot) - if(coffeepot.reagents.total_volume > 0) - . += "pot_full" + if(istype(coffeepot, /obj/item/reagent_containers/cup/coffeepot/bluespace)) + . += "pot_bluespace" else - . += "pot_empty" + . += "pot_[coffeepot.reagents.total_volume ? "full" : "empty"]" if(coffee_cups > 0) if(coffee_cups >= max_coffee_cups/3) if(coffee_cups > max_coffee_cups/1.5) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm index 9048964df1c7c..a0f60b1922163 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_martian.dm @@ -67,6 +67,7 @@ /datum/reagent/water = 10, ) result = /obj/item/food/rice_dough + crafting_flags = CRAFT_CHECK_DENSITY category = CAT_MARTIAN /datum/crafting_recipe/food/hurricane_rice diff --git a/code/modules/mining/equipment/kheiral_cuffs.dm b/code/modules/mining/equipment/kheiral_cuffs.dm index 27b3a1c42a70d..0f1e4f12fd84d 100644 --- a/code/modules/mining/equipment/kheiral_cuffs.dm +++ b/code/modules/mining/equipment/kheiral_cuffs.dm @@ -93,7 +93,6 @@ if(isliving(loc)) connect_kheiral_network(loc) -// LEMON AND HERE /obj/item/kheiral_cuffs/worn_overlays(mutable_appearance/standing, isinhands, icon_file) . = ..() if(!isinhands) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm deleted file mode 100644 index 09982715f23c3..0000000000000 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ /dev/null @@ -1,631 +0,0 @@ -/** - * Kinetic Crusher - * - * Lavaland's "Hard Mode" option for players, requiring melee attacks (backstabs even better), - * but allowing you to upgrade it with trophies gained from fighting lavaland monsters, making it - * a good tradeoff and a decent playstyle. - */ -/obj/item/kinetic_crusher - name = "proto-kinetic crusher" - desc = "An early design of the proto-kinetic accelerator, it is little more than a combination of various mining tools cobbled together, \ - forming a high-tech club. While it is an effective mining tool, it did little to aid any but the most skilled and/or \ - suicidal miners against local fauna." - icon = 'icons/obj/mining.dmi' - icon_state = "crusher" - inhand_icon_state = "crusher0" - icon_angle = -45 - lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' - resistance_flags = FIRE_PROOF - force = 0 //You can't hit stuff unless wielded - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK - throwforce = 5 - throw_speed = 4 - armour_penetration = 10 - custom_materials = list(/datum/material/iron=HALF_SHEET_MATERIAL_AMOUNT*1.15, /datum/material/glass=HALF_SHEET_MATERIAL_AMOUNT*2.075) - hitsound = 'sound/items/weapons/bladeslice.ogg' - attack_verb_continuous = list("smashes", "crushes", "cleaves", "chops", "pulps") - attack_verb_simple = list("smash", "crush", "cleave", "chop", "pulp") - sharpness = SHARP_EDGED - actions_types = list(/datum/action/item_action/toggle_light) - obj_flags = UNIQUE_RENAME - light_system = OVERLAY_LIGHT - light_range = 5 - light_power = 1.2 - light_color = "#ffff66" - light_on = FALSE - ///List of all crusher trophies attached to this. - var/list/obj/item/crusher_trophy/trophies = list() - var/charged = TRUE - var/charge_time = 1.5 SECONDS - var/detonation_damage = 50 - var/backstab_bonus = 30 - var/current_inhand_icon_state = "crusher" //variable used by retool kits when changing the crusher's appearance - var/projectile_icon = "pulse1" //variable used by retool kits when changing the crusher's projectile sprite - -/obj/item/kinetic_crusher/Initialize(mapload) - . = ..() - AddComponent(/datum/component/butchering, \ - speed = 6 SECONDS, \ - effectiveness = 110, \ - ) - //technically it's huge and bulky, but this provides an incentive to use it - AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20) - register_context() - -/obj/item/kinetic_crusher/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - if(!held_item) - context[SCREENTIP_CONTEXT_RMB] = "Detach trophy" - return CONTEXTUAL_SCREENTIP_SET - - if(istype(held_item) && held_item.tool_behaviour == TOOL_CROWBAR) - context[SCREENTIP_CONTEXT_LMB] = "Detach all trophies" - return CONTEXTUAL_SCREENTIP_SET - -/obj/item/kinetic_crusher/Destroy() - QDEL_LIST(trophies) - return ..() - -/obj/item/kinetic_crusher/Exited(atom/movable/gone, direction) - . = ..() - trophies -= gone - -/obj/item/kinetic_crusher/examine(mob/living/user) - . = ..() - . += span_notice("Mark a large creature with a destabilizing force with right-click, then hit them in melee to do [force + detonation_damage] damage.") - . += span_notice("Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].") - for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) - . += span_notice("It has \a [crusher_trophy] attached, which causes [crusher_trophy.effect_desc()].") - -/obj/item/kinetic_crusher/attackby(obj/item/attacking_item, mob/user, params) - if(istype(attacking_item, /obj/item/crusher_trophy)) - var/obj/item/crusher_trophy/crusher_trophy = attacking_item - crusher_trophy.add_to(src, user) - return - return ..() - -/obj/item/kinetic_crusher/crowbar_act(mob/living/user, obj/item/tool) - . = ..() - if(!LAZYLEN(trophies)) - user.balloon_alert(user, "no trophies!") - return ITEM_INTERACT_BLOCKING - user.balloon_alert(user, "trophies removed") - tool.play_tool_sound(src) - for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) - crusher_trophy.remove_from(src, user) - return ITEM_INTERACT_SUCCESS - -// adapted from kinetic accelerator attack_hand_secodary -/obj/item/kinetic_crusher/attack_hand_secondary(mob/user, list/modifiers) - . = ..() - if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - if(!LAZYLEN(trophies)) - return SECONDARY_ATTACK_CONTINUE_CHAIN - - var/list/display_names = list() - var/list/items = list() - for(var/trophies_length in 1 to length(trophies)) - var/obj/item/crusher_trophy/trophy = trophies[trophies_length] - display_names[trophy.name] = REF(trophy) - var/image/item_image = image(icon = trophy.icon, icon_state = trophy.icon_state) - if(length(trophy.overlays)) - item_image.copy_overlays(trophy) - items["[trophy.name]"] = item_image - - var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE, tooltips = TRUE) - if(!pick) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - - var/trophy_reference = display_names[pick] - var/obj/item/crusher_trophy/trophy_to_remove = locate(trophy_reference) in trophies - if(!istype(trophy_to_remove)) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - trophy_to_remove.remove_from(src, user) - if(!user.put_in_hands(trophy_to_remove)) - trophy_to_remove.forceMove(drop_location()) - - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - -/obj/item/kinetic_crusher/proc/check_menu(mob/living/carbon/human/user) - if(!istype(user)) - return FALSE - if(user.incapacitated) - return FALSE - return TRUE - -/obj/item/kinetic_crusher/pre_attack(atom/A, mob/living/user, params) - . = ..() - if(.) - return TRUE - if(!HAS_TRAIT(src, TRAIT_WIELDED)) - user.balloon_alert(user, "must be wielded!") - return TRUE - return . - -/obj/item/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) - target.apply_status_effect(/datum/status_effect/crusher_damage) - return ..() - -/obj/item/kinetic_crusher/afterattack(mob/living/target, mob/living/user, clickparams) - if(!isliving(target)) - return - // Melee effect - for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) - crusher_trophy.on_melee_hit(target, user) - if(QDELETED(target)) - return - var/datum/status_effect/crusher_mark/mark = target.has_status_effect(/datum/status_effect/crusher_mark) - var/boosted_mark = mark?.boosted - if(!target.remove_status_effect(mark)) - return - // Detonation effect - var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(/datum/status_effect/crusher_damage) || target.apply_status_effect(/datum/status_effect/crusher_damage) - var/target_health = target.health - for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) - crusher_trophy.on_mark_detonation(target, user) - if(QDELETED(target)) - return - if(!QDELETED(crusher_damage_effect)) - crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did - new /obj/effect/temp_visual/kinetic_blast(get_turf(target)) - var/backstabbed = FALSE - var/combined_damage = detonation_damage - var/def_check = target.getarmor(type = BOMB) - // Backstab bonus - if(check_behind(user, target) || boosted_mark) - backstabbed = TRUE - combined_damage += backstab_bonus - playsound(user, 'sound/items/weapons/kinetic_accel.ogg', 100, TRUE) //Seriously who spelled it wrong - if(!QDELETED(crusher_damage_effect)) - crusher_damage_effect.total_damage += combined_damage - SEND_SIGNAL(user, COMSIG_LIVING_CRUSHER_DETONATE, target, src, backstabbed) - target.apply_damage(combined_damage, BRUTE, blocked = def_check) - -/obj/item/kinetic_crusher/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) - if(!HAS_TRAIT(src, TRAIT_WIELDED)) - balloon_alert(user, "wield it first!") - return ITEM_INTERACT_BLOCKING - if(interacting_with == user) - balloon_alert(user, "can't aim at yourself!") - return ITEM_INTERACT_BLOCKING - fire_kinetic_blast(interacting_with, user, modifiers) - user.changeNext_move(CLICK_CD_MELEE) - return ITEM_INTERACT_SUCCESS - -/obj/item/kinetic_crusher/ranged_interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) - return interact_with_atom_secondary(interacting_with, user, modifiers) - -/obj/item/kinetic_crusher/proc/fire_kinetic_blast(atom/target, mob/living/user, list/modifiers) - if(!charged) - return - var/turf/proj_turf = user.loc - if(!isturf(proj_turf)) - return - var/obj/projectile/destabilizer/destabilizer = new(proj_turf) - destabilizer.icon_state = "[projectile_icon]" - for(var/obj/item/crusher_trophy/attached_trophy as anything in trophies) - attached_trophy.on_projectile_fire(destabilizer, user) - destabilizer.aim_projectile(target, user, modifiers) - destabilizer.firer = user - playsound(user, 'sound/items/weapons/plasma_cutter.ogg', 100, TRUE) - destabilizer.fire() - charged = FALSE - update_appearance() - addtimer(CALLBACK(src, PROC_REF(recharge_projectile)), charge_time) - -/obj/item/kinetic_crusher/proc/recharge_projectile() - if(!charged) - charged = TRUE - update_appearance() - playsound(src.loc, 'sound/items/weapons/kinetic_reload.ogg', 60, TRUE) - -/obj/item/kinetic_crusher/ui_action_click(mob/user, actiontype) - set_light_on(!light_on) - playsound(user, 'sound/items/weapons/empty.ogg', 100, TRUE) - update_appearance() - -/obj/item/kinetic_crusher/on_saboteur(datum/source, disrupt_duration) - . = ..() - set_light_on(FALSE) - playsound(src, 'sound/items/weapons/empty.ogg', 100, TRUE) - return TRUE - -/obj/item/kinetic_crusher/update_icon_state() - inhand_icon_state = "[current_inhand_icon_state][HAS_TRAIT(src, TRAIT_WIELDED)]" // this is not icon_state and not supported by 2hcomponent - return ..() - -/obj/item/kinetic_crusher/update_overlays() - . = ..() - if(!charged) - . += "[icon_state]_uncharged" - if(light_on) - . += "[icon_state]_lit" - -/obj/item/kinetic_crusher/compact //for admins - name = "compact kinetic crusher" - w_class = WEIGHT_CLASS_NORMAL - -//destablizing force -/obj/projectile/destabilizer - name = "destabilizing force" - damage = 0 //We're just here to mark people. This is still a melee weapon. - damage_type = BRUTE - armor_flag = BOMB - range = 6 - log_override = TRUE - /// Has this projectile been boosted - var/boosted = FALSE - -/obj/projectile/destabilizer/Initialize(mapload) - . = ..() - AddComponent(/datum/component/parriable_projectile, parry_callback = CALLBACK(src, PROC_REF(on_parry))) - -/obj/projectile/destabilizer/proc/on_parry(mob/user) - SIGNAL_HANDLER - boosted = TRUE - // Get a bit of a damage/range boost after being parried - damage = 10 - range = 9 - -/obj/projectile/destabilizer/on_hit(atom/target, blocked = 0, pierce_hit) - if(isliving(target)) - var/mob/living/living_target = target - living_target.apply_status_effect(/datum/status_effect/crusher_mark, boosted) - var/target_turf = get_turf(target) - if(ismineralturf(target_turf)) - var/turf/closed/mineral/hit_mineral = target_turf - new /obj/effect/temp_visual/kinetic_blast(hit_mineral) - hit_mineral.gets_drilled(firer) - return ..() - -//trophies -/obj/item/crusher_trophy - name = "tail spike" - desc = "A strange spike with no usage." - icon = 'icons/obj/mining_zones/artefacts.dmi' - icon_state = "tail_spike" - var/bonus_value = 10 //if it has a bonus effect, this is how much that effect is - var/denied_type = /obj/item/crusher_trophy - -/obj/item/crusher_trophy/examine(mob/living/user) - . = ..() - . += span_notice("Causes [effect_desc()] when attached to a kinetic crusher.") - -/obj/item/crusher_trophy/proc/effect_desc() - return "errors" - -/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user) - if(istype(A, /obj/item/kinetic_crusher)) - add_to(A, user) - else - ..() - -/obj/item/crusher_trophy/proc/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) - for(var/obj/item/crusher_trophy/trophy as anything in crusher.trophies) - if(istype(trophy, denied_type) || istype(src, trophy.denied_type)) - to_chat(user, span_warning("You can't seem to attach [src] to [crusher]. Maybe remove a few trophies?")) - return FALSE - if(!user.transferItemToLoc(src, crusher)) - return - crusher.trophies += src - to_chat(user, span_notice("You attach [src] to [crusher].")) - return TRUE - -/obj/item/crusher_trophy/proc/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) - forceMove(get_turf(crusher)) - return TRUE - -/obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user -/obj/item/crusher_trophy/proc/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user -/obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user - -//watcher -/obj/item/crusher_trophy/watcher_wing - name = "watcher wing" - desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." - icon_state = "watcher_wing" - denied_type = /obj/item/crusher_trophy/watcher_wing - bonus_value = 5 - -/obj/item/crusher_trophy/watcher_wing/effect_desc() - return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" - -/obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) - if(ishostile(target)) - var/mob/living/simple_animal/hostile/H = target - if(H.ranged) //briefly delay ranged attacks - if(H.ranged_cooldown >= world.time) - H.ranged_cooldown += bonus_value - else - H.ranged_cooldown = bonus_value + world.time - -//magmawing watcher -/obj/item/crusher_trophy/blaster_tubes/magma_wing - name = "magmawing watcher wing" - desc = "A still-searing wing from a magmawing watcher. Suitable as a trophy for a kinetic crusher." - icon_state = "magma_wing" - gender = NEUTER - bonus_value = 5 - -/obj/item/crusher_trophy/blaster_tubes/magma_wing/effect_desc() - return "mark detonation to make the next destabilizer shot deal [bonus_value] damage" - -/obj/item/crusher_trophy/blaster_tubes/magma_wing/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) - if(deadly_shot) - marker.name = "heated [marker.name]" - marker.icon_state = "lava" - marker.damage = bonus_value - deadly_shot = FALSE - -//icewing watcher -/obj/item/crusher_trophy/watcher_wing/ice_wing - name = "icewing watcher wing" - desc = "A carefully preserved frozen wing from an icewing watcher. Suitable as a trophy for a kinetic crusher." - icon_state = "ice_wing" - bonus_value = 8 - -//legion -/obj/item/crusher_trophy/legion_skull - name = "legion skull" - desc = "A dead and lifeless legion skull. Suitable as a trophy for a kinetic crusher." - icon_state = "legion_skull" - denied_type = /obj/item/crusher_trophy/legion_skull - bonus_value = 3 - -/obj/item/crusher_trophy/legion_skull/effect_desc() - return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster" - -/obj/item/crusher_trophy/legion_skull/add_to(obj/item/kinetic_crusher/pkc, mob/living/user) - . = ..() - if(.) - pkc.charge_time -= bonus_value - -/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/kinetic_crusher/pkc, mob/living/user) - . = ..() - if(.) - pkc.charge_time += bonus_value - -//blood-drunk hunter -/obj/item/crusher_trophy/miner_eye - name = "eye of a blood-drunk hunter" - desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher." - icon_state = "hunter_eye" - denied_type = /obj/item/crusher_trophy/miner_eye - -/obj/item/crusher_trophy/miner_eye/effect_desc() - return "mark detonation to grant stun immunity and 90% damage reduction for 1 second" - -/obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user) - user.apply_status_effect(/datum/status_effect/blooddrunk) - -//ash drake -/obj/item/crusher_trophy/tail_spike - desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher." - denied_type = /obj/item/crusher_trophy/tail_spike - bonus_value = 5 - -/obj/item/crusher_trophy/tail_spike/effect_desc() - return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" - -/obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) - for(var/mob/living/living_target in oview(2, user)) - if(user.faction_check_atom(living_target) || living_target.stat == DEAD) - continue - playsound(living_target, 'sound/effects/magic/fireball.ogg', 20, TRUE) - new /obj/effect/temp_visual/fire(living_target.loc) - addtimer(CALLBACK(src, PROC_REF(pushback), living_target, user), 1) //no free backstabs, we push AFTER module stuff is done - living_target.adjustFireLoss(bonus_value, forced = TRUE) - -/obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user) - if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed - step(target, get_dir(user, target)) - -//bubblegum -/obj/item/crusher_trophy/demon_claws - name = "demon claws" - desc = "A set of blood-drenched claws from a massive demon's hand. Suitable as a trophy for a kinetic crusher." - icon_state = "demon_claws" - gender = PLURAL - denied_type = /obj/item/crusher_trophy/demon_claws - bonus_value = 10 - var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) - -/obj/item/crusher_trophy/demon_claws/effect_desc() - return "melee hits to do [bonus_value * 0.2] more damage and heal you for [bonus_value * 0.1], with 5X effect on mark detonation" - -/obj/item/crusher_trophy/demon_claws/add_to(obj/item/kinetic_crusher/pkc, mob/living/user) - . = ..() - if(.) - pkc.force += bonus_value * 0.2 - pkc.detonation_damage += bonus_value * 0.8 - AddComponent(/datum/component/two_handed, force_wielded=(20 + bonus_value * 0.2)) - -/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/kinetic_crusher/pkc, mob/living/user) - . = ..() - if(.) - pkc.force -= bonus_value * 0.2 - pkc.detonation_damage -= bonus_value * 0.8 - AddComponent(/datum/component/two_handed, force_wielded=20) - -/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user) - user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order) - -/obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user) - user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order) - -//colossus -/obj/item/crusher_trophy/blaster_tubes - name = "blaster tubes" - desc = "The blaster tubes from a colossus's arm. Suitable as a trophy for a kinetic crusher." - icon_state = "blaster_tubes" - gender = PLURAL - denied_type = /obj/item/crusher_trophy/blaster_tubes - bonus_value = 15 - var/deadly_shot = FALSE - -/obj/item/crusher_trophy/blaster_tubes/effect_desc() - return "mark detonation to make the next destabilizer shot deal [bonus_value] damage but move slower" - -/obj/item/crusher_trophy/blaster_tubes/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) - if(deadly_shot) - marker.name = "deadly [marker.name]" - marker.icon_state = "chronobolt" - marker.damage = bonus_value - marker.speed = 0.5 - deadly_shot = FALSE - -/obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user) - deadly_shot = TRUE - addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE) - -/obj/item/crusher_trophy/blaster_tubes/proc/reset_deadly_shot() - deadly_shot = FALSE - -//hierophant -/obj/item/crusher_trophy/vortex_talisman - name = "vortex talisman" - desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher." - icon_state = "vortex_talisman" - denied_type = /obj/item/crusher_trophy/vortex_talisman - -/obj/item/crusher_trophy/vortex_talisman/effect_desc() - return "mark detonation to create a homing hierophant chaser" - -/obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user) - if(isliving(target)) - var/obj/effect/temp_visual/hierophant/chaser/chaser = new(get_turf(user), user, target, 3, TRUE) - chaser.monster_damage_boost = FALSE // Weaker cuz no cooldown - chaser.damage = 20 - log_combat(user, target, "fired a chaser at", src) - -/obj/item/crusher_trophy/ice_demon_cube - name = "demonic cube" - desc = "A stone cold cube dropped from an ice demon." - icon_state = "ice_demon_cube" - denied_type = /obj/item/crusher_trophy/ice_demon_cube - ///how many will we summon? - var/summon_amount = 2 - ///cooldown to summon demons upon the target - COOLDOWN_DECLARE(summon_cooldown) - -/obj/item/crusher_trophy/ice_demon_cube/effect_desc() - return "mark detonation to unleash demonic ice clones upon the target" - -/obj/item/crusher_trophy/ice_demon_cube/on_mark_detonation(mob/living/target, mob/living/user) - if(isnull(target) || !COOLDOWN_FINISHED(src, summon_cooldown)) - return - for(var/i in 1 to summon_amount) - var/turf/drop_off = find_dropoff_turf(target, user) - var/mob/living/basic/mining/demon_afterimage/crusher/friend = new(drop_off) - friend.faction = list(FACTION_NEUTRAL) - friend.befriend(user) - friend.ai_controller?.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, target) - COOLDOWN_START(src, summon_cooldown, 30 SECONDS) - -///try to make them spawn all around the target to surround him -/obj/item/crusher_trophy/ice_demon_cube/proc/find_dropoff_turf(mob/living/target, mob/living/user) - var/list/turfs_list = get_adjacent_open_turfs(target) - for(var/turf/possible_turf in turfs_list) - if(possible_turf.is_blocked_turf()) - continue - return possible_turf - return get_turf(user) - -//wolf trophy - -/obj/item/crusher_trophy/wolf_ear - name = "wolf ear" - desc = "It's a wolf ear." - icon_state = "wolf_ear" - denied_type = /obj/item/crusher_trophy/wolf_ear - -/obj/item/crusher_trophy/wolf_ear/effect_desc() - return "mark detonation to gain a slight speed boost temporarily" - -/obj/item/crusher_trophy/wolf_ear/on_mark_detonation(mob/living/target, mob/living/user) - user.apply_status_effect(/datum/status_effect/speed_boost, 1 SECONDS) - -//cosmetic items for changing the crusher's look - -/obj/item/crusher_trophy/retool_kit - name = "crusher sword retool kit" - desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a sword." - icon = 'icons/obj/mining.dmi' - icon_state = "retool_kit" - denied_type = /obj/item/crusher_trophy/retool_kit - ///Specifies the sprite/icon state which the crusher is changed to as an item. Should appear in the icons/obj/mining.dmi file with accompanying "lit" and "recharging" sprites - var/retool_icon = "crusher_sword" - ///Specifies the icon state for the crusher's appearance in hand. Should appear in both icons/mob/inhands/weapons/hammers_lefthand.dmi and icons/mob/inhands/weapons/hammers_righthand.dmi - var/retool_inhand_icon = "crusher_sword" - ///For if the retool kit changes the projectile's appearance. The sprite should be in icons/obj/weapons/guns/projectiles.dmi - var/retool_projectile_icon = "pulse1" - -/obj/item/crusher_trophy/retool_kit/effect_desc() - return "the crusher to have the appearance of a sword" - -/obj/item/crusher_trophy/retool_kit/add_to(obj/item/kinetic_crusher/pkc, mob/user) - . = ..() - if(.) - pkc.icon_state = retool_icon - pkc.current_inhand_icon_state = retool_inhand_icon - pkc.projectile_icon = retool_projectile_icon - if(iscarbon(pkc.loc)) - var/mob/living/carbon/holder = pkc.loc - holder.update_worn_back() - holder.update_suit_storage() - holder.update_held_items() - pkc.update_appearance() - -/obj/item/crusher_trophy/retool_kit/remove_from(obj/item/kinetic_crusher/pkc) - pkc.icon_state = initial(pkc.icon_state) - pkc.current_inhand_icon_state = initial(pkc.current_inhand_icon_state) - pkc.projectile_icon = initial(pkc.projectile_icon) - if(iscarbon(pkc.loc)) - var/mob/living/carbon/holder = pkc.loc - holder.update_worn_back() - holder.update_suit_storage() - holder.update_held_items() - pkc.update_appearance() - ..() - -/obj/item/crusher_trophy/retool_kit/harpoon - name = "crusher harpoon retool kit" - desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a harpoon." - icon = 'icons/obj/mining.dmi' - icon_state = "retool_kit" - denied_type = /obj/item/crusher_trophy/retool_kit - retool_icon = "crusher_harpoon" - retool_inhand_icon = "crusher_harpoon" - retool_projectile_icon = "pulse_harpoon" - -/obj/item/crusher_trophy/retool_kit/harpoon/effect_desc() - return "the crusher to have the appearance of a harpoon" - -/obj/item/crusher_trophy/retool_kit/dagger - name = "crusher dagger retool kit" - desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a dual dagger and mini-blaster on a chain." - icon = 'icons/obj/mining.dmi' - icon_state = "retool_kit" - denied_type = /obj/item/crusher_trophy/retool_kit - retool_icon = "crusher_dagger" - retool_inhand_icon = "crusher_dagger" - -/obj/item/crusher_trophy/retool_kit/dagger/effect_desc() - return "the crusher to have the appearance of a dual dagger and blaster" - -/obj/item/crusher_trophy/retool_kit/ashenskull - name = "ashen skull" - desc = "It burns with the flame of the necropolis, whispering in your ear. It demands to be bound to a suitable weapon." - icon = 'icons/obj/mining.dmi' - icon_state = "retool_kit_skull" - denied_type = /obj/item/crusher_trophy/retool_kit - retool_icon = "crusher_skull" - retool_inhand_icon = "crusher_skull" - retool_projectile_icon = "pulse_skull" - -/obj/item/crusher_trophy/retool_kit/ashenskull/effect_desc() - return "the crusher to appear corrupted by infernal powers" diff --git a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm new file mode 100644 index 0000000000000..871dbc6eccacc --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm @@ -0,0 +1,329 @@ +/** + * Kinetic Crusher + * + * Lavaland's "Hard Mode" option for players, requiring melee attacks (backstabs even better), + * but allowing you to upgrade it with trophies gained from fighting lavaland monsters, making it + * a good tradeoff and a decent playstyle. + */ +/obj/item/kinetic_crusher + name = "proto-kinetic crusher" + desc = "An early design of the proto-kinetic accelerator, it is little more than a combination of various mining tools cobbled together, \ + forming a high-tech club. While it is an effective mining tool, it did little to aid any but the most skilled and/or \ + suicidal miners against local fauna." + icon = 'icons/obj/mining.dmi' + icon_state = "crusher" + inhand_icon_state = "crusher0" + icon_angle = -45 + lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi' + resistance_flags = FIRE_PROOF + force = 0 //You can't hit stuff unless wielded + w_class = WEIGHT_CLASS_BULKY + slot_flags = ITEM_SLOT_BACK + throwforce = 5 + throw_speed = 4 + armour_penetration = 10 + custom_materials = list(/datum/material/iron=HALF_SHEET_MATERIAL_AMOUNT*1.15, /datum/material/glass=HALF_SHEET_MATERIAL_AMOUNT*2.075) + hitsound = 'sound/items/weapons/bladeslice.ogg' + attack_verb_continuous = list("smashes", "crushes", "cleaves", "chops", "pulps") + attack_verb_simple = list("smash", "crush", "cleave", "chop", "pulp") + sharpness = SHARP_EDGED + actions_types = list(/datum/action/item_action/toggle_light) + obj_flags = UNIQUE_RENAME + light_system = OVERLAY_LIGHT + light_range = 5 + light_power = 1.2 + light_color = "#ffff66" + light_on = FALSE + /// List of all crusher trophies attached to this. + var/list/obj/item/crusher_trophy/trophies = list() + /// If our crusher is ready to fire a projectile (FALSE means it's on cooldown) + var/charged = TRUE + /// How long before our crusher will recharge by default + var/charge_time = 1.5 SECONDS + /// Timer before our crusher recharges + var/charge_timer + /// Damage that the mark does when hit by the crusher + var/detonation_damage = 50 + /// Damage that the mark additionally does when hit by the crusher via backstab + var/backstab_bonus = 30 + /// Used by retool kits when changing the crusher's appearance + var/current_inhand_icon_state = "crusher" + /// Used by retool kits when changing the crusher's projectile sprite + var/projectile_icon = "pulse1" + +/obj/item/kinetic_crusher/Initialize(mapload) + . = ..() + AddComponent(/datum/component/butchering, \ + speed = 6 SECONDS, \ + effectiveness = 110, \ + ) + //technically it's huge and bulky, but this provides an incentive to use it + AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20) + register_context() + +/obj/item/kinetic_crusher/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(!held_item) + context[SCREENTIP_CONTEXT_RMB] = "Detach trophy" + return CONTEXTUAL_SCREENTIP_SET + + if(istype(held_item) && held_item.tool_behaviour == TOOL_CROWBAR) + context[SCREENTIP_CONTEXT_LMB] = "Detach all trophies" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/kinetic_crusher/Destroy() + QDEL_LIST(trophies) + return ..() + +/obj/item/kinetic_crusher/Exited(atom/movable/gone, direction) + . = ..() + trophies -= gone + +/obj/item/kinetic_crusher/examine(mob/living/user) + . = ..() + . += span_notice("Mark a large creature with a destabilizing force with right-click, then hit them in melee to do [force + detonation_damage] damage.") + . += span_notice("Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].") + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + . += span_notice("It has \a [crusher_trophy] attached, which causes [crusher_trophy.effect_desc()].") + +/obj/item/kinetic_crusher/attackby(obj/item/attacking_item, mob/user, params) + if(istype(attacking_item, /obj/item/crusher_trophy)) + var/obj/item/crusher_trophy/crusher_trophy = attacking_item + crusher_trophy.add_to(src, user) + return + return ..() + +/obj/item/kinetic_crusher/crowbar_act(mob/living/user, obj/item/tool) + . = ..() + if(!LAZYLEN(trophies)) + user.balloon_alert(user, "no trophies!") + return ITEM_INTERACT_BLOCKING + user.balloon_alert(user, "trophies removed") + tool.play_tool_sound(src) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.remove_from(src, user) + return ITEM_INTERACT_SUCCESS + +// adapted from kinetic accelerator attack_hand_secodary +/obj/item/kinetic_crusher/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(!LAZYLEN(trophies)) + return SECONDARY_ATTACK_CONTINUE_CHAIN + + var/list/display_names = list() + var/list/items = list() + for(var/trophies_length in 1 to length(trophies)) + var/obj/item/crusher_trophy/trophy = trophies[trophies_length] + display_names[trophy.name] = REF(trophy) + var/image/item_image = image(icon = trophy.icon, icon_state = trophy.icon_state) + if(length(trophy.overlays)) + item_image.copy_overlays(trophy) + items["[trophy.name]"] = item_image + + var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE, tooltips = TRUE) + if(!pick) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/trophy_reference = display_names[pick] + var/obj/item/crusher_trophy/trophy_to_remove = locate(trophy_reference) in trophies + if(!istype(trophy_to_remove)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + trophy_to_remove.remove_from(src, user) + if(!user.put_in_hands(trophy_to_remove)) + trophy_to_remove.forceMove(drop_location()) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/kinetic_crusher/proc/check_menu(mob/living/carbon/human/user) + if(!istype(user)) + return FALSE + if(user.incapacitated) + return FALSE + return TRUE + +/obj/item/kinetic_crusher/pre_attack(atom/A, mob/living/user, params) + . = ..() + if(.) + return TRUE + if(!HAS_TRAIT(src, TRAIT_WIELDED)) + user.balloon_alert(user, "must be wielded!") + return TRUE + return . + +/obj/item/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) + target.apply_status_effect(/datum/status_effect/crusher_damage) + return ..() + +/obj/item/kinetic_crusher/afterattack(mob/living/target, mob/living/user, clickparams) + if(!isliving(target)) + return + // Melee effect + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.on_melee_hit(target, user) + if(QDELETED(target)) + return + var/datum/status_effect/crusher_mark/mark = target.has_status_effect(/datum/status_effect/crusher_mark) + var/boosted_mark = mark?.boosted + if(world.time < mark.mark_applied + mark.ready_delay) // Simple way to prevent right+left click at the same time to detonate the mark for free + return + if(!target.remove_status_effect(mark)) + return + // Detonation effect + var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(/datum/status_effect/crusher_damage) || target.apply_status_effect(/datum/status_effect/crusher_damage) + var/target_health = target.health + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.on_mark_detonation(target, user) + if(QDELETED(target)) + return + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + new /obj/effect/temp_visual/kinetic_blast(get_turf(target)) + var/backstabbed = FALSE + var/combined_damage = detonation_damage + var/def_check = target.getarmor(type = BOMB) + // Backstab bonus + if(check_behind(user, target) || boosted_mark) + backstabbed = TRUE + combined_damage += backstab_bonus + playsound(user, 'sound/items/weapons/kinetic_accel.ogg', 100, TRUE) //Seriously who spelled it wrong + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += combined_damage + SEND_SIGNAL(user, COMSIG_LIVING_CRUSHER_DETONATE, target, src, backstabbed) + target.apply_damage(combined_damage, BRUTE, blocked = def_check) + +/obj/item/kinetic_crusher/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) + if(!HAS_TRAIT(src, TRAIT_WIELDED)) + balloon_alert(user, "wield it first!") + return ITEM_INTERACT_BLOCKING + if(interacting_with == user) + balloon_alert(user, "can't aim at yourself!") + return ITEM_INTERACT_BLOCKING + fire_kinetic_blast(interacting_with, user, modifiers) + return ITEM_INTERACT_SUCCESS + +/obj/item/kinetic_crusher/ranged_interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) + return interact_with_atom_secondary(interacting_with, user, modifiers) + +/obj/item/kinetic_crusher/proc/fire_kinetic_blast(atom/target, mob/living/user, list/modifiers) + if(!charged) + return + var/turf/proj_turf = user.loc + if(!isturf(proj_turf)) + return + var/obj/projectile/destabilizer/destabilizer = new(proj_turf) + destabilizer.icon_state = "[projectile_icon]" + for(var/obj/item/crusher_trophy/attached_trophy as anything in trophies) + attached_trophy.on_projectile_fire(destabilizer, user) + destabilizer.aim_projectile(target, user, modifiers) + destabilizer.firer = user + destabilizer.fired_from = src + playsound(user, 'sound/items/weapons/plasma_cutter.ogg', 100, TRUE) + destabilizer.fire() + charged = FALSE + update_appearance() + attempt_recharge_projectile() + +/// Handles the timer for reloading the projectile +/obj/item/kinetic_crusher/proc/attempt_recharge_projectile(set_recharge_time) + if(!set_recharge_time) + set_recharge_time = charge_time + deltimer(charge_timer) + charge_timer = addtimer(CALLBACK(src, PROC_REF(recharge_projectile)), set_recharge_time, TIMER_STOPPABLE) + +/// Recharges the projectile +/obj/item/kinetic_crusher/proc/recharge_projectile() + if(!charged) + charged = TRUE + update_appearance() + playsound(src.loc, 'sound/items/weapons/kinetic_reload.ogg', 60, TRUE) + +/obj/item/kinetic_crusher/ui_action_click(mob/user, actiontype) + set_light_on(!light_on) + playsound(user, 'sound/items/weapons/empty.ogg', 100, TRUE) + update_appearance() + +/obj/item/kinetic_crusher/on_saboteur(datum/source, disrupt_duration) + . = ..() + set_light_on(FALSE) + playsound(src, 'sound/items/weapons/empty.ogg', 100, TRUE) + return TRUE + +/obj/item/kinetic_crusher/update_icon_state() + inhand_icon_state = "[current_inhand_icon_state][HAS_TRAIT(src, TRAIT_WIELDED)]" // this is not icon_state and not supported by 2hcomponent + return ..() + +/obj/item/kinetic_crusher/update_overlays() + . = ..() + if(!charged) + . += "[icon_state]_uncharged" + if(light_on) + . += "[icon_state]_lit" + +/obj/item/kinetic_crusher/compact //for admins + name = "compact kinetic crusher" + w_class = WEIGHT_CLASS_NORMAL + +//destablizing force +/obj/projectile/destabilizer + name = "destabilizing force" + damage = 0 //We're just here to mark people. This is still a melee weapon. + damage_type = BRUTE + armor_flag = BOMB + range = 6 + log_override = TRUE + /// Has this projectile been boosted + var/boosted = FALSE + +/obj/projectile/destabilizer/Initialize(mapload) + . = ..() + AddComponent(/datum/component/parriable_projectile, parry_callback = CALLBACK(src, PROC_REF(on_parry))) + +/obj/projectile/destabilizer/Destroy() + fired_from = null + return ..() + +/obj/projectile/destabilizer/proc/on_parry(mob/user) + SIGNAL_HANDLER + boosted = TRUE + // Get a bit of a damage/range boost after being parried + damage = 10 + range = 9 + +/obj/projectile/destabilizer/on_hit(atom/target, blocked = 0, pierce_hit) + var/obj/item/kinetic_crusher/used_crusher + if(istype(fired_from, /obj/item/kinetic_crusher)) + used_crusher = fired_from + + if(isliving(target)) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in used_crusher?.trophies) + crusher_trophy.on_projectile_hit_mob(target, firer) + if(QDELETED(target)) + return ..() + var/mob/living/living_target = target + living_target.apply_status_effect(/datum/status_effect/crusher_mark, boosted) + return ..() + + var/target_turf = get_turf(target) + if(ismineralturf(target_turf)) + var/turf/closed/mineral/hit_mineral = target_turf + for(var/obj/item/crusher_trophy/crusher_trophy as anything in used_crusher?.trophies) + crusher_trophy.on_projectile_hit_mineral(hit_mineral, firer) + if(QDELETED(hit_mineral)) + return ..() + new /obj/effect/temp_visual/kinetic_blast(hit_mineral) + hit_mineral.gets_drilled(firer, TRUE) + if(!iscarbon(firer)) + return ..() + var/mob/living/carbon/carbon_firer = firer + var/skill_modifier = 1 + // If there is a mind, check for skill modifier to allow them to reload faster. + if(carbon_firer.mind && used_crusher) + skill_modifier = carbon_firer.mind.get_skill_modifier(/datum/skill/mining, SKILL_SPEED_MODIFIER) + used_crusher.attempt_recharge_projectile(used_crusher.charge_time * skill_modifier) //If you hit a mineral, you might get a quicker reload. epic gamer style. + + return ..() + diff --git a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm new file mode 100644 index 0000000000000..6a00423206e00 --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher_trophies.dm @@ -0,0 +1,63 @@ +/*! + * Contains the baseline of kinetic crusher trophies. + */ + +/obj/item/crusher_trophy + name = "tail spike" + desc = "A strange spike with no usage." + icon = 'icons/obj/mining_zones/artefacts.dmi' + icon_state = "tail_spike" + /// if it has a bonus effect, this is how much that effect is + var/bonus_value = 10 + /// what type of trophies will block this trophy from being added, must be overriden + var/denied_type = /obj/item/crusher_trophy + +/obj/item/crusher_trophy/examine(mob/living/user) + . = ..() + . += span_notice("Causes [effect_desc()] when attached to a kinetic crusher.") + +/// Returns a string to get added to the examine +/obj/item/crusher_trophy/proc/effect_desc() + SHOULD_CALL_PARENT(FALSE) + return "errors" + +/obj/item/crusher_trophy/attackby(obj/item/attacking_item, mob/living/user) + if(!istype(attacking_item, /obj/item/kinetic_crusher)) + return ..() + add_to(attacking_item, user) + +/// Tries to add the trophy to our crusher +/obj/item/crusher_trophy/proc/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) + for(var/obj/item/crusher_trophy/trophy as anything in crusher.trophies) + if(istype(trophy, denied_type) || istype(src, trophy.denied_type)) + to_chat(user, span_warning("You can't seem to attach [src] to [crusher]. Maybe remove a few trophies?")) + return FALSE + if(!user.transferItemToLoc(src, crusher)) + return + crusher.trophies += src + to_chat(user, span_notice("You attach [src] to [crusher].")) + return TRUE + +/// Removes the trophy from our crusher +/obj/item/crusher_trophy/proc/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) + forceMove(get_turf(crusher)) + return TRUE + +/// Does an effect when you hit a mob with a crusher +/obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user + return + +/obj/item/crusher_trophy/proc/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user + return + +/// Does an effect when you hit a mob with the projectile +/obj/item/crusher_trophy/proc/on_projectile_hit_mob(mob/living/target, mob/living/user) //the target and the user + return + +/// Does an effect when you hit a mineral turf with the projectile +/obj/item/crusher_trophy/proc/on_projectile_hit_mineral(turf/closed/mineral, mob/living/user) //the target and the user + return + +/// Does an effect when you hit a mob that is marked via the projectile +/obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user + return diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm new file mode 100644 index 0000000000000..2327980a98335 --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm @@ -0,0 +1,241 @@ +/*! + * Contains crusher trophies you can obtain from regular fauna + */ + +//watcher +/obj/item/crusher_trophy/watcher_wing + name = "watcher wing" + desc = "A wing ripped from a watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "watcher_wing" + denied_type = /obj/item/crusher_trophy/watcher_wing + bonus_value = 5 + +/obj/item/crusher_trophy/watcher_wing/effect_desc() + return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" + +/obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) + if(ishostile(target)) + var/mob/living/simple_animal/hostile/H = target + if(H.ranged) //briefly delay ranged attacks + if(H.ranged_cooldown >= world.time) + H.ranged_cooldown += bonus_value + else + H.ranged_cooldown = bonus_value + world.time + +//magmawing watcher +/obj/item/crusher_trophy/blaster_tubes/magma_wing + name = "magmawing watcher wing" + desc = "A still-searing wing from a magmawing watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "magma_wing" + gender = NEUTER + bonus_value = 5 + +/obj/item/crusher_trophy/blaster_tubes/magma_wing/effect_desc() + return "mark detonation to make the next destabilizer shot deal [bonus_value] damage" + +/obj/item/crusher_trophy/blaster_tubes/magma_wing/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) + if(deadly_shot) + marker.name = "heated [marker.name]" + marker.icon_state = "lava" + marker.damage = bonus_value + deadly_shot = FALSE + +//icewing watcher +/obj/item/crusher_trophy/watcher_wing/ice_wing + name = "icewing watcher wing" + desc = "A carefully preserved frozen wing from an icewing watcher. Suitable as a trophy for a kinetic crusher." + icon_state = "ice_wing" + bonus_value = 8 + +//legion +/obj/item/crusher_trophy/legion_skull + name = "legion skull" + desc = "A dead and lifeless legion skull. Suitable as a trophy for a kinetic crusher." + icon_state = "legion_skull" + denied_type = /obj/item/crusher_trophy/legion_skull + bonus_value = 3 + +/obj/item/crusher_trophy/legion_skull/effect_desc() + return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster" + +/obj/item/crusher_trophy/legion_skull/add_to(obj/item/kinetic_crusher/pkc, mob/living/user) + . = ..() + if(.) + pkc.charge_time -= bonus_value + +/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/kinetic_crusher/pkc, mob/living/user) + . = ..() + if(.) + pkc.charge_time += bonus_value + +// Goliath - Increases damage as your health decreases. +/obj/item/crusher_trophy/goliath_tentacle + name = "goliath tentacle" + desc = "A sliced-off goliath tentacle. Suitable as a trophy for a kinetic crusher." + icon_state = "goliath_tentacle" + denied_type = /obj/item/crusher_trophy/goliath_tentacle + bonus_value = 2 + /// Your missing health is multiplied by this value to find the bonus damage + var/missing_health_ratio = 0.1 + /// Amount of health you must lose to gain damage, according to the examine text. Cached so we don't recalculate it every examine. + var/missing_health_desc + +/obj/item/crusher_trophy/goliath_tentacle/Initialize(mapload) + . = ..() + missing_health_desc = 1 / missing_health_ratio / bonus_value + +/obj/item/crusher_trophy/goliath_tentacle/effect_desc() + return "mark detonation to do [bonus_value] more damage for every [missing_health_desc] health you are missing" + +/obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user) + var/missing_health = user.maxHealth - user.health + missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health + missing_health *= bonus_value //multiply the remaining amount by bonus_value + if(missing_health > 0) + target.adjustBruteLoss(missing_health) //and do that much damage + +// Lobstrosity - Rebukes targets, increasing their click cooldown. +/obj/item/crusher_trophy/lobster_claw + name = "lobster claw" + icon_state = "lobster_claw" + desc = "A lobster claw." + denied_type = /obj/item/crusher_trophy/lobster_claw + bonus_value = 1 + +/obj/item/crusher_trophy/lobster_claw/effect_desc() + return "mark detonation to briefly rebuke the target for [bonus_value] seconds" + +/obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user) + target.apply_status_effect(/datum/status_effect/rebuked, bonus_value SECONDS) + +// Brimdemon - makes a funny sound, the most essential trophy out of all +/obj/item/crusher_trophy/brimdemon_fang + name = "brimdemon's fang" + icon_state = "brimdemon_fang" + desc = "A fang from a brimdemon's corpse." + denied_type = /obj/item/crusher_trophy/brimdemon_fang + /// Cartoon punching vfx + var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM") + +/obj/item/crusher_trophy/brimdemon_fang/effect_desc() + return "mark detonation to create visual and audiosensory effects at the target" + +/obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user) + target.balloon_alert_to_viewers("[pick(comic_phrases)]!") + playsound(target, 'sound/mobs/non-humanoids/brimdemon/brimdemon_crush.ogg', 100) + +// Bileworm +/obj/item/crusher_trophy/bileworm_spewlet + name = "bileworm spewlet" + icon = 'icons/mob/simple/lavaland/bileworm.dmi' + icon_state = "bileworm_spewlet" + desc = "A baby bileworm. Suitable as a trophy for a kinetic crusher." + denied_type = /obj/item/crusher_trophy/bileworm_spewlet + ///item ability that handles the effect + var/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet/ability + +/obj/item/crusher_trophy/bileworm_spewlet/Initialize(mapload) + . = ..() + ability = new() + +/obj/item/crusher_trophy/bileworm_spewlet/Destroy(force) + . = ..() + QDEL_NULL(ability) + +/obj/item/crusher_trophy/bileworm_spewlet/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) + . = ..() + if(.) + crusher.add_item_action(ability) + +/obj/item/crusher_trophy/bileworm_spewlet/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) + . = ..() + crusher.remove_item_action(ability) + +/obj/item/crusher_trophy/bileworm_spewlet/effect_desc() + return "mark detonation launches projectiles in cardinal directions on a 10 second cooldown. Also gives you an AOE when mining minerals" + +/obj/item/crusher_trophy/bileworm_spewlet/on_mark_detonation(mob/living/target, mob/living/user) + //ability itself handles cooldowns. + ability.InterceptClickOn(user, null, target) + +/obj/item/crusher_trophy/bileworm_spewlet/on_projectile_hit_mineral(turf/closed/mineral, mob/living/user) + for(var/turf/closed/mineral/mineral_turf in RANGE_TURFS(1, mineral) - mineral) + mineral_turf.gets_drilled(user, TRUE) + +//yes this is a /mob_cooldown subtype being added to an item. I can't recommend you do what I'm doing +/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet + check_flags = NONE + owner_has_control = FALSE + cooldown_time = 10 SECONDS + projectile_type = /obj/projectile/bileworm_acid + projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg' + +/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet/New(Target) + firing_directions = GLOB.cardinals.Copy() + return ..() + +// demonic watcher +/obj/item/crusher_trophy/ice_demon_cube + name = "demonic cube" + desc = "A stone cold cube dropped from an ice demon." + icon_state = "ice_demon_cube" + denied_type = /obj/item/crusher_trophy/ice_demon_cube + ///how many will we summon? + var/summon_amount = 2 + ///cooldown to summon demons upon the target + COOLDOWN_DECLARE(summon_cooldown) + +/obj/item/crusher_trophy/ice_demon_cube/effect_desc() + return "mark detonation to unleash demonic ice clones upon the target" + +/obj/item/crusher_trophy/ice_demon_cube/on_mark_detonation(mob/living/target, mob/living/user) + if(isnull(target) || !COOLDOWN_FINISHED(src, summon_cooldown)) + return + for(var/i in 1 to summon_amount) + var/turf/drop_off = find_dropoff_turf(target, user) + var/mob/living/basic/mining/demon_afterimage/crusher/friend = new(drop_off) + friend.faction = list(FACTION_NEUTRAL) + friend.befriend(user) + friend.ai_controller?.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, target) + COOLDOWN_START(src, summon_cooldown, 30 SECONDS) + +///try to make them spawn all around the target to surround him +/obj/item/crusher_trophy/ice_demon_cube/proc/find_dropoff_turf(mob/living/target, mob/living/user) + var/list/turfs_list = get_adjacent_open_turfs(target) + for(var/turf/possible_turf in turfs_list) + if(possible_turf.is_blocked_turf()) + continue + return possible_turf + return get_turf(user) + +// Wolf + +/obj/item/crusher_trophy/wolf_ear + name = "wolf ear" + desc = "It's a wolf ear." + icon_state = "wolf_ear" + denied_type = /obj/item/crusher_trophy/wolf_ear + +/obj/item/crusher_trophy/wolf_ear/effect_desc() + return "mark detonation to gain a slight speed boost temporarily" + +/obj/item/crusher_trophy/wolf_ear/on_mark_detonation(mob/living/target, mob/living/user) + user.apply_status_effect(/datum/status_effect/speed_boost, 1 SECONDS) + +// Polar bear +/obj/item/crusher_trophy/bear_paw + name = "polar bear paw" + desc = "It's a polar bear paw." + icon_state = "bear_paw" + denied_type = /obj/item/crusher_trophy/bear_paw + +/obj/item/crusher_trophy/bear_paw/effect_desc() + return "mark detonation to attack twice if you are below half your life" + +/obj/item/crusher_trophy/bear_paw/on_mark_detonation(mob/living/target, mob/living/user) + if(user.health / user.maxHealth > 0.5) + return + var/obj/item/I = user.get_active_held_item() + if(!I) + return + I.melee_attack_chain(user, target, null) diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm new file mode 100644 index 0000000000000..ba302999010c7 --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_megafauna.dm @@ -0,0 +1,217 @@ +/*! + * Contains crusher trophies you can obtain from megafauna + */ + +//blood-drunk hunter +/obj/item/crusher_trophy/miner_eye + name = "eye of a blood-drunk hunter" + desc = "Its pupil is collapsed and turned to mush. Suitable as a trophy for a kinetic crusher." + icon_state = "hunter_eye" + denied_type = /obj/item/crusher_trophy/miner_eye + +/obj/item/crusher_trophy/miner_eye/effect_desc() + return "mark detonation to grant stun immunity and 90% damage reduction for 1 second" + +/obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user) + user.apply_status_effect(/datum/status_effect/blooddrunk) + +//ash drake +/obj/item/crusher_trophy/tail_spike + desc = "A spike taken from an ash drake's tail. Suitable as a trophy for a kinetic crusher." + denied_type = /obj/item/crusher_trophy/tail_spike + bonus_value = 5 + +/obj/item/crusher_trophy/tail_spike/effect_desc() + return "mark detonation to do [bonus_value] damage to nearby creatures and push them back" + +/obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user) + for(var/mob/living/living_target in oview(2, user)) + if(user.faction_check_atom(living_target) || living_target.stat == DEAD) + continue + playsound(living_target, 'sound/effects/magic/fireball.ogg', 20, TRUE) + new /obj/effect/temp_visual/fire(living_target.loc) + addtimer(CALLBACK(src, PROC_REF(pushback), living_target, user), 1) //no free backstabs, we push AFTER module stuff is done + living_target.adjustFireLoss(bonus_value, forced = TRUE) + +/obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user) + if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed + step(target, get_dir(user, target)) + +//bubblegum +/obj/item/crusher_trophy/demon_claws + name = "demon claws" + desc = "A set of blood-drenched claws from a massive demon's hand. Suitable as a trophy for a kinetic crusher." + icon_state = "demon_claws" + gender = PLURAL + denied_type = /obj/item/crusher_trophy/demon_claws + bonus_value = 10 + var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) + +/obj/item/crusher_trophy/demon_claws/effect_desc() + return "melee hits to do [bonus_value * 0.2] more damage and heal you for [bonus_value * 0.1], with 5X effect on mark detonation" + +/obj/item/crusher_trophy/demon_claws/add_to(obj/item/kinetic_crusher/pkc, mob/living/user) + . = ..() + if(.) + pkc.force += bonus_value * 0.2 + pkc.detonation_damage += bonus_value * 0.8 + AddComponent(/datum/component/two_handed, force_wielded=(20 + bonus_value * 0.2)) + +/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/kinetic_crusher/pkc, mob/living/user) + . = ..() + if(.) + pkc.force -= bonus_value * 0.2 + pkc.detonation_damage -= bonus_value * 0.8 + AddComponent(/datum/component/two_handed, force_wielded=20) + +/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user) + user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order) + +/obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user) + user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order) + +//colossus +/obj/item/crusher_trophy/blaster_tubes + name = "blaster tubes" + desc = "The blaster tubes from a colossus's arm. Suitable as a trophy for a kinetic crusher." + icon_state = "blaster_tubes" + gender = PLURAL + denied_type = /obj/item/crusher_trophy/blaster_tubes + bonus_value = 15 + var/deadly_shot = FALSE + +/obj/item/crusher_trophy/blaster_tubes/effect_desc() + return "mark detonation to make the next destabilizer shot deal [bonus_value] damage but move slower" + +/obj/item/crusher_trophy/blaster_tubes/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) + if(deadly_shot) + marker.name = "deadly [marker.name]" + marker.icon_state = "chronobolt" + marker.damage = bonus_value + marker.speed = 2 + deadly_shot = FALSE + +/obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user) + deadly_shot = TRUE + addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE) + +/obj/item/crusher_trophy/blaster_tubes/proc/reset_deadly_shot() + deadly_shot = FALSE + +//hierophant +/obj/item/crusher_trophy/vortex_talisman + name = "vortex talisman" + desc = "A glowing trinket that was originally the Hierophant's beacon. Suitable as a trophy for a kinetic crusher." + icon_state = "vortex_talisman" + denied_type = /obj/item/crusher_trophy/vortex_talisman + +/obj/item/crusher_trophy/vortex_talisman/effect_desc() + return "mark detonation to create a homing hierophant chaser" + +/obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user) + if(isliving(target)) + var/obj/effect/temp_visual/hierophant/chaser/chaser = new(get_turf(user), user, target, 3, TRUE) + chaser.monster_damage_boost = FALSE // Weaker cuz no cooldown + chaser.damage = 20 + log_combat(user, target, "fired a chaser at", src) + +// Demonic frost miner +/obj/item/crusher_trophy/ice_block_talisman + name = "ice block talisman" + desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason." + icon_state = "ice_trap_talisman" + denied_type = /obj/item/crusher_trophy/ice_block_talisman + +/obj/item/crusher_trophy/ice_block_talisman/effect_desc() + return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving" + +/obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user) + target.apply_status_effect(/datum/status_effect/ice_block_talisman) + +// Wendigo +/obj/item/crusher_trophy/wendigo_horn + name = "wendigo horn" + desc = "A gnarled horn ripped from the skull of a wendigo. Suitable as a trophy for a kinetic crusher." + icon_state = "wendigo_horn" + denied_type = /obj/item/crusher_trophy/wendigo_horn + +/obj/item/crusher_trophy/wendigo_horn/effect_desc() + return "melee hits inflict twice as much damage" + +/obj/item/crusher_trophy/wendigo_horn/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) + . = ..() + if(.) + crusher.AddComponent(/datum/component/two_handed, force_wielded=40) + +/obj/item/crusher_trophy/wendigo_horn/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) + . = ..() + if(.) + crusher.AddComponent(/datum/component/two_handed, force_wielded=20) + +// Goliath Broodmother +/obj/item/crusher_trophy/broodmother_tongue + name = "broodmother tongue" + desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy. It also feels very spongey, I wonder what would happen if you squeezed it?..." + icon = 'icons/obj/mining_zones/elite_trophies.dmi' + icon_state = "broodmother_tongue" + denied_type = /obj/item/crusher_trophy/broodmother_tongue + bonus_value = 10 + /// Time at which the item becomes usable again + var/use_time + +/obj/item/crusher_trophy/broodmother_tongue/effect_desc() + return "mark detonation to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location" + +/obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user) + if(prob(bonus_value) && target.stat != DEAD) + new /obj/effect/goliath_tentacle/broodmother/patch(get_turf(target), user) + +/obj/item/crusher_trophy/broodmother_tongue/attack_self(mob/user) + if(!isliving(user)) + return + var/mob/living/living_user = user + if(use_time > world.time) + to_chat(living_user, "The tongue looks dried out. You'll need to wait longer to use it again.") + return + else if(HAS_TRAIT(living_user, TRAIT_LAVA_IMMUNE)) + to_chat(living_user, "You stare at the tongue. You don't think this is any use to you.") + return + ADD_TRAIT(living_user, TRAIT_LAVA_IMMUNE, type) + to_chat(living_user, "You squeeze the tongue, and some transluscent liquid shoots out all over you.") + addtimer(TRAIT_CALLBACK_REMOVE(user, TRAIT_LAVA_IMMUNE, type), 10 SECONDS) + use_time = world.time + 60 SECONDS + +// Legionnaire +/obj/item/crusher_trophy/legionnaire_spine + name = "legionnaire spine" + desc = "The spine of a legionnaire. With some creativity, you could use it as a crusher trophy. Alternatively, shaking it might do something as well." + icon = 'icons/obj/mining_zones/elite_trophies.dmi' + icon_state = "legionnaire_spine" + denied_type = /obj/item/crusher_trophy/legionnaire_spine + bonus_value = 20 + /// Time at which the item becomes usable again + var/next_use_time + +/obj/item/crusher_trophy/legionnaire_spine/effect_desc() + return "mark detonation to have a [bonus_value]% chance to summon a loyal legion skull" + +/obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user) + if(!prob(bonus_value) || target.stat == DEAD) + return + var/mob/living/basic/legion_brood/minion = new (user.loc) + minion.assign_creator(user) + minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target + +/obj/item/crusher_trophy/legionnaire_spine/attack_self(mob/user) + if(!isliving(user)) + return + var/mob/living/LivingUser = user + if(next_use_time > world.time) + LivingUser.visible_message(span_warning("[LivingUser] shakes the [src], but nothing happens...")) + to_chat(LivingUser, "You need to wait longer to use this again.") + return + LivingUser.visible_message(span_boldwarning("[LivingUser] shakes the [src] and summons a legion skull!")) + + var/mob/living/basic/legion_brood/minion = new (LivingUser.loc) + minion.assign_creator(LivingUser) + next_use_time = world.time + 4 SECONDS diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_misc.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_misc.dm new file mode 100644 index 0000000000000..4d50d0aa3f79a --- /dev/null +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_misc.dm @@ -0,0 +1,84 @@ +/*! + * Contains crusher trophies that are not obtained from fauna + */ + +//cosmetic items for changing the crusher's look + +/obj/item/crusher_trophy/retool_kit + name = "crusher sword retool kit" + desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a sword." + icon = 'icons/obj/mining.dmi' + icon_state = "retool_kit" + denied_type = /obj/item/crusher_trophy/retool_kit + ///Specifies the sprite/icon state which the crusher is changed to as an item. Should appear in the icons/obj/mining.dmi file with accompanying "lit" and "recharging" sprites + var/retool_icon = "crusher_sword" + ///Specifies the icon state for the crusher's appearance in hand. Should appear in both icons/mob/inhands/weapons/hammers_lefthand.dmi and icons/mob/inhands/weapons/hammers_righthand.dmi + var/retool_inhand_icon = "crusher_sword" + ///For if the retool kit changes the projectile's appearance. The sprite should be in icons/obj/weapons/guns/projectiles.dmi + var/retool_projectile_icon = "pulse1" + +/obj/item/crusher_trophy/retool_kit/effect_desc() + return "the crusher to have the appearance of a sword" + +/obj/item/crusher_trophy/retool_kit/add_to(obj/item/kinetic_crusher/pkc, mob/user) + . = ..() + if(.) + pkc.icon_state = retool_icon + pkc.current_inhand_icon_state = retool_inhand_icon + pkc.projectile_icon = retool_projectile_icon + if(iscarbon(pkc.loc)) + var/mob/living/carbon/holder = pkc.loc + holder.update_worn_back() + holder.update_suit_storage() + holder.update_held_items() + pkc.update_appearance() + +/obj/item/crusher_trophy/retool_kit/remove_from(obj/item/kinetic_crusher/pkc) + pkc.icon_state = initial(pkc.icon_state) + pkc.current_inhand_icon_state = initial(pkc.current_inhand_icon_state) + pkc.projectile_icon = initial(pkc.projectile_icon) + if(iscarbon(pkc.loc)) + var/mob/living/carbon/holder = pkc.loc + holder.update_worn_back() + holder.update_suit_storage() + holder.update_held_items() + pkc.update_appearance() + ..() + +/obj/item/crusher_trophy/retool_kit/harpoon + name = "crusher harpoon retool kit" + desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a harpoon." + icon = 'icons/obj/mining.dmi' + icon_state = "retool_kit" + denied_type = /obj/item/crusher_trophy/retool_kit + retool_icon = "crusher_harpoon" + retool_inhand_icon = "crusher_harpoon" + retool_projectile_icon = "pulse_harpoon" + +/obj/item/crusher_trophy/retool_kit/harpoon/effect_desc() + return "the crusher to have the appearance of a harpoon" + +/obj/item/crusher_trophy/retool_kit/dagger + name = "crusher dagger retool kit" + desc = "A toolkit for changing the crusher's appearance without affecting the device's function. This one will make it look like a dual dagger and mini-blaster on a chain." + icon = 'icons/obj/mining.dmi' + icon_state = "retool_kit" + denied_type = /obj/item/crusher_trophy/retool_kit + retool_icon = "crusher_dagger" + retool_inhand_icon = "crusher_dagger" + +/obj/item/crusher_trophy/retool_kit/dagger/effect_desc() + return "the crusher to have the appearance of a dual dagger and blaster" + +/obj/item/crusher_trophy/retool_kit/ashenskull + name = "ashen skull" + desc = "It burns with the flame of the necropolis, whispering in your ear. It demands to be bound to a suitable weapon." + icon = 'icons/obj/mining.dmi' + icon_state = "retool_kit_skull" + denied_type = /obj/item/crusher_trophy/retool_kit + retool_icon = "crusher_skull" + retool_inhand_icon = "crusher_skull" + retool_projectile_icon = "pulse_skull" + +/obj/item/crusher_trophy/retool_kit/ashenskull/effect_desc() + return "the crusher to appear corrupted by infernal powers" diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index 31c4c1177acc4..ee3170a624b99 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -534,7 +534,6 @@ /datum/reagent/flightpotion name = "Flight Potion" description = "Strange mutagenic compound of unknown origins." - reagent_state = LIQUID color = "#976230" /datum/reagent/flightpotion/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE) diff --git a/code/modules/mob/eye/camera/remote.dm b/code/modules/mob/eye/camera/remote.dm index 97fe41886ce93..ff1dd9612eb83 100644 --- a/code/modules/mob/eye/camera/remote.dm +++ b/code/modules/mob/eye/camera/remote.dm @@ -119,7 +119,7 @@ sprint = initial for(var/i = 0; i < max(sprint, initial); i += 20) - var/turf/step = get_turf(get_step(src, direction)) + var/turf/step = get_turf(get_step_multiz(src, direction)) if(step) setLoc(step) diff --git a/code/modules/mob/living/basic/bots/_bots.dm b/code/modules/mob/living/basic/bots/_bots.dm index c120eab84250d..5272d64add51f 100644 --- a/code/modules/mob/living/basic/bots/_bots.dm +++ b/code/modules/mob/living/basic/bots/_bots.dm @@ -783,11 +783,11 @@ GLOBAL_LIST_INIT(command_strings, list( initial_access = access_card.access.Copy() -/mob/living/basic/bot/proc/summon_bot(atom/caller, turf/turf_destination, user_access = list(), grant_all_access = FALSE) - if(isAI(caller) && !set_ai_caller(caller)) +/mob/living/basic/bot/proc/summon_bot(atom/summoner, turf/turf_destination, user_access = list(), grant_all_access = FALSE) + if(isAI(summoner) && !set_ai_caller(summoner)) return FALSE - bot_reset(bypass_ai_reset = isAI(caller)) - var/turf/destination = turf_destination ? turf_destination : get_turf(caller) + bot_reset(bypass_ai_reset = isAI(summoner)) + var/turf/destination = turf_destination ? turf_destination : get_turf(summoner) ai_controller?.set_blackboard_key(BB_BOT_SUMMON_TARGET, destination) var/list/access_to_grant = grant_all_access ? REGION_ACCESS_ALL_STATION : user_access + initial_access access_card.set_access(access_to_grant) @@ -797,11 +797,11 @@ GLOBAL_LIST_INIT(command_strings, list( addtimer(CALLBACK(src, PROC_REF(bot_reset)), SENTIENT_BOT_RESET_TIMER) return TRUE -/mob/living/basic/bot/proc/set_ai_caller(mob/living/caller) +/mob/living/basic/bot/proc/set_ai_caller(mob/living/ai_caller) var/atom/calling_ai = calling_ai_ref?.resolve() if(!isnull(calling_ai) && calling_ai != src) return FALSE - calling_ai_ref = WEAKREF(caller) + calling_ai_ref = WEAKREF(ai_caller) return TRUE /mob/living/basic/bot/proc/update_bot_mode(new_mode, update_hud = TRUE) diff --git a/code/modules/mob/living/basic/bots/bot_hud.dm b/code/modules/mob/living/basic/bots/bot_hud.dm index 0edcaad6a7e2a..08a7f9e3fbb78 100644 --- a/code/modules/mob/living/basic/bots/bot_hud.dm +++ b/code/modules/mob/living/basic/bots/bot_hud.dm @@ -1,39 +1,35 @@ /mob/living/basic/bot/proc/diag_hud_set_bothealth() - var/image/holder = hud_list[DIAG_HUD] - holder.pixel_y = get_cached_height() - ICON_SIZE_Y - holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + set_hud_image_state(DIAG_HUD, "huddiag[RoundDiagBar(health/maxHealth)]") /mob/living/basic/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed - var/image/holder = hud_list[DIAG_STAT_HUD] - holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) - holder.icon_state = "hudstat" + set_hud_image_state(DIAG_STAT_HUD, "hudstat") return + if(stat != CONSCIOUS) - holder.icon_state = "hudoffline" + set_hud_image_state(DIAG_STAT_HUD, "hudoffline") return - holder.icon_state = "huddead2" + + set_hud_image_state(DIAG_STAT_HUD, "huddead2") /mob/living/basic/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation - var/image/holder = hud_list[DIAG_BOT_HUD] - holder.pixel_y = get_cached_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, Floorbot 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, "") ///proc that handles drawing and transforming the bot's path onto diagnostic huds /mob/living/basic/bot/proc/generate_bot_path(datum/move_loop/has_target/jps/source) diff --git a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm index 0a6a4b03b4354..922289698d4d5 100644 --- a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm +++ b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm @@ -210,11 +210,11 @@ /datum/pet_command/clean/set_command_target(mob/living/parent, atom/target) if(isnull(target) || !istype(target, /obj/effect/decal/cleanable)) - return + return FALSE if(isnull(parent.ai_controller)) - return + return FALSE if(LAZYACCESS(parent.ai_controller.blackboard[BB_TEMPORARY_IGNORE_LIST], target)) - return + return FALSE return ..() /datum/pet_command/clean/execute_action(datum/ai_controller/basic_controller/bot/controller) diff --git a/code/modules/mob/living/basic/drone/_drone.dm b/code/modules/mob/living/basic/drone/_drone.dm index a0be86ecc6a9a..ba315dade6418 100644 --- a/code/modules/mob/living/basic/drone/_drone.dm +++ b/code/modules/mob/living/basic/drone/_drone.dm @@ -219,19 +219,18 @@ listener.RegisterSignal(src, COMSIG_LIVING_REVIVE, TYPE_PROC_REF(/datum/alarm_listener, allow_alarm_changes)) /mob/living/basic/drone/med_hud_set_health() - var/image/holder = hud_list[DIAG_HUD] - holder.pixel_y = get_cached_height() - ICON_SIZE_Y - holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" + set_hud_image_state(DIAG_HUD, "huddiag[RoundDiagBar(health/maxHealth)]") /mob/living/basic/drone/med_hud_set_status() - var/image/holder = hud_list[DIAG_STAT_HUD] - holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(stat == DEAD) - holder.icon_state = "huddead2" - else if(incapacitated) - holder.icon_state = "hudoffline" - else - holder.icon_state = "hudstat" + set_hud_image_state(DIAG_STAT_HUD, "huddead2") + return + + if(incapacitated) + set_hud_image_state(DIAG_STAT_HUD, "hudoffline") + return + + set_hud_image_state(DIAG_STAT_HUD, "hudstat") /mob/living/basic/drone/Destroy() GLOB.drones_list -= src diff --git a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm index bc6415c1a5312..e9b5573ec4703 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm @@ -122,6 +122,12 @@ if(isnull(picked_gas) || isnull(gas_type)) return + if(isguardian(owner)) + var/mob/living/basic/guardian/guardian_owner = owner + if(!guardian_owner.is_deployed()) + to_chat(owner, span_warning("You cannot release gas without being summoned!")) + return + to_chat(owner, span_bolddanger("You start releasing [picked_gas].")) owner.investigate_log("set their gas type to [picked_gas].", INVESTIGATE_ATMOS) var/had_gas = !isnull(active_gas) @@ -150,6 +156,13 @@ SIGNAL_HANDLER if (isnull(active_gas)) return // We shouldn't even be registered at this point but just in case + + if(isguardian(owner)) + var/mob/living/basic/guardian/guardian_owner = owner + if(!guardian_owner.is_deployed()) + stop_gas() + return + var/datum/gas_mixture/mix_to_spawn = new() mix_to_spawn.add_gas(active_gas) mix_to_spawn.gases[active_gas][MOLES] = possible_gases[active_gas] * seconds_per_tick diff --git a/code/modules/mob/living/basic/heretic/fire_shark.dm b/code/modules/mob/living/basic/heretic/fire_shark.dm index 0dfb9a3a1578c..847584ae41a12 100644 --- a/code/modules/mob/living/basic/heretic/fire_shark.dm +++ b/code/modules/mob/living/basic/heretic/fire_shark.dm @@ -21,6 +21,7 @@ mob_size = MOB_SIZE_TINY speak_emote = list("screams") basic_mob_flags = DEL_ON_DEATH + ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles /mob/living/basic/heretic_summon/fire_shark/Initialize(mapload) . = ..() @@ -32,3 +33,6 @@ ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) + +/mob/living/basic/heretic_summon/fire_shark/wild + faction = list(FACTION_HOSTILE) diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm index a5740a51ebd9a..55f960e736a96 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm @@ -9,50 +9,3 @@ icon_state = "sheet-bileworm" inhand_icon_state = null merge_type = /obj/item/stack/sheet/animalhide/bileworm - -//trophy - -/obj/item/crusher_trophy/bileworm_spewlet - name = "bileworm spewlet" - icon = 'icons/mob/simple/lavaland/bileworm.dmi' - icon_state = "bileworm_spewlet" - desc = "A baby bileworm. Suitable as a trophy for a kinetic crusher." - denied_type = /obj/item/crusher_trophy/bileworm_spewlet - ///item ability that handles the effect - var/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet/ability - -/obj/item/crusher_trophy/bileworm_spewlet/Initialize(mapload) - . = ..() - ability = new() - -/obj/item/crusher_trophy/bileworm_spewlet/Destroy(force) - . = ..() - QDEL_NULL(ability) - -/obj/item/crusher_trophy/bileworm_spewlet/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) - . = ..() - if(.) - crusher.add_item_action(ability) - -/obj/item/crusher_trophy/bileworm_spewlet/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) - . = ..() - crusher.remove_item_action(ability) - -/obj/item/crusher_trophy/bileworm_spewlet/effect_desc() - return "mark detonation launches projectiles in cardinal directions on a 10 second cooldown" - -/obj/item/crusher_trophy/bileworm_spewlet/on_mark_detonation(mob/living/target, mob/living/user) - //ability itself handles cooldowns. - ability.InterceptClickOn(user, null, target) - -//yes this is a /mob_cooldown subtype being added to an item. I can't recommend you do what I'm doing -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet - check_flags = NONE - owner_has_control = FALSE - cooldown_time = 10 SECONDS - projectile_type = /obj/projectile/bileworm_acid - projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg' - -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet/New(Target) - firing_directions = GLOB.cardinals.Copy() - return ..() diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm index 98025373b4100..9be663bccd440 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm @@ -31,7 +31,7 @@ var/datum/action/cooldown/ability = controller.blackboard[BB_TARGETED_ACTION] if(QDELETED(target) || QDELETED(controller.pawn) || !ability?.IsAvailable()) return - ability.InterceptClickOn(caller = controller.pawn, target = target) + ability.InterceptClickOn(clicker = controller.pawn, target = target) /datum/ai_planning_subtree/targeted_mob_ability/brimbeam use_ability_behaviour = /datum/ai_behavior/targeted_mob_ability/brimbeam diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm index 9b1916c9ac0f3..fcc03c9531874 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_loot.dm @@ -1,19 +1,3 @@ -/// Brimdemon crusher trophy, it... makes a funny sound? -/obj/item/crusher_trophy/brimdemon_fang - name = "brimdemon's fang" - icon_state = "brimdemon_fang" - desc = "A fang from a brimdemon's corpse." - denied_type = /obj/item/crusher_trophy/brimdemon_fang - /// Cartoon punching vfx - var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM") - -/obj/item/crusher_trophy/brimdemon_fang/effect_desc() - return "mark detonation to create visual and audiosensory effects at the target" - -/obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user) - target.balloon_alert_to_viewers("[pick(comic_phrases)]!") - playsound(target, 'sound/mobs/non-humanoids/brimdemon/brimdemon_crush.ogg', 100) - /// Reagent pool left by dying brimdemon /obj/effect/decal/cleanable/brimdust name = "brimdust" diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath_trophy.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath_trophy.dm deleted file mode 100644 index a4801569cea8b..0000000000000 --- a/code/modules/mob/living/basic/lavaland/goliath/goliath_trophy.dm +++ /dev/null @@ -1,25 +0,0 @@ -/// Mining crusher trophy from a goliath. Increases damage as your health decreases. -/obj/item/crusher_trophy/goliath_tentacle - name = "goliath tentacle" - desc = "A sliced-off goliath tentacle. Suitable as a trophy for a kinetic crusher." - icon_state = "goliath_tentacle" - denied_type = /obj/item/crusher_trophy/goliath_tentacle - bonus_value = 2 - /// Your missing health is multiplied by this value to find the bonus damage - var/missing_health_ratio = 0.1 - /// Amount of health you must lose to gain damage, according to the examine text. Cached so we don't recalculate it every examine. - var/missing_health_desc - -/obj/item/crusher_trophy/goliath_tentacle/Initialize(mapload) - . = ..() - missing_health_desc = 1 / missing_health_ratio / bonus_value - -/obj/item/crusher_trophy/goliath_tentacle/effect_desc() - return "mark detonation to do [bonus_value] more damage for every [missing_health_desc] health you are missing" - -/obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user) - var/missing_health = user.maxHealth - user.health - missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health - missing_health *= bonus_value //multiply the remaining amount by bonus_value - if(missing_health > 0) - target.adjustBruteLoss(missing_health) //and do that much damage diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm index 4b329a0003aa8..1028a7d45eb14 100644 --- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm +++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm @@ -131,7 +131,7 @@ /datum/pet_command/breed/gutlunch/set_command_target(mob/living/parent, atom/target) if(GLOB.gutlunch_count >= MAXIMUM_GUTLUNCH_POP) parent.balloon_alert_to_viewers("can't reproduce anymore!") - return + return FALSE return ..() #undef MAXIMUM_GUTLUNCH_POP diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index 7e7d3e71819bf..b5c590a358968 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -268,7 +268,7 @@ /datum/pet_command/use_ability/lob_charge/set_command_target(mob/living/parent, atom/target) if (!target) - return + return FALSE var/datum/targeting_strategy/targeter = GET_TARGETING_STRATEGY(parent.ai_controller.blackboard[targeting_strategy_key]) if(!targeter?.can_attack(parent, target)) parent.balloon_alert_to_viewers("shakes head!") diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_trophy.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_trophy.dm deleted file mode 100644 index 4647aab260a97..0000000000000 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_trophy.dm +++ /dev/null @@ -1,13 +0,0 @@ -/// Lobstrosity crusher trophy. Rebukes targets, increasing their click cooldown. -/obj/item/crusher_trophy/lobster_claw - name = "lobster claw" - icon_state = "lobster_claw" - desc = "A lobster claw." - denied_type = /obj/item/crusher_trophy/lobster_claw - bonus_value = 1 - -/obj/item/crusher_trophy/lobster_claw/effect_desc() - return "mark detonation to briefly rebuke the target for [bonus_value] seconds" - -/obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user) - target.apply_status_effect(/datum/status_effect/rebuked, bonus_value SECONDS) diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm index 51a4e43f66ab5..a36ea26c4f27f 100644 --- a/code/modules/mob/living/basic/minebots/minebot_ai.dm +++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm @@ -285,7 +285,7 @@ speech_commands = list("mine") callout_type = /datum/callout_option/mine -/datum/pet_command/automate_mining/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target) +/datum/pet_command/automate_mining/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target) return ismineralturf(target) /datum/pet_command/automate_mining/retrieve_command_text(atom/living_pet, atom/target) @@ -350,9 +350,10 @@ /datum/pet_command/protect_owner/minebot/set_command_target(mob/living/parent, atom/target) if(!parent.ai_controller.blackboard[BB_MINEBOT_AUTO_DEFEND]) - return + return FALSE if(!parent.ai_controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET) && !QDELETED(target)) //we are already dealing with something, parent.ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, target) + return TRUE /datum/pet_command/protect_owner/minebot/execute_action(datum/ai_controller/controller) if(controller.blackboard[BB_MINEBOT_AUTO_DEFEND]) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_abilities.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_abilities.dm index 24c5fb4ece2ec..12588886105e2 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_abilities.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_abilities.dm @@ -28,8 +28,8 @@ projectile_type = pick(permitted_projectiles) return ..() -/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/InterceptClickOn(mob/living/caller, params, atom/target) - if (!caller.combat_mode) +/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/InterceptClickOn(mob/living/clicker, params, atom/target) + if (!clicker.combat_mode) return FALSE return ..() diff --git a/code/modules/mob/living/basic/space_fauna/morph.dm b/code/modules/mob/living/basic/space_fauna/morph.dm index f205474af8176..65f3bf7eb82a1 100644 --- a/code/modules/mob/living/basic/space_fauna/morph.dm +++ b/code/modules/mob/living/basic/space_fauna/morph.dm @@ -77,16 +77,14 @@ return ..() //we hide medical hud while in regular state or an item - var/image/holder = hud_list[HEALTH_HUD] - holder.icon_state = null + set_hud_image_state(HEALTH_HUD, null) /mob/living/basic/morph/med_hud_set_status() if(isliving(form_typepath)) return ..() //we hide medical hud while in regular state or an item - var/image/holder = hud_list[STATUS_HUD] - holder.icon_state = null + set_hud_image_state(STATUS_HUD, null) /mob/living/basic/morph/death(gibbed) if(HAS_TRAIT(src, TRAIT_DISGUISED)) @@ -145,7 +143,7 @@ SIGNAL_HANDLER // linters hate this if it's not async for some reason even though nothing blocks - INVOKE_ASYNC(disguise_ability, TYPE_PROC_REF(/datum/action/cooldown, InterceptClickOn), caller = source, target = target) + INVOKE_ASYNC(disguise_ability, TYPE_PROC_REF(/datum/action/cooldown, InterceptClickOn), clicker = source, target = target) return COMSIG_MOB_CANCEL_CLICKON /// Handles the logic for attacking anything. diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm index 74f6c76b459e7..7f5abe60bbeb5 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm @@ -233,7 +233,6 @@ /datum/reagent/rat_spit name = "Rat Spit" description = "Something coming from a rat. Dear god! Who knows where it's been!" - reagent_state = LIQUID color = "#C8C8C8" metabolization_rate = 0.03 * REAGENTS_METABOLISM taste_description = "something funny" diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index b1acd8f9631b2..662242ce60f60 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -74,7 +74,7 @@ AddElement(/datum/element/content_barfer) AddElement(/datum/element/wall_tearer, tear_time = 4 SECONDS, reinforced_multiplier = 3, do_after_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) AddElement(/datum/element/door_pryer, pry_time = 4 SECONDS, interaction_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) - AddComponent(/datum/component/seethrough_mob) + AddComponent(/datum/component/seethrough_mob, keep_color = TRUE) AddComponent(/datum/component/profound_fisher, new /obj/item/fishing_rod/mob_fisher/dragon(src)) RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack)) RegisterSignal(src, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) diff --git a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm index b9cdd8581e4cd..d5bf029f45d94 100644 --- a/code/modules/mob/living/carbon/alien/adult/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/adult/alien_powers.dm @@ -283,22 +283,22 @@ Doesn't work on other aliens/AI.*/ // 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/alien/acid/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/alien/acid/neurotoxin/InterceptClickOn(mob/living/clicker, params, atom/target) . = ..() if(!.) - unset_click_ability(caller, refund_cooldown = FALSE) + unset_click_ability(clicker, refund_cooldown = FALSE) return FALSE var/modifiers = params2list(params) - caller.visible_message( - span_danger("[caller] spits neurotoxin!"), + clicker.visible_message( + span_danger("[clicker] spits neurotoxin!"), span_alertalien("You spit neurotoxin."), ) - var/obj/projectile/neurotoxin/neurotoxin = new /obj/projectile/neurotoxin(caller.loc) - neurotoxin.aim_projectile(target, caller, modifiers) - neurotoxin.firer = caller + var/obj/projectile/neurotoxin/neurotoxin = new /obj/projectile/neurotoxin(clicker.loc) + neurotoxin.aim_projectile(target, clicker, modifiers) + neurotoxin.firer = clicker neurotoxin.fire() - caller.newtonian_move(get_angle(target, caller)) + clicker.newtonian_move(get_angle(target, clicker)) return TRUE // Has to return TRUE, otherwise is skipped. diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index b416cd2c41e26..6274f08c61227 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -244,6 +244,10 @@ paper_note.show_through_camera(usr) +/mob/living/carbon/on_fall() + . = ..() + loc?.handle_fall(src) //it's loc so it doesn't call the mob's handle_fall which does nothing + /mob/living/carbon/resist_buckle() if(!HAS_TRAIT(src, TRAIT_RESTRAINED)) buckled.user_unbuckle_mob(src, src) @@ -1376,7 +1380,7 @@ /// Special carbon interaction on lying down, to transform its sprite by a rotation. /mob/living/carbon/proc/lying_angle_on_lying_down(new_lying_angle) if(!new_lying_angle) - set_lying_angle(pick(90, 270)) + set_lying_angle(pick(LYING_ANGLE_EAST, LYING_ANGLE_WEST)) else set_lying_angle(new_lying_angle) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 4497728db8f42..00c186f8e7751 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -78,6 +78,8 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/heart/mutantheart = /obj/item/organ/heart ///Replaces default lungs with a different organ var/obj/item/organ/lungs/mutantlungs = /obj/item/organ/lungs + /// Smoker lungs for the quirk, overriden by certain species + var/obj/item/organ/lungs/smoker_lungs = /obj/item/organ/lungs/smoker_lungs ///Replaces default eyes with a different organ var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes ///Replaces default ears with a different organ diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 2a1b7785ba84a..9a31bc6d8c910 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -3,6 +3,7 @@ id = SPECIES_ETHEREAL meat = /obj/item/food/meat/slab/human/mutant/ethereal mutantlungs = /obj/item/organ/lungs/ethereal + smoker_lungs = /obj/item/organ/lungs/ethereal/ethereal_smoker mutantstomach = /obj/item/organ/stomach/ethereal mutanttongue = /obj/item/organ/tongue/ethereal mutantheart = /obj/item/organ/heart/ethereal diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index b27759e594faa..f6864ac0d4c30 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -19,6 +19,7 @@ inherent_biotypes = MOB_HUMANOID|MOB_MINERAL inherent_respiration_type = RESPIRATION_PLASMA mutantlungs = /obj/item/organ/lungs/plasmaman + smoker_lungs = /obj/item/organ/lungs/plasmaman/plasmaman_smoker mutanttongue = /obj/item/organ/tongue/bone/plasmaman mutantliver = /obj/item/organ/liver/bone/plasmaman mutantstomach = /obj/item/organ/stomach/bone/plasmaman diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 6616736a61064..7dc6de58cfc32 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -73,15 +73,22 @@ #define DUST_ANIMATION_TIME 1.3 SECONDS /** - * This is the proc for turning a mob into ash. + * This is the proc for turning an atom into ash. * Dusting robots does not eject the MMI, so it's a bit more powerful than gib() * - * Arguments: + * Arguments: (Only used for mobs) * * just_ash - If TRUE, ash will spawn where the mob was, as opposed to remains * * drop_items - Should the mob drop their items before dusting? * * force - Should this mob be FORCABLY dusted? */ -/mob/living/proc/dust(just_ash, drop_items, force) +/atom/movable/proc/dust(just_ash, drop_items, force) + dust_animation() + // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. + // Looks much nicer and doesn't cause multiple runtimes. + QDEL_IN(src, DUST_ANIMATION_TIME) + +/mob/living/dust(just_ash, drop_items, force) + ..() if(body_position == STANDING_UP) // keep us upright so the animation fits. ADD_TRAIT(src, TRAIT_FORCED_STANDING, TRAIT_GENERIC) @@ -93,10 +100,8 @@ if(buckled) buckled.unbuckle_mob(src, force = TRUE) - dust_animation() addtimer(CALLBACK(src, PROC_REF(spawn_dust), just_ash), DUST_ANIMATION_TIME - 0.3 SECONDS) ghostize() - QDEL_IN(src, DUST_ANIMATION_TIME) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes. /// Animates turning into dust. /// Does not delete src afterwards, BUT it will become invisible (and grey), so ensure you handle that yourself diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d6633a2905d5b..8405e693cfe67 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -480,12 +480,12 @@ if(SOUTH) animate(M, pixel_x = target_pixel_x, pixel_y = target_pixel_y - offset, 3) if(EAST) - if(M.lying_angle == 270) //update the dragged dude's direction if we've turned - M.set_lying_angle(90) + if(M.lying_angle == LYING_ANGLE_WEST) //update the dragged dude's direction if we've turned + M.set_lying_angle(LYING_ANGLE_EAST) animate(M, pixel_x = target_pixel_x + offset, pixel_y = target_pixel_y, 3) if(WEST) - if(M.lying_angle == 90) - M.set_lying_angle(270) + if(M.lying_angle == LYING_ANGLE_EAST) + M.set_lying_angle(LYING_ANGLE_WEST) animate(M, pixel_x = target_pixel_x - offset, pixel_y = target_pixel_y, 3) /mob/living/proc/reset_pull_offsets(mob/living/M, override) @@ -703,7 +703,7 @@ if(istype(potential_spine)) get_up_time *= potential_spine.athletics_boost_multiplier - if(!instant && !do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP, hidden = TRUE)) + if(!instant && !do_after(src, get_up_time, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP, hidden = TRUE)) return if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED)) return @@ -731,7 +731,6 @@ if(rotate_on_lying) body_position_pixel_y_offset = PIXEL_Y_OFFSET_LYING - /// Proc to append behavior related to lying down. /mob/living/proc/on_standing_up() if(layer == LYING_MOB_LAYER) @@ -1046,9 +1045,9 @@ ///Called by mob Move() when the lying_angle is different than zero, to better visually simulate crawling. /mob/living/proc/lying_angle_on_movement(direct) if(direct & EAST) - set_lying_angle(90) + set_lying_angle(LYING_ANGLE_EAST) else if(direct & WEST) - set_lying_angle(270) + set_lying_angle(LYING_ANGLE_WEST) /mob/living/carbon/alien/adult/lying_angle_on_movement(direct) return @@ -1923,7 +1922,6 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/proc/on_fall() SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_LIVING_THUD) - loc?.handle_fall(src)//it's loc so it doesn't call the mob's handle_fall which does nothing return /mob/living/forceMove(atom/destination) @@ -2620,8 +2618,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) on_fall() if(body_position == STANDING_UP) //force them on the ground set_body_position(LYING_DOWN) - set_lying_angle(pick(90, 270)) - + set_lying_angle(pick(LYING_ANGLE_EAST, LYING_ANGLE_WEST)) /// Proc to append behavior to the condition of being floored. Called when the condition ends. /mob/living/proc/on_floored_end() @@ -3012,3 +3009,8 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/proc/check_hit_limb_zone_name(hit_zone) if(has_limbs) return hit_zone + +/mob/living/proc/painful_scream(force = FALSE) + if(HAS_TRAIT(src, TRAIT_ANALGESIA) && !force) + return + INVOKE_ASYNC(src, PROC_REF(emote), "scream") diff --git a/code/modules/mob/living/living_update_icons.dm b/code/modules/mob/living/living_update_icons.dm index 4e8b809e047f9..20f36ab96b001 100644 --- a/code/modules/mob/living/living_update_icons.dm +++ b/code/modules/mob/living/living_update_icons.dm @@ -61,7 +61,12 @@ ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT) addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_NO_FLOATING_ANIM, UPDATE_TRANSFORM_TRAIT), 0.3 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //if true, we want to avoid any animation time, it'll tween and not rotate at all otherwise. - var/is_opposite_angle = SIMPLIFY_DEGREES(lying_angle+180) == lying_prev - animate(src, transform = ntransform, time = is_opposite_angle ? 0 : UPDATE_TRANSFORM_ANIMATION_TIME, pixel_y = final_pixel_y, dir = final_dir, easing = (EASE_IN|EASE_OUT)) + var/is_opposite_angle = REVERSE_ANGLE(lying_angle) == lying_prev + var/animate_time = is_opposite_angle ? 0 : UPDATE_TRANSFORM_ANIMATION_TIME + animate(src, transform = ntransform, time = animate_time, pixel_y = final_pixel_y, dir = final_dir, easing = (EASE_IN|EASE_OUT)) + for (var/hud_key in hud_list) + var/image/hud_image = hud_list[hud_key] + if (istype(hud_image)) + adjust_hud_position(hud_image, animate_time = animate_time) SEND_SIGNAL(src, COMSIG_LIVING_POST_UPDATE_TRANSFORM, resize, lying_angle, is_opposite_angle) diff --git a/code/modules/mob/living/silicon/ai/ai_actions/remote_power.dm b/code/modules/mob/living/silicon/ai/ai_actions/remote_power.dm index fd45ed3d68795..bc0d720487f5e 100644 --- a/code/modules/mob/living/silicon/ai/ai_actions/remote_power.dm +++ b/code/modules/mob/living/silicon/ai/ai_actions/remote_power.dm @@ -14,28 +14,28 @@ enable_text = span_notice("You prepare to power any APC you see.") disable_text = span_notice("You stop focusing on powering APCs.") -/datum/action/innate/ai/ranged/power_apc/do_ability(mob/living/caller, atom/clicked_on) +/datum/action/innate/ai/ranged/power_apc/do_ability(mob/living/clicker, atom/clicked_on) - if (!isAI(caller)) + if (!isAI(clicker)) return FALSE - var/mob/living/silicon/ai/ai_caller = caller + var/mob/living/silicon/ai/ai_clicker = clicker - if(caller.incapacitated) - unset_ranged_ability(caller) + if(clicker.incapacitated) + unset_ranged_ability(clicker) return FALSE if(!isapc(clicked_on)) - clicked_on.balloon_alert(ai_caller, "not an APC!") + clicked_on.balloon_alert(ai_clicker, "not an APC!") return FALSE - if(ai_caller.battery - 50 <= 0) - to_chat(ai_caller, span_warning("You do not have the battery to charge an APC!")) + if(ai_clicker.battery - 50 <= 0) + to_chat(ai_clicker, span_warning("You do not have the battery to charge an APC!")) return FALSE var/obj/machinery/power/apc/apc = clicked_on var/obj/item/stock_parts/power_store/cell = apc.get_cell() cell.give(STANDARD_BATTERY_CHARGE) - ai_caller.battery -= 50 + ai_clicker.battery -= 50 diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 38599c204653a..6753a34b5a3ba 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -686,8 +686,8 @@ Pass a positive integer as an argument to override a bot's default speed. if(mode != BOT_SUMMON && mode != BOT_RESPONDING) access_card.set_access(prev_access) -/mob/living/simple_animal/bot/proc/call_bot(caller, turf/waypoint, message = TRUE) - if(isAI(caller) && calling_ai && calling_ai != src) //Prevents an override if another AI is controlling this bot. +/mob/living/simple_animal/bot/proc/call_bot(summoner, turf/waypoint, message = TRUE) + if(isAI(summoner) && calling_ai && calling_ai != src) //Prevents an override if another AI is controlling this bot. return FALSE bot_reset() //Reset a bot before setting it to call mode. @@ -696,7 +696,7 @@ Pass a positive integer as an argument to override a bot's default speed. //Easier then building the list ourselves. I'm sorry. var/static/obj/item/card/id/all_access = new /obj/item/card/id/advanced/gold/captains_spare() set_path(get_path_to(src, waypoint, max_distance=200, access = all_access.GetAccess())) - calling_ai = caller //Link the AI to the bot! + calling_ai = summoner //Link the AI to the bot! ai_waypoint = waypoint if(path?.len) //Ensures that a valid path is calculated! @@ -706,7 +706,7 @@ Pass a positive integer as an argument to override a bot's default speed. access_card.set_access(REGION_ACCESS_ALL_STATION) //Give the bot all-access while under the AI's command. if(client) reset_access_timer_id = addtimer(CALLBACK (src, PROC_REF(bot_reset)), 60 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time - to_chat(src, span_notice("[span_big("Priority waypoint set by [icon2html(calling_ai, src)] [caller]. Proceed to [end_area].")]
[path.len-1] meters to destination. You have been granted additional door access for 60 seconds.")) + to_chat(src, span_notice("[span_big("Priority waypoint set by [icon2html(calling_ai, src)] [summoner]. Proceed to [end_area].")]
[path.len-1] meters to destination. You have been granted additional door access for 60 seconds.")) if(message) to_chat(calling_ai, span_notice("[icon2html(src, calling_ai)] [name] called to [end_area]. [path.len-1] meters to destination.")) pathset = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 8cdf9141ab845..a5897c01695d4 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -321,18 +321,6 @@ Difficulty: Extremely Hard mineral_scan_pulse(T, world.view + 1, src) . = ..() -/obj/item/crusher_trophy/ice_block_talisman - name = "ice block talisman" - desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason." - icon_state = "ice_trap_talisman" - denied_type = /obj/item/crusher_trophy/ice_block_talisman - -/obj/item/crusher_trophy/ice_block_talisman/effect_desc() - return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving" - -/obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user) - target.apply_status_effect(/datum/status_effect/ice_block_talisman) - /datum/status_effect/ice_block_talisman id = "ice_block_talisman" duration = 4 SECONDS diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 4643d529d495c..b6ba30f523f6b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -240,25 +240,6 @@ Difficulty: Hard playsound(human_user.loc, 'sound/items/drink.ogg', rand(10,50), TRUE) qdel(src) -/obj/item/crusher_trophy/wendigo_horn - name = "wendigo horn" - desc = "A gnarled horn ripped from the skull of a wendigo. Suitable as a trophy for a kinetic crusher." - icon_state = "wendigo_horn" - denied_type = /obj/item/crusher_trophy/wendigo_horn - -/obj/item/crusher_trophy/wendigo_horn/effect_desc() - return "melee hits inflict twice as much damage" - -/obj/item/crusher_trophy/wendigo_horn/add_to(obj/item/kinetic_crusher/crusher, mob/living/user) - . = ..() - if(.) - crusher.AddComponent(/datum/component/two_handed, force_wielded=40) - -/obj/item/crusher_trophy/wendigo_horn/remove_from(obj/item/kinetic_crusher/crusher, mob/living/user) - . = ..() - if(.) - crusher.AddComponent(/datum/component/two_handed, force_wielded=20) - /obj/item/wendigo_skull name = "wendigo skull" desc = "A bloody skull torn from a murderous beast, the soulless eye sockets seem to constantly track your movement." diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 6e673aa9be5e7..55d7a1d5c3d96 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -244,39 +244,6 @@ T = get_step(T, i) new /obj/effect/goliath_tentacle/broodmother(T) -// Broodmother's loot: Broodmother Tongue -/obj/item/crusher_trophy/broodmother_tongue - name = "broodmother tongue" - desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy. It also feels very spongey, I wonder what would happen if you squeezed it?..." - icon = 'icons/obj/mining_zones/elite_trophies.dmi' - icon_state = "broodmother_tongue" - denied_type = /obj/item/crusher_trophy/broodmother_tongue - bonus_value = 10 - /// Time at which the item becomes usable again - var/use_time - -/obj/item/crusher_trophy/broodmother_tongue/effect_desc() - return "mark detonation to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location" - -/obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user) - if(prob(bonus_value) && target.stat != DEAD) - new /obj/effect/goliath_tentacle/broodmother/patch(get_turf(target), user) - -/obj/item/crusher_trophy/broodmother_tongue/attack_self(mob/user) - if(!isliving(user)) - return - var/mob/living/living_user = user - if(use_time > world.time) - to_chat(living_user, "The tongue looks dried out. You'll need to wait longer to use it again.") - return - else if(HAS_TRAIT(living_user, TRAIT_LAVA_IMMUNE)) - to_chat(living_user, "You stare at the tongue. You don't think this is any use to you.") - return - ADD_TRAIT(living_user, TRAIT_LAVA_IMMUNE, type) - to_chat(living_user, "You squeeze the tongue, and some transluscent liquid shoots out all over you.") - addtimer(TRAIT_CALLBACK_REMOVE(user, TRAIT_LAVA_IMMUNE, type), 10 SECONDS) - use_time = world.time + 60 SECONDS - #undef CALL_CHILDREN #undef RAGE #undef SPAWN_CHILDREN diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm index 051733211ed3c..1c729df07d36e 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm @@ -310,42 +310,6 @@ . = ..() transform *= 0.33 -// Legionnaire's loot: Legionnaire Spine - -/obj/item/crusher_trophy/legionnaire_spine - name = "legionnaire spine" - desc = "The spine of a legionnaire. With some creativity, you could use it as a crusher trophy. Alternatively, shaking it might do something as well." - icon = 'icons/obj/mining_zones/elite_trophies.dmi' - icon_state = "legionnaire_spine" - denied_type = /obj/item/crusher_trophy/legionnaire_spine - bonus_value = 20 - /// Time at which the item becomes usable again - var/next_use_time - -/obj/item/crusher_trophy/legionnaire_spine/effect_desc() - return "mark detonation to have a [bonus_value]% chance to summon a loyal legion skull" - -/obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user) - if(!prob(bonus_value) || target.stat == DEAD) - return - var/mob/living/basic/legion_brood/minion = new (user.loc) - minion.assign_creator(user) - minion.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] = target - -/obj/item/crusher_trophy/legionnaire_spine/attack_self(mob/user) - if(!isliving(user)) - return - var/mob/living/LivingUser = user - if(next_use_time > world.time) - LivingUser.visible_message(span_warning("[LivingUser] shakes the [src], but nothing happens...")) - to_chat(LivingUser, "You need to wait longer to use this again.") - return - LivingUser.visible_message(span_boldwarning("[LivingUser] shakes the [src] and summons a legion skull!")) - - var/mob/living/basic/legion_brood/minion = new (LivingUser.loc) - minion.assign_creator(LivingUser) - next_use_time = world.time + 4 SECONDS - #undef LEGIONNAIRE_CHARGE #undef HEAD_DETACH #undef BONFIRE_TELEPORT diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm index 5dba83e25320e..ef8e596ac2ce0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm @@ -65,20 +65,3 @@ name = "magic polar bear" desc = "It seems sentient somehow." faction = list(FACTION_NEUTRAL) - -/obj/item/crusher_trophy/bear_paw - name = "polar bear paw" - desc = "It's a polar bear paw." - icon_state = "bear_paw" - denied_type = /obj/item/crusher_trophy/bear_paw - -/obj/item/crusher_trophy/bear_paw/effect_desc() - return "mark detonation to attack twice if you are below half your life" - -/obj/item/crusher_trophy/bear_paw/on_mark_detonation(mob/living/target, mob/living/user) - if(user.health / user.maxHealth > 0.5) - return - var/obj/item/I = user.get_active_held_item() - if(!I) - return - I.melee_attack_chain(user, target, null) diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm index 7f6a5c5cd36e3..a47d9fe26768a 100644 --- a/code/modules/mob/living/simple_animal/hostile/ooze.dm +++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm @@ -352,7 +352,7 @@ return TRUE -/datum/action/cooldown/globules/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/globules/InterceptClickOn(mob/living/clicker, params, atom/target) . = ..() if(!.) return FALSE @@ -361,19 +361,19 @@ // Well, we need to use the params of the click intercept // for passing into aim_projectile, so we'll handle it here instead. // We just need to make sure Pre-activate and Activate return TRUE so we make it this far - caller.visible_message( - span_nicegreen("[caller] launches a mending globule!"), + clicker.visible_message( + span_nicegreen("[clicker] launches a mending globule!"), span_notice("You launch a mending globule."), ) - var/mob/living/simple_animal/hostile/ooze/oozy = caller + var/mob/living/simple_animal/hostile/ooze/oozy = clicker if(istype(oozy)) oozy.adjust_ooze_nutrition(-5) var/modifiers = params2list(params) - var/obj/projectile/globule/globule = new(caller.loc) - globule.aim_projectile(target, caller, modifiers) - globule.def_zone = caller.zone_selected + var/obj/projectile/globule/globule = new(clicker.loc) + globule.aim_projectile(target, clicker, modifiers) + globule.def_zone = clicker.zone_selected globule.fire() StartCooldown() diff --git a/code/modules/mob/living/simple_animal/hostile/vatbeast.dm b/code/modules/mob/living/simple_animal/hostile/vatbeast.dm index 56dcbcaf7e1fe..c4850fae783a3 100644 --- a/code/modules/mob/living/simple_animal/hostile/vatbeast.dm +++ b/code/modules/mob/living/simple_animal/hostile/vatbeast.dm @@ -85,13 +85,13 @@ if(refund_cooldown) to_chat(on_who, span_notice("You stop preparing your [on_who == owner ? "":"steed's "]pimp-tentacle.")) -/datum/action/cooldown/tentacle_slap/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/tentacle_slap/InterceptClickOn(mob/living/clicker, params, atom/target) // Check if we can slap if(!isliving(target) || target == owner) return FALSE if(!owner.Adjacent(target)) - owner.balloon_alert(caller, "too far!") + owner.balloon_alert(clicker, "too far!") return FALSE // Do the slap @@ -101,8 +101,8 @@ // Give feedback from the slap. // Additional feedback for if a rider did it - if(caller != owner) - to_chat(caller, span_notice("You command [owner] to slap [target] with its tentacles.")) + if(clicker != owner) + to_chat(clicker, span_notice("You command [owner] to slap [target] with its tentacles.")) return TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index acc14dc7a003d..6be0304fda45c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -179,7 +179,7 @@ else var/image/I = image('icons/mob/huds/hud.dmi', src, "") - I.appearance_flags = RESET_COLOR|RESET_TRANSFORM + I.appearance_flags = RESET_COLOR|PIXEL_SCALE|KEEP_APART hud_list[hud] = I set_hud_image_active(hud, update_huds = FALSE) //by default everything is active. but dont add it to huds to keep control. diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm index a93ebec8b570c..aef563bacef8c 100644 --- a/code/modules/mod/mod_link.dm +++ b/code/modules/mod/mod_link.dm @@ -397,7 +397,7 @@ RETURN_TYPE(/datum/mod_link) if(!link_call) return - return link_call.caller == src ? link_call.receiver : link_call.caller + return link_call.link_caller == src ? link_call.link_receiver : link_call.link_caller /datum/mod_link/proc/call_link(datum/mod_link/called, mob/user) if(!frequency) @@ -424,8 +424,8 @@ link_target.playsound_local(get_turf(called.holder), 'sound/items/weapons/ring.ogg', 15, vary = TRUE) var/atom/movable/screen/alert/modlink_call/alert = link_target.throw_alert("[REF(src)]_modlink", /atom/movable/screen/alert/modlink_call) alert.desc = "[holder] ([id]) is calling you! Left-click this to accept the call. Right-click to deny it." - alert.caller_ref = WEAKREF(src) - alert.receiver_ref = WEAKREF(called) + alert.link_caller_ref = WEAKREF(src) + alert.link_receiver_ref = WEAKREF(called) alert.user_ref = WEAKREF(user) /datum/mod_link/proc/end_call() @@ -438,33 +438,33 @@ /// A MODlink call datum, used to handle the call between two MODlinks. /datum/mod_link_call /// The MODlink that is calling. - var/datum/mod_link/caller + var/datum/mod_link/link_caller /// The MODlink that is being called. - var/datum/mod_link/receiver - -/datum/mod_link_call/New(datum/mod_link/caller, datum/mod_link/receiver) - caller.link_call = src - receiver.link_call = src - src.caller = caller - src.receiver = receiver - var/mob/living/caller_mob = caller.get_user_callback.Invoke() + var/datum/mod_link/link_receiver + +/datum/mod_link_call/New(datum/mod_link/link_caller, datum/mod_link/link_receiver) + link_caller.link_call = src + link_receiver.link_call = src + src.link_caller = link_caller + src.link_receiver = link_receiver + var/mob/living/caller_mob = link_caller.get_user_callback.Invoke() ADD_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src)) - var/mob/living/receiver_mob = receiver.get_user_callback.Invoke() + var/mob/living/receiver_mob = link_receiver.get_user_callback.Invoke() ADD_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src)) make_visuals() START_PROCESSING(SSprocessing, src) /datum/mod_link_call/Destroy() - var/mob/living/caller_mob = caller.get_user_callback.Invoke() + var/mob/living/caller_mob = link_caller.get_user_callback.Invoke() if(!QDELETED(caller_mob)) REMOVE_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src)) - var/mob/living/receiver_mob = receiver.get_user_callback.Invoke() + var/mob/living/receiver_mob = link_receiver.get_user_callback.Invoke() if(!QDELETED(receiver_mob)) REMOVE_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src)) STOP_PROCESSING(SSprocessing, src) clear_visuals() - caller.link_call = null - receiver.link_call = null + link_caller.link_call = null + link_receiver.link_call = null return ..() /datum/mod_link_call/process(seconds_per_tick) @@ -473,17 +473,17 @@ qdel(src) /datum/mod_link_call/proc/can_continue_call() - return caller.frequency == receiver.frequency && caller.can_call_callback.Invoke() && receiver.can_call_callback.Invoke() + return link_caller.frequency == link_receiver.frequency && link_caller.can_call_callback.Invoke() && link_receiver.can_call_callback.Invoke() /datum/mod_link_call/proc/make_visuals() - var/caller_visual = caller.make_visual_callback.Invoke() - var/receiver_visual = receiver.make_visual_callback.Invoke() - caller.get_visual_callback.Invoke(receiver_visual) - receiver.get_visual_callback.Invoke(caller_visual) + var/caller_visual = link_caller.make_visual_callback.Invoke() + var/receiver_visual = link_receiver.make_visual_callback.Invoke() + link_caller.get_visual_callback.Invoke(receiver_visual) + link_receiver.get_visual_callback.Invoke(caller_visual) /datum/mod_link_call/proc/clear_visuals() - caller.delete_visual_callback.Invoke() - receiver.delete_visual_callback.Invoke() + link_caller.delete_visual_callback.Invoke() + link_receiver.delete_visual_callback.Invoke() /proc/call_link(mob/user, datum/mod_link/calling_link) if(!calling_link.frequency) @@ -514,9 +514,9 @@ clickable_glow = TRUE var/end_message = "call timed out!" /// A weak reference to the MODlink that is calling. - var/datum/weakref/caller_ref + var/datum/weakref/link_caller_ref /// A weak reference to the MODlink that is being called. - var/datum/weakref/receiver_ref + var/datum/weakref/link_receiver_ref /// A weak reference to the mob that is calling. var/datum/weakref/user_ref @@ -524,25 +524,25 @@ . = ..() if(usr != owner) return - var/datum/mod_link/caller = caller_ref.resolve() - var/datum/mod_link/receiver = receiver_ref.resolve() - if(!caller || !receiver) + var/datum/mod_link/link_caller = link_caller_ref.resolve() + var/datum/mod_link/link_receiver = link_receiver_ref.resolve() + if(!link_caller || !link_receiver) return - if(caller.link_call || receiver.link_call) + if(link_caller.link_call || link_receiver.link_call) return var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, RIGHT_CLICK)) end_message = "call denied!" - owner.clear_alert("[REF(caller)]_modlink") + owner.clear_alert("[REF(link_caller)]_modlink") return end_message = "call accepted" - new /datum/mod_link_call(caller, receiver) - owner.clear_alert("[REF(caller)]_modlink") + new /datum/mod_link_call(link_caller, link_receiver) + owner.clear_alert("[REF(link_caller)]_modlink") /atom/movable/screen/alert/modlink_call/Destroy() var/mob/living/user = user_ref?.resolve() - var/datum/mod_link/caller = caller_ref?.resolve() - if(!user || !caller) + var/datum/mod_link/link_caller = link_caller_ref?.resolve() + if(!user || !link_caller) return ..() - caller.holder.balloon_alert(user, end_message) + link_caller.holder.balloon_alert(user, end_message) return ..() diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 4923479d71def..e547d390fcd56 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -549,11 +549,11 @@ * The program calling this proc. * The message that the program wishes to display. */ -/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/beep/twobeep_high.ogg') - if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence. +/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/call_source, alerttext, sound = 'sound/machines/beep/twobeep_high.ogg') + if(!call_source || !call_source.alert_able || call_source.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence. return FALSE playsound(src, sound, 50, TRUE) - physical.loc.visible_message(span_notice("[icon2html(physical, viewers(physical.loc))] \The [src] displays a [caller.filedesc] notification: [alerttext]")) + physical.loc.visible_message(span_notice("[icon2html(physical, viewers(physical.loc))] \The [src] displays a [call_source.filedesc] notification: [alerttext]")) /obj/item/modular_computer/proc/ring(ringtone, list/balloon_alertees) // bring bring if(!use_energy()) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index fcd73ec99bf1e..d974141bc19c8 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -162,7 +162,7 @@ new_paper.raw_stamp_data = copy_raw_stamps() new_paper.stamp_cache = stamp_cache?.Copy() new_paper.update_icon_state() - copy_overlays(new_paper, TRUE) + new_paper.copy_overlays(src) return new_paper /** diff --git a/code/modules/plumbing/plumbers/_plumb_reagents.dm b/code/modules/plumbing/plumbers/_plumb_reagents.dm index 4cce127c8b822..90954ca4985a3 100644 --- a/code/modules/plumbing/plumbers/_plumb_reagents.dm +++ b/code/modules/plumbing/plumbers/_plumb_reagents.dm @@ -121,12 +121,19 @@ SHOULD_NOT_OVERRIDE(TRUE) . = 0 + + //no reagents if(!total_volume) return var/obj/machinery/plumbing/reaction_chamber/reactor = my_atom var/list/datum/reagent/catalysts = reactor.catalysts + //no catalysts + if(!catalysts.len) + return total_volume + + //filter out catalysts except when we have excess of them var/working_volume var/catalyst_volume var/list/cached_reagents = reagent_list diff --git a/code/modules/power/power_store.dm b/code/modules/power/power_store.dm index 8756f052781df..ddf35e2bed330 100644 --- a/code/modules/power/power_store.dm +++ b/code/modules/power/power_store.dm @@ -201,7 +201,7 @@ . = ..() if(rigged) . += span_danger("This [name] seems to be faulty!") - else + else if(!isnull(charge_light_type)) . += "The charge meter reads [CEILING(percent(), 0.1)]%." //so it doesn't say 0% charge when the overlay indicates it still has charge /obj/item/stock_parts/power_store/proc/on_reagent_change(datum/reagents/holder, ...) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 1823f086228a4..4cd1692cc3e0a 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -170,7 +170,7 @@ // actually flip to other direction? if(abs(angle - azimuth_current) > 180) - mid_azimuth = reverse_angle(mid_azimuth) + mid_azimuth = REVERSE_ANGLE(mid_azimuth) // Split into 2 parts so it doesn't distort on large changes animate(part, diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 0855e63ed4bf9..4b103080b16e3 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -90,7 +90,7 @@ // actually flip to other direction? if(abs(angle - azimuth_current) > 180) - mid_azimuth = reverse_angle(mid_azimuth) + mid_azimuth = REVERSE_ANGLE(mid_azimuth) // Split into 2 parts so it doesn't distort on large changes animate(part, diff --git a/code/modules/power/turbine/turbine.dm b/code/modules/power/turbine/turbine.dm index 2112002e50745..bdb91cd8d2f4d 100644 --- a/code/modules/power/turbine/turbine.dm +++ b/code/modules/power/turbine/turbine.dm @@ -2,10 +2,6 @@ #define MINIMUM_TURBINE_PRESSURE 0.01 ///Returns the minimum pressure if it falls below the value #define PRESSURE_MAX(value)(max((value), MINIMUM_TURBINE_PRESSURE)) -///Use emissive for overlays -#define EMISSIVE_OVERLAY (1 << 0) -///No turned off overlay -#define NO_INACTIVE_OVERLAY (1 << 1) /obj/machinery/power/turbine icon = 'icons/obj/machines/engine/turbine.dmi' @@ -14,18 +10,14 @@ can_atmos_pass = ATMOS_PASS_DENSITY processing_flags = START_PROCESSING_MANUALLY - ///Checks if the machine is processing or not - var/active = FALSE - ///The parts can be registered on the main one only when their panel is closed - var/can_connect = TRUE + ///The cached efficiency of this turbines installed part + var/efficiency = 0 ///Reference to our turbine part var/obj/item/turbine_parts/installed_part ///Path of the turbine part we can install var/obj/item/turbine_parts/part_path ///The gas mixture this turbine part is storing var/datum/gas_mixture/machine_gasmix - ///Flags for our overlays - var/overlay_flags = NONE /obj/machinery/power/turbine/Initialize(mapload, gas_theoretical_volume) . = ..() @@ -35,16 +27,17 @@ if(mapload) installed_part = new part_path(src) + efficiency = installed_part.get_tier_value(TURBINE_MAX_EFFICIENCY) air_update_turf(TRUE) - update_appearance() + update_appearance(UPDATE_OVERLAYS) register_context() - /obj/machinery/power/turbine/post_machine_initialize() . = ..() + activate_parts() /obj/machinery/power/turbine/Destroy() @@ -59,6 +52,10 @@ deactivate_parts() return ..() +/obj/machinery/power/turbine/on_deconstruction(disassembled) + installed_part?.forceMove(loc) + return ..() + /obj/machinery/power/turbine/add_context(atom/source, list/context, obj/item/held_item, mob/user) if(isnull(held_item)) return NONE @@ -103,19 +100,31 @@ . += span_notice("It can rotated with a [EXAMINE_HINT("wrench")]") . += span_notice("The full machine can be [EXAMINE_HINT("pried")] apart") +///Is this machine currently running +/obj/machinery/power/turbine/proc/is_active() + SHOULD_BE_PURE(TRUE) + PROTECTED_PROC(TRUE) + + return FALSE + +/** + * Adds overlays to this turbines appearance + * Arguments + * + * * list/overlays - the list of overlays to add to + */ +/obj/machinery/power/turbine/proc/set_overlays(list/overlays) + PROTECTED_PROC(TRUE) + + overlays += "[base_icon_state]_[is_active() ? "on" : "off"]" + /obj/machinery/power/turbine/update_overlays() . = ..() if(panel_open) . += "[base_icon_state]_open" - if(active) - . += "[base_icon_state]_on" - if(overlay_flags & EMISSIVE_OVERLAY) - . += emissive_appearance(icon, "[base_icon_state]_on", src) - else if(!(overlay_flags & NO_INACTIVE_OVERLAY)) - . += "[base_icon_state]_off" - + set_overlays(.) /** * Handles all the calculations needed for the gases, work done, temperature increase/decrease @@ -156,7 +165,7 @@ /obj/machinery/power/turbine/screwdriver_act(mob/living/user, obj/item/tool) . = ITEM_INTERACT_BLOCKING - if(active) + if(is_active()) balloon_alert(user, "turn it off!") return if(!anchored) @@ -183,10 +192,6 @@ if(default_deconstruction_crowbar(tool)) return ITEM_INTERACT_SUCCESS -/obj/machinery/power/turbine/on_deconstruction(disassembled) - installed_part?.forceMove(loc) - return ..() - /obj/machinery/power/turbine/crowbar_act_secondary(mob/living/user, obj/item/tool) . = ITEM_INTERACT_BLOCKING if(!panel_open) @@ -195,7 +200,7 @@ if(!installed_part) balloon_alert(user, "no rotor installed!") return - if(active) + if(is_active()) balloon_alert(user, "[src] is on!") return @@ -210,7 +215,11 @@ * * check_only - if TRUE it will not activate the machine but will only check if it can be activated */ /obj/machinery/power/turbine/proc/activate_parts(mob/user, check_only = FALSE) - can_connect = TRUE + SHOULD_CALL_PARENT(TRUE) + + set_machine_stat(machine_stat & ~MAINT) + + return TRUE /** * Allow easy disabling of each machine from the main controller @@ -219,13 +228,18 @@ * * mob/user - the player who deactivated the parts */ /obj/machinery/power/turbine/proc/deactivate_parts(mob/user) - can_connect = FALSE + SHOULD_CALL_PARENT(TRUE) + + set_machine_stat(machine_stat | MAINT) + + return TRUE /obj/machinery/power/turbine/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() set_panel_open(TRUE) - update_appearance() + update_appearance(UPDATE_OVERLAYS) deactivate_parts() + old_loc.air_update_turf(TRUE) air_update_turf(TRUE) /obj/machinery/power/turbine/Exited(atom/movable/gone, direction) @@ -236,10 +250,10 @@ /obj/machinery/power/turbine/item_interaction(mob/living/user, obj/item/turbine_parts/object, list/modifiers) . = NONE if(!istype(object, part_path)) - return ..() + return - //not in a state to accep the part. return TRUE so we don't bash the machine and damage it - if(active) + //not in a state to accept the part. block so we don't bash the machine and damage it + if(is_active()) balloon_alert(user, "turn off the machine first!") return ITEM_INTERACT_BLOCKING if(!panel_open) @@ -256,13 +270,9 @@ balloon_alert(user, "installed new part") user.transferItemToLoc(object, src) installed_part = object - return ITEM_INTERACT_SUCCESS - -/// Gets the efficiency of the installed part, returns 0 if no part is installed -/obj/machinery/power/turbine/proc/get_efficiency() - SHOULD_BE_PURE(TRUE) + efficiency = installed_part.get_tier_value(TURBINE_MAX_EFFICIENCY) - return installed_part?.part_efficiency || 0 + return ITEM_INTERACT_SUCCESS /obj/machinery/power/turbine/inlet_compressor name = "inlet compressor" @@ -287,6 +297,9 @@ //Volume of gas mixture is 1000 return ..(mapload, gas_theoretical_volume = 1000) +/obj/machinery/power/turbine/inlet_compressor/is_active() + return QDELETED(rotor) ? FALSE : rotor.is_active() + /obj/machinery/power/turbine/inlet_compressor/deactivate_parts(mob/user) . = ..() if(!QDELETED(rotor)) @@ -337,6 +350,9 @@ //Volume of gas mixture is 6000 return ..(mapload, gas_theoretical_volume = 6000) +/obj/machinery/power/turbine/turbine_outlet/is_active() + return QDELETED(rotor) ? FALSE : rotor.is_active() + /obj/machinery/power/turbine/turbine_outlet/deactivate_parts(mob/user) . = ..() if(!QDELETED(rotor)) @@ -354,7 +370,7 @@ if(!TURF_SHARES(output_turf)) return FALSE - //eject gases and update turf is any was ejected + //eject gases and update turf if any was ejected var/datum/gas_mixture/ejected_gases = machine_gasmix.pump_gas_to(output_turf.air, machine_gasmix.return_pressure()) if(ejected_gases) output_turf.air_update_turf(TRUE) @@ -372,10 +388,11 @@ can_change_cable_layer = TRUE circuit = /obj/item/circuitboard/machine/turbine_rotor part_path = /obj/item/turbine_parts/rotor - overlay_flags = EMISSIVE_OVERLAY | NO_INACTIVE_OVERLAY ///ID to easily connect the main part of the turbine to the computer var/mapping_id + ///Checks if the machine is processing or not + var/active = FALSE ///Reference to the compressor var/obj/machinery/power/turbine/inlet_compressor/compressor ///Reference to the turbine @@ -433,6 +450,15 @@ if(!all_parts_connected) . += span_warning("The parts need to be linked via a [EXAMINE_HINT("multitool")]") +///Adds overlays to this turbines appearance +/obj/machinery/power/turbine/core_rotor/set_overlays(list/overlays) + if(active) + overlays += "[base_icon_state]_on" + overlays += emissive_appearance(icon, "[base_icon_state]_on", src) + +/obj/machinery/power/turbine/core_rotor/is_active() + return active + /obj/machinery/power/turbine/core_rotor/cable_layer_act(mob/living/user, obj/item/tool) if(!panel_open) balloon_alert(user, "open panel first!") @@ -485,6 +511,11 @@ if(!check_only && all_parts_connected) return TRUE + //are we broken + if(machine_stat & BROKEN) + feedback(user, "rotor is broken!") + return (all_parts_connected = FALSE) + //locate compressor & turbine, when checking we simply check to see if they are still there if(!check_only) compressor = locate() in get_step(src, REVERSE_DIR(dir)) @@ -507,9 +538,12 @@ if(compressor.dir != dir && compressor.dir != REVERSE_DIR(dir)) //make sure it's not perpendicular to the rotor feedback(user, "compressor not aligned with rotor!") return (all_parts_connected = FALSE) - if(!compressor.can_connect) + if(compressor.machine_stat & MAINT) feedback(user, "close compressor panel!") return (all_parts_connected = FALSE) + if(compressor.machine_stat & BROKEN) + feedback(user, "compressor is broken!") + return (all_parts_connected = FALSE) if(!compressor.installed_part) feedback(user, "compressor has a missing part!") return (all_parts_connected = FALSE) @@ -521,8 +555,11 @@ if(turbine.dir != dir && turbine.dir != REVERSE_DIR(dir)) //make sure it's not perpendicular to the rotor feedback(user, "turbine not aligned with rotor!") return (all_parts_connected = FALSE) - if(!turbine.can_connect) - feedback(user, "close turbine panel!") //we say misplaced because can_connect becomes FALSE when this turbine is moved + if(turbine.machine_stat & MAINT) + feedback(user, "close turbine panel!") + return (all_parts_connected = FALSE) + if(turbine.machine_stat & BROKEN) + feedback(user, "turbine is broken!") return (all_parts_connected = FALSE) if(!turbine.installed_part) feedback(user, "turbine is missing stator part!") @@ -540,15 +577,13 @@ compressor.rotor = src turbine.rotor = src - max_allowed_rpm = (compressor.installed_part.max_rpm + turbine.installed_part.max_rpm + installed_part.max_rpm) / 3 - max_allowed_temperature = (compressor.installed_part.max_temperature + turbine.installed_part.max_temperature + installed_part.max_temperature) / 3 + max_allowed_rpm = (compressor.installed_part.get_tier_value(TURBINE_MAX_RPM) + turbine.installed_part.get_tier_value(TURBINE_MAX_RPM) + installed_part.get_tier_value(TURBINE_MAX_RPM)) / 3 + max_allowed_temperature = (compressor.installed_part.get_tier_value(TURBINE_MAX_TEMP) + turbine.installed_part.get_tier_value(TURBINE_MAX_TEMP) + installed_part.get_tier_value(TURBINE_MAX_TEMP)) / 3 connect_to_network() - return TRUE + return ..() -/** - * Allows to null the various machines and references from the main core - */ +///Allows to null the various machines and references from the main core /obj/machinery/power/turbine/core_rotor/deactivate_parts() toggle_power(force_off = TRUE) compressor?.rotor = null @@ -556,8 +591,12 @@ turbine?.rotor = null turbine = null all_parts_connected = FALSE + rpm = 0 + produced_energy = 0 disconnect_from_network() + return ..() + /obj/machinery/power/turbine/core_rotor/on_deconstruction(disassembled) deactivate_parts() return ..() @@ -577,10 +616,8 @@ //update operation status of parts update_appearance(UPDATE_OVERLAYS) if(!QDELETED(compressor)) - compressor.active = active compressor.update_appearance(UPDATE_OVERLAYS) if(!QDELETED(turbine)) - turbine.active = active turbine.update_appearance(UPDATE_OVERLAYS) //start or stop processing @@ -595,12 +632,10 @@ /obj/machinery/power/turbine/core_rotor/proc/get_turbine_integrity() SHOULD_NOT_OVERRIDE(TRUE) - var/integrity = damage / 500 - integrity = max(round(100 - integrity * 100, 0.01), 0) - return integrity + return max(round(100 - (damage / 500) * 100, 0.01), 0) /obj/machinery/power/turbine/core_rotor/process(seconds_per_tick) - if(!active || !activate_parts(check_only = TRUE) || (machine_stat & BROKEN) || !powered(ignore_use_power = TRUE)) + if(!active || !activate_parts(check_only = TRUE) || !powered(ignore_use_power = TRUE)) deactivate_parts() return PROCESS_KILL @@ -622,16 +657,16 @@ var/integrity = get_turbine_integrity() if(integrity <= 0) deactivate_parts() - if(rpm < 35000) + if(rpm < TURBINE_MAX_BASE_RPM) explosion(src, 0, 1, 4) return PROCESS_KILL - if(rpm < 87500) + if(rpm < TURBINE_MAX_BASE_RPM * 2.5) explosion(src, 0, 2, 6) return PROCESS_KILL - if(rpm < 220000) + if(rpm < TURBINE_MAX_BASE_RPM * 2.5 * 2.5) explosion(src, 1, 3, 7) return PROCESS_KILL - if(rpm < 550000) + if(rpm < TURBINE_MAX_BASE_RPM * 2.5 * 2.5 * 2.5) explosion(src, 2, 5, 7) return PROCESS_KILL @@ -655,7 +690,7 @@ //removing the work needed to move the compressor but adding back the turbine work that is the one generating most of the power. work_done = max(work_done - compressor.compressor_work * TURBINE_COMPRESSOR_STATOR_INTERACTION_MULTIPLIER - turbine_work, 0) //calculate final acheived rpm - rpm = ((work_done * compressor.get_efficiency()) ** turbine.get_efficiency()) * get_efficiency() / TURBINE_RPM_CONVERSION + rpm = ((work_done * compressor.efficiency) ** turbine.efficiency) * efficiency / TURBINE_RPM_CONVERSION rpm = min(ROUND_UP(rpm), max_allowed_rpm) //add energy into the grid, also use part of it for turbine operation produced_energy = rpm * TURBINE_ENERGY_RECTIFICATION_MULTIPLIER * TURBINE_RPM_CONVERSION * seconds_per_tick @@ -674,5 +709,3 @@ #undef PRESSURE_MAX #undef MINIMUM_TURBINE_PRESSURE -#undef EMISSIVE_OVERLAY -#undef NO_INACTIVE_OVERLAY diff --git a/code/modules/power/turbine/turbine_parts.dm b/code/modules/power/turbine/turbine_parts.dm index e568f9e096469..2da60eff13166 100644 --- a/code/modules/power/turbine/turbine_parts.dm +++ b/code/modules/power/turbine/turbine_parts.dm @@ -9,20 +9,12 @@ icon = 'icons/obj/machines/engine/turbine.dmi' icon_state = "inlet_compressor" - ///Efficiency of the part to the turbine machine - var/part_efficiency = 0 - ///Efficiency increase amount for each tier - var/part_efficiency_increase_amount = 0 ///Current part tier var/current_tier = TURBINE_PART_TIER_ONE - ///Max rpm reachable by the part - var/max_rpm = 35000 - ///Max temperature achievable by the part before the turbine starts to take damage - var/max_temperature = 50000 /obj/item/turbine_parts/examine(mob/user) . = ..() - . += span_notice("This is a tier [current_tier] turbine part, rated for [max_rpm] rpm and [max_temperature] K.") + . += span_notice("This is a tier [current_tier] turbine part, rated for [get_tier_value(TURBINE_MAX_RPM)] rpm and [get_tier_value(TURBINE_MAX_TEMP)] K.") var/list/required_parts = get_tier_upgrades() if(length(required_parts)) @@ -31,6 +23,35 @@ else . += span_notice("Is already at max tier.") +/** + * Returns the max values of various attributes of this turbine based on its tier + * param - see code/__DEFINES/turbine_defines/.dm + */ +/obj/item/turbine_parts/proc/get_tier_value(param) + SHOULD_BE_PURE(TRUE) + + var/max_value = 0 + for(var/_ in 1 to current_tier) + switch(param) + if(TURBINE_MAX_RPM) + if(!max_value) + max_value = TURBINE_MAX_BASE_RPM + else + max_value *= 2.5 + + if(TURBINE_MAX_TEMP) + if(!max_value) + max_value = 50000 + else + max_value = max_value ** 1.2 + + if(TURBINE_MAX_EFFICIENCY) + if(!max_value) + max_value = 0.25 + else + max_value += 0.2 + return max_value + ///Returns a list containing the typepath & amount of it required to upgrade to the next tier /obj/item/turbine_parts/proc/get_tier_upgrades() PROTECTED_PROC(TRUE) @@ -65,31 +86,34 @@ if(do_after(user, current_tier SECONDS, src) && material.use(amount)) current_tier += 1 - part_efficiency += part_efficiency_increase_amount - max_rpm *= 2.5 - max_temperature = max_temperature ** 1.2 return ITEM_INTERACT_SUCCESS /obj/item/turbine_parts/compressor name = "compressor part" desc = "Install in a turbine engine compressor to increase its performance" icon_state = "compressor_part" - part_efficiency = 0.25 - part_efficiency_increase_amount = 0.2 /obj/item/turbine_parts/rotor name = "rotor part" desc = "Install in a turbine engine rotor to increase its performance" icon_state = "rotor_part" - part_efficiency = 0.25 - part_efficiency_increase_amount = 0.2 /obj/item/turbine_parts/stator name = "stator part" desc = "Install in a turbine engine turbine to increase its performance" icon_state = "stator_part" - part_efficiency = 0.85 - part_efficiency_increase_amount = 0.015 + +/obj/item/turbine_parts/stator/get_tier_value(param) + if(param == TURBINE_MAX_EFFICIENCY) + var/max_value = 0 + for(var/_ in 1 to current_tier) + if(!max_value) + max_value = 0.85 + else + max_value += 0.015 + return max_value + + return ..() /obj/item/turbine_parts/stator/get_tier_upgrades() switch(current_tier) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm index 2492f0d4276f5..a3de2f4b2fe2a 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm @@ -14,7 +14,7 @@ . = ..() atom_storage.numerical_stacking = TRUE atom_storage.max_specific_storage = WEIGHT_CLASS_TINY - atom_storage.max_slots = 40 + atom_storage.max_slots = max_slots atom_storage.max_total_storage = 100 atom_storage.set_holdable(/obj/item/ammo_casing/arrow) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 7176b4c13370e..e238ebdd37402 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -12,8 +12,6 @@ var/taste_mult = 1 /// reagent holder this belongs to var/datum/reagents/holder = null - /// LIQUID, SOLID, GAS - var/reagent_state = LIQUID /// Special data associated with the reagent that will be passed on upon transfer to a new holder. var/list/data /// increments everytime on_mob_life is called diff --git a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm index 5728f6cb24db6..58ed84f53dcd1 100644 --- a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm @@ -1,7 +1,6 @@ /datum/reagent/freon name = "Freon" description = "A powerful heat absorbent." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 // Because nitrium/freon/hypernoblium are handled through gas breathing, metabolism must be lower for breathcode to keep up color = "90560B" taste_description = "burning" @@ -18,7 +17,6 @@ /datum/reagent/halon name = "Halon" description = "A fire suppression gas that removes oxygen and cools down the area" - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 color = "90560B" taste_description = "minty" @@ -36,7 +34,6 @@ /datum/reagent/healium name = "Healium" description = "A powerful sleeping agent with healing properties" - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 color = "90560B" taste_description = "rubbery" @@ -59,7 +56,6 @@ /datum/reagent/hypernoblium name = "Hyper-Noblium" description = "A suppressive gas that stops gas reactions on those who inhale it." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 // Because nitrium/freon/hyper-nob are handled through gas breathing, metabolism must be lower for breathcode to keep up color = "90560B" taste_description = "searingly cold" @@ -73,7 +69,6 @@ /datum/reagent/nitrium_high_metabolization name = "Nitrosyl plasmide" description = "A highly reactive byproduct that stops you from sleeping, while dealing increasing toxin damage over time." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 // Because nitrium/freon/hypernoblium are handled through gas breathing, metabolism must be lower for breathcode to keep up color = "E1A116" taste_description = "sourness" @@ -93,7 +88,6 @@ /datum/reagent/nitrium_low_metabolization name = "Nitrium" description = "A highly reactive gas that makes you feel faster." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 // Because nitrium/freon/hypernoblium are handled through gas breathing, metabolism must be lower for breathcode to keep up color = "90560B" taste_description = "burning" @@ -111,7 +105,6 @@ /datum/reagent/pluoxium name = "Pluoxium" description = "A gas that is eight times more efficient than O2 at lung diffusion with organ healing properties on sleeping patients." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 color = COLOR_GRAY taste_description = "irradiated air" @@ -132,7 +125,6 @@ /datum/reagent/zauker name = "Zauker" description = "An unstable gas that is toxic to all living beings." - reagent_state = GAS metabolization_rate = REAGENTS_METABOLISM * 0.5 color = "90560B" taste_description = "bitter" diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 2093491015641..c3b68b98b9ee5 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -18,7 +18,6 @@ taste_description = "cold and lifeless" ph = 8 overdose_threshold = 35 - reagent_state = SOLID inverse_chem_val = 0.3 inverse_chem = /datum/reagent/inverse/helgrasp var/helbent = FALSE @@ -104,7 +103,6 @@ color = "#ECEC8D" // rgb: 236 236 141 ph = 8.2 taste_description = "bitter with a hint of alcohol" - reagent_state = SOLID inverse_chem_val = 0.3 inverse_chem = /datum/reagent/inverse/libitoil chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -120,7 +118,6 @@ /datum/reagent/medicine/c2/probital name = "Probital" description = "Originally developed as a prototype-gym supliment for those looking for quick workout turnover, this oral medication quickly repairs broken muscle tissue but causes lactic acid buildup, tiring the patient. Overdosing can cause extreme drowsiness. An Influx of nutrients promotes the muscle repair even further." - reagent_state = SOLID color = "#FFFF6B" ph = 5.5 overdose_threshold = 20 @@ -171,7 +168,6 @@ /datum/reagent/medicine/c2/lenturi name = "Lenturi" description = "Used to treat burns. Applies stomach damage when it leaves your system." - reagent_state = LIQUID color = "#6171FF" ph = 4.7 var/resetting_probability = 0 //What are these for?? Can I remove them? @@ -180,7 +176,6 @@ inverse_chem_val = 0.4 inverse_chem = /datum/reagent/inverse/lentslurri - /datum/reagent/medicine/c2/lenturi/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/need_mob_update @@ -192,7 +187,6 @@ /datum/reagent/medicine/c2/aiuri name = "Aiuri" description = "Used to treat burns. Does minor eye damage." - reagent_state = LIQUID color = "#8C93FF" ph = 4 var/resetting_probability = 0 //same with this? Old legacy vars that should be removed? @@ -212,7 +206,6 @@ /datum/reagent/medicine/c2/hercuri name = "Hercuri" description = "Not to be confused with element Mercury, this medicine excels in reverting effects of dangerous high-temperature environments. Prolonged exposure can cause hypothermia." - reagent_state = LIQUID color = "#F7FFA5" overdose_threshold = 25 reagent_weight = 0.6 @@ -262,7 +255,6 @@ /datum/reagent/medicine/c2/convermol name = "Convermol" description = "Restores oxygen deprivation while producing a lesser amount of toxic byproducts. Both scale with exposure to the drug and current amount of oxygen deprivation. Overdose causes toxic byproducts regardless of oxygen deprivation." - reagent_state = LIQUID color = "#FF6464" overdose_threshold = 35 // at least 2 full syringes +some, this stuff is nasty if left in for long ph = 5.6 @@ -407,7 +399,6 @@ /datum/reagent/medicine/c2/syriniver //Inject >> SYRINge name = "Syriniver" description = "A potent antidote for intravenous use with a narrow therapeutic index, it is considered an active prodrug of musiver." - reagent_state = LIQUID color = "#8CDF24" // heavy saturation to make the color blend better metabolization_rate = 0.75 * REAGENTS_METABOLISM overdose_threshold = 6 @@ -452,7 +443,6 @@ /datum/reagent/medicine/c2/musiver //MUScles name = "Musiver" description = "The active metabolite of syriniver. Causes muscle weakness on overdose" - reagent_state = LIQUID color = "#DFD54E" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 25 @@ -494,7 +484,6 @@ /datum/reagent/medicine/c2/synthflesh name = "Synthflesh" description = "Heals brute and burn damage at the cost of toxicity (66% of damage healed). 100u or more can restore corpses husked by burns. Touch application only." - reagent_state = LIQUID color = "#FFEBEB" ph = 7.2 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED diff --git a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm index 21bb32e0d6556..529d671976372 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm @@ -700,7 +700,6 @@ /datum/reagent/consumable/ice name = "Ice" description = "Frozen water, your dentist wouldn't like you chewing this." - reagent_state = SOLID color = "#619494" // rgb: 97, 148, 148 taste_description = "ice" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 4a4bf137b3c4d..97f81c76a48b8 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -65,7 +65,6 @@ /datum/reagent/drug/nicotine name = "Nicotine" description = "Slightly reduces stun times. If overdosed it will deal toxin and oxygen damage." - reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 taste_description = "smoke" trippy = FALSE @@ -102,14 +101,12 @@ /datum/reagent/drug/krokodil name = "Krokodil" description = "Cools and calms you down. If overdosed it will deal significant Brain and Toxin damage." - reagent_state = LIQUID color = "#0064B4" overdose_threshold = 20 ph = 9 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED addiction_types = list(/datum/addiction/opioids = 18) //7.2 per 2 seconds - /datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/high_message = pick("You feel calm.", "You feel collected.", "You feel like you need to relax.") @@ -137,7 +134,6 @@ /datum/reagent/drug/methamphetamine name = "Methamphetamine" description = "Reduces stun times by about 300%, speeds the user up, and allows the user to quickly recover stamina while dealing a small amount of Brain damage. If overdosed the subject will move randomly, laugh randomly, drop items and suffer from Toxin and Brain damage. If addicted the subject will constantly jitter and drool, before becoming dizzy and losing motor control and eventually suffer heavy toxin damage." - reagent_state = LIQUID color = "#78C8FA" //best case scenario is the "default", gets muddled depending on purity overdose_threshold = 20 metabolization_rate = 0.75 * REAGENTS_METABOLISM @@ -204,7 +200,6 @@ /datum/reagent/drug/bath_salts name = "Bath Salts" description = "Makes you impervious to stuns and grants a stamina regeneration buff, but you will be a nearly uncontrollable tramp-bearded raving lunatic." - reagent_state = LIQUID color = "#FAFAFA" overdose_threshold = 20 taste_description = "salt" // because they're bathsalts? @@ -256,7 +251,6 @@ /datum/reagent/drug/aranesp name = "Aranesp" description = "Amps you up, gets you going, and rapidly restores stamina damage. Side effects include breathlessness and toxicity." - reagent_state = LIQUID color = "#78FFF0" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED addiction_types = list(/datum/addiction/stimulants = 8) @@ -279,7 +273,6 @@ /datum/reagent/drug/happiness name = "Happiness" description = "Fills you with ecstasic numbness and causes minor brain damage. Highly addictive. If overdosed causes sudden mood swings." - reagent_state = LIQUID color = "#EE35FF" overdose_threshold = 20 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -323,7 +316,6 @@ /datum/reagent/drug/pumpup name = "Pump-Up" description = "Take on the world! A fast acting, hard hitting drug that pushes the limit on what you can handle." - reagent_state = LIQUID color = "#e38e44" metabolization_rate = 2 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -388,7 +380,6 @@ /datum/reagent/drug/maint/powder name = "Maintenance Powder" description = "An unknown powder that you most likely gotten from an assistant, a bored chemist... or cooked yourself. It is a refined form of tar that enhances your mental ability, making you learn stuff a lot faster." - reagent_state = SOLID color = "#ffffff" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 15 @@ -416,7 +407,6 @@ /datum/reagent/drug/maint/sludge name = "Maintenance Sludge" description = "An unknown sludge that you most likely gotten from an assistant, a bored chemist... or cooked yourself. Half refined, it fills your body with itself, making it more resistant to wounds, but causes toxins to accumulate." - reagent_state = LIQUID color = "#203d2c" metabolization_rate = 2 * REAGENTS_METABOLISM overdose_threshold = 25 @@ -446,7 +436,6 @@ /datum/reagent/drug/maint/tar name = "Maintenance Tar" description = "An unknown tar that you most likely gotten from an assistant, a bored chemist... or cooked yourself. Raw tar, straight from the floor. It can help you with escaping bad situations at the cost of liver damage." - reagent_state = LIQUID color = COLOR_BLACK overdose_threshold = 30 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -552,7 +541,6 @@ /datum/reagent/drug/blastoff name = "bLaStOoF" description = "A drug for the hardcore party crowd said to enhance ones abilities on the dance floor.\nMost old heads refuse to touch this stuff, perhaps because memories of the luna discoteque incident are seared into their brains." - reagent_state = LIQUID color = "#9015a9" taste_description = "holodisk cleaner" ph = 5 @@ -678,7 +666,6 @@ /datum/reagent/drug/saturnx name = "Saturn-X" description = "This compound was first discovered during the infancy of cloaking technology and at the time thought to be a promising candidate agent. It was withdrawn for consideration after the researchers discovered a slew of associated safety issues including thought disorders and hepatoxicity." - reagent_state = SOLID taste_description = "metallic bitterness" color = "#638b9b" overdose_threshold = 25 @@ -779,7 +766,6 @@ /datum/reagent/drug/kronkaine name = "Kronkaine" description = "A highly illegal stimulant from the edge of the galaxy.\nIt is said the average kronkaine addict causes as much criminal damage as five stick up men, two rascals and one proferssional cambringo hustler combined." - reagent_state = SOLID color = "#FAFAFA" taste_description = "numbing bitterness" ph = 8 diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index c55f661c67a8b..3b866fa2d7f3a 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -61,7 +61,6 @@ /datum/reagent/consumable/nutriment name = "Nutriment" description = "All the vitamins, minerals, and carbohydrates the body needs in pure form." - reagent_state = SOLID nutriment_factor = 15 color = "#664330" // rgb: 102, 67, 48 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -129,7 +128,6 @@ description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." taste_description = "bitterness" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED - brute_heal = 1 burn_heal = 1 @@ -292,7 +290,6 @@ /datum/reagent/consumable/sugar name = "Sugar" description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste." - reagent_state = SOLID color = COLOR_WHITE // rgb: 255, 255, 255 taste_mult = 1.5 // stop sugar drowning out other flavours nutriment_factor = 2 @@ -472,7 +469,6 @@ /datum/reagent/consumable/salt name = "Table Salt" description = "A salt made of sodium chloride. Commonly used to season food." - reagent_state = SOLID color = COLOR_WHITE // rgb: 255,255,255 taste_description = "salt" penetrates_skin = NONE @@ -523,7 +519,6 @@ /datum/reagent/consumable/blackpepper name = "Black Pepper" description = "A powder ground from peppercorns. *AAAACHOOO*" - reagent_state = SOLID // no color (ie, black) taste_description = "pepper" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -532,7 +527,6 @@ /datum/reagent/consumable/coco name = "Coco Powder" description = "A fatty, bitter paste made from coco beans." - reagent_state = SOLID nutriment_factor = 5 color = "#302000" // rgb: 48, 32, 0 taste_description = "bitterness" @@ -609,7 +603,6 @@ /datum/reagent/consumable/dry_ramen name = "Dry Ramen" description = "Space age food, since August 25, 1958. Contains dried noodles, vegetables, and chemicals that boil in contact with water." - reagent_state = SOLID color = "#302000" // rgb: 48, 32, 0 taste_description = "dry and cheap noodles" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -651,7 +644,6 @@ /datum/reagent/consumable/flour name = "Flour" description = "This is what you rub all over yourself to pretend to be a ghost." - reagent_state = SOLID color = COLOR_WHITE // rgb: 0, 0, 0 taste_description = "chalky wheat" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS @@ -715,7 +707,6 @@ /datum/reagent/consumable/rice name = "Rice" description = "tiny nutritious grains" - reagent_state = SOLID nutriment_factor = 3 color = COLOR_WHITE // rgb: 0, 0, 0 taste_description = "rice" @@ -725,7 +716,6 @@ /datum/reagent/consumable/rice_flour name = "Rice Flour" description = "Flour mixed with Rice" - reagent_state = SOLID color = COLOR_WHITE // rgb: 0, 0, 0 taste_description = "chalky wheat with rice" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -733,7 +723,7 @@ /datum/reagent/consumable/vanilla name = "Vanilla Powder" description = "A fatty, bitter paste made from vanilla pods." - reagent_state = SOLID + nutriment_factor = 5 color = "#FFFACD" taste_description = "vanilla" @@ -892,7 +882,6 @@ /datum/reagent/consumable/nutriment/stabilized name = "Stabilized Nutriment" description = "A bioengineered protien-nutrient structure designed to decompose in high saturation. In layman's terms, it won't get you fat." - reagent_state = SOLID nutriment_factor = 15 color = "#664330" // rgb: 102, 67, 48 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1005,7 +994,6 @@ description = "A space age artifical sweetener." nutriment_factor = 0 metabolization_rate = 2 * REAGENTS_METABOLISM - reagent_state = SOLID color = COLOR_WHITE // rgb: 255, 255, 255 taste_mult = 8 taste_description = "sweetness" @@ -1046,7 +1034,6 @@ color = "#D98736" taste_mult = 2 taste_description = "caramel" - reagent_state = SOLID chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/caramel/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) @@ -1057,7 +1044,6 @@ /datum/reagent/consumable/char name = "Char" description = "Essence of the grill. Has strange properties when overdosed." - reagent_state = LIQUID nutriment_factor = 5 color = "#C8C8C8" taste_mult = 6 @@ -1172,7 +1158,6 @@ name = "Peanut Butter" description = "A rich, creamy spread produced by grinding peanuts." taste_description = "peanuts" - reagent_state = SOLID color = "#D9A066" nutriment_factor = 15 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm index b9c0ee0522dfa..0f4642509771d 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm @@ -92,7 +92,6 @@ /datum/reagent/inverse/cryostylane name = "Cryogelidia" description = "Freezes the live or dead patient in a cryostasis ice block." - reagent_state = LIQUID color = "#03dbfc" taste_description = "your tongue freezing, shortly followed by your thoughts. Brr!" ph = 14 diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index ebd392f536892..0b5d297669dbb 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -174,7 +174,6 @@ Basically, we fill the time between now and 2s from now with hands based off the name = "Metabolic Inhibition Factor" description = "This enzyme catalyzes crashes the conversion of nutricious food into healing peptides." metabolization_rate = 0.0625 * REAGENTS_METABOLISM //slow metabolism rate so the patient can self heal with food even after the troph has metabolized away for amazing reagent efficency. - reagent_state = SOLID color = "#b3ff00" overdose_threshold = 10 ph = 1 @@ -694,7 +693,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/oculine name = "Oculater" description = "Temporarily blinds the patient." - reagent_state = LIQUID color = "#DDDDDD" metabolization_rate = 0.1 * REM addiction_types = list(/datum/addiction/medicine = 3) @@ -723,7 +721,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/impurity/inacusiate name = "Tinacusiate" description = "Makes the patient's hearing temporarily funky." - reagent_state = LIQUID addiction_types = list(/datum/addiction/medicine = 5.6) color = "#DDDDFF" taste_description = "the heat evaporating from your mouth." @@ -764,7 +761,6 @@ Basically, we fill the time between now and 2s from now with hands based off the name = "Benzoic Acid" description = "Robust fertilizer that provides a decent range of benefits for plant life." taste_description = "flowers" - reagent_state = LIQUID color = "#e6c843" ph = 3.4 tox_damage = 0 @@ -778,7 +774,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/oxandrolone name = "Oxymetholone" description = "Anabolic steroid that promotes the growth of muscle during and after exercise." - reagent_state = LIQUID color = "#520c23" taste_description = "sweat" metabolization_rate = 0.4 * REM @@ -805,7 +800,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/salbutamol name = "Bamethan" description = "Blood thinner that drastically increases the chance of receiving bleeding wounds." - reagent_state = LIQUID color = "#ecd4d6" taste_description = "paint thinner" ph = 4.5 @@ -816,7 +810,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/pen_acid name = "Pendetide" description = "Purges basic toxin healing medications and increases the severity of radiation poisoning." - reagent_state = LIQUID color = "#09ff00" ph = 3.7 taste_description = "venom" @@ -839,7 +832,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/atropine name = "Hyoscyamine" description = "Slowly regenerates all damaged organs, but cannot restore non-functional organs." - reagent_state = LIQUID color = "#273333" ph = 13.6 metabolization_rate = 0.2 * REM @@ -875,7 +867,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/ammoniated_mercury name = "Ammoniated Sludge" description = "A ghastly looking mess of mercury by-product. Causes bursts of manic hysteria." - reagent_state = LIQUID color = "#353535" ph = 10.2 metabolization_rate = 0.4 * REM @@ -890,7 +881,6 @@ Basically, we fill the time between now and 2s from now with hands based off the /datum/reagent/inverse/rezadone name = "Inreziniver" description = "Makes the user horribly afraid of all things related to carps." - reagent_state = LIQUID color = "#c92eb4" ph = 13.9 metabolization_rate = 0.05 * REM diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm index 4e904dcf684d3..4a3d837f1db09 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm @@ -22,7 +22,6 @@ /datum/reagent/impurity/methanol name = "Methanol" description = "A light, colourless liquid with a distinct smell. Ingestion can lead to blindness. It is a byproduct of organisms processing impure Formaldehyde." - reagent_state = LIQUID color = "#aae7e4" ph = 7 liver_damage = 0 @@ -37,7 +36,6 @@ /datum/reagent/impurity/chloralax name = "Chloralax" description = "An oily, colorless and slightly toxic liquid. It is produced when impure choral hydrate is broken down inside an organism." - reagent_state = LIQUID color = "#387774" ph = 7 liver_damage = 0 @@ -51,7 +49,6 @@ /datum/reagent/impurity/rosenol name = "Rosenol" description = "A strange, blue liquid that is produced during impure mindbreaker toxin reactions. Historically it has been abused to write poetry." - reagent_state = LIQUID color = "#0963ad" ph = 7 liver_damage = 0 diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index a60b4c171b703..d69b3712539b4 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -205,7 +205,6 @@ /datum/reagent/medicine/rezadone name = "Rezadone" description = "A powder derived from fish toxin, Rezadone can effectively restore corpses husked by burns as well as treat minor wounds. Overdose will cause intense nausea and minor toxin damage." - reagent_state = SOLID color = "#669900" // rgb: 102, 153, 0 overdose_threshold = 30 ph = 12.2 @@ -257,7 +256,6 @@ /datum/reagent/medicine/oxandrolone name = "Oxandrolone" description = "Stimulates the healing of severe burns. Extremely rapidly heals severe burns and slowly heals minor ones. Overdose will worsen existing burns." - reagent_state = LIQUID color = "#1E8BFF" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 @@ -285,7 +283,6 @@ /datum/reagent/medicine/salglu_solution name = "Saline-Glucose Solution" description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute, as well as slowly speeding blood regeneration." - reagent_state = LIQUID color = "#DCDCDC" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 @@ -335,7 +332,6 @@ /datum/reagent/medicine/mine_salve name = "Miner's Salve" description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed. Also great for treating severe burn wounds in a pinch." - reagent_state = LIQUID color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM ph = 2.6 @@ -383,7 +379,6 @@ /datum/reagent/medicine/omnizine name = "Omnizine" description = "Slowly heals all damage types. Overdose will cause damage in all types instead." - reagent_state = LIQUID color = "#DCDCDC" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -422,7 +417,6 @@ name = "Calomel" description = "Quickly purges the body of all chemicals except itself. The more health a person has, \ the more toxin damage it will deal. It can heal toxin damage when people have low enough health." - reagent_state = LIQUID color = "#c85319" metabolization_rate = 1 * REAGENTS_METABOLISM taste_description = "acid" @@ -451,7 +445,6 @@ description = "Quickly purges the body of toxic chemicals. Heals toxin damage when in a good condition someone has \ no brute and fire damage. When hurt with brute or fire damage, it can deal a great amount of toxin damage. \ When there are no toxins present, it starts slowly purging itself." - reagent_state = LIQUID color = "#f3f1f0" metabolization_rate = 0.1 * REAGENTS_METABOLISM taste_description = "metallic" @@ -482,7 +475,6 @@ /datum/reagent/medicine/potass_iodide name = "Potassium Iodide" description = "Heals low toxin damage while the patient is irradiated, and will halt the damaging effects of radiation." - reagent_state = LIQUID color = "#BAA15D" metabolization_rate = 2 * REAGENTS_METABOLISM ph = 12 //It's a reducing agent @@ -498,7 +490,6 @@ /datum/reagent/medicine/pen_acid name = "Pentetic Acid" description = "Reduces massive amounts of toxin damage while purging other chemicals from the body." - reagent_state = LIQUID color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM ph = 1 //One of the best buffers, NEVERMIND! @@ -518,7 +509,6 @@ /datum/reagent/medicine/sal_acid name = "Salicylic Acid" description = "Stimulates the healing of severe bruises. Extremely rapidly heals severe bruising and slowly heals minor ones. Overdose will worsen existing bruising." - reagent_state = LIQUID color = "#D2D2D2" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 @@ -546,7 +536,6 @@ /datum/reagent/medicine/salbutamol name = "Salbutamol" description = "Rapidly restores oxygen deprivation as well as preventing more of it to an extent." - reagent_state = LIQUID color = COLOR_CYAN metabolization_rate = 0.25 * REAGENTS_METABOLISM ph = 2 @@ -570,7 +559,6 @@ /datum/reagent/medicine/ephedrine name = "Ephedrine" description = "Increases resistance to batons and movement speed, giving you hand cramps. Overdose deals toxin damage and inhibits breathing." - reagent_state = LIQUID color = "#D2FFFA" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -624,7 +612,6 @@ /datum/reagent/medicine/diphenhydramine name = "Diphenhydramine" description = "Rapidly purges the body of Histamine and reduces jitteriness. Slight chance of causing drowsiness." - reagent_state = LIQUID color = "#64FFE6" metabolization_rate = 0.5 * REAGENTS_METABOLISM ph = 11.5 @@ -640,7 +627,6 @@ /datum/reagent/medicine/morphine name = "Morphine" description = "A painkiller that allows the patient to move at full speed even when injured. Causes drowsiness and eventually unconsciousness in high doses. Overdose will cause a variety of effects, ranging from minor to lethal." - reagent_state = LIQUID color = "#A9FBFB" metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -695,7 +681,6 @@ /datum/reagent/medicine/oculine name = "Oculine" description = "Quickly restores eye damage, cures nearsightedness, and has a chance to restore vision to the blind." - reagent_state = LIQUID color = "#404040" //oculine is dark grey, inacusiate is light grey metabolization_rate = 1 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -774,6 +759,63 @@ if(affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) . = UPDATE_MOB_HEALTH +/datum/reagent/medicine/oculine/flumpuline + name = "Flumpuline" + description = "Often confused for, or sold as, Oculine or a variation thereof. Slowly transmogrifies the eyes of the patient into grotesque stalks - but you'll never need glasses again." + color = "#6c596d" + metabolization_rate = 0.1 * REAGENTS_METABOLISM + overdose_threshold = 5 + taste_description = "fungus" + purity = 1 + ph = 0.01 + chemical_flags = REAGENT_DEAD_PROCESS|REAGENT_IGNORE_STASIS|REAGENT_NO_RANDOM_RECIPE|REAGENT_CAN_BE_SYNTHESIZED + inverse_chem = /datum/reagent/inverse + inverse_chem_val = 0 + var/static/list/eye_types = list(/obj/item/organ/eyes/snail, /obj/item/organ/eyes/night_vision/mushroom) + +/datum/reagent/medicine/oculine/flumpuline/improve_eyesight(mob/living/carbon/affected_mob, obj/item/organ/eyes/eyes) + delta_light = 200 //2x better than pure oculine + eyes.lighting_cutoff += delta_light + affected_mob.update_sight() + +/datum/reagent/medicine/oculine/flumpuline/restore_eyesight(mob/living/carbon/affected_mob, obj/item/organ/eyes/eyes) + eyes.lighting_cutoff -= delta_light + affected_mob.update_sight() + +/datum/reagent/medicine/oculine/flumpuline/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/obj/item/organ/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES) + // if no eyes or inorganic do nothing. we let already changed eyes go because funny + if(!eyes || !IS_ORGANIC_ORGAN(eyes)) + return . + + if(!prob(2)) + return . + + flump_eyes(affected_mob, eyes) + +// Overdose causes constant eye popping +/datum/reagent/medicine/oculine/flumpuline/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(!prob(25)) + return + var/obj/item/organ/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES) + + flump_eyes(affected_mob, eyes) + +/datum/reagent/medicine/oculine/flumpuline/proc/flump_eyes(mob/affected_mob, obj/eyes) + var/obj/item/organ/eyes/new_eyes = pick(eye_types) + new_eyes = new new_eyes(affected_mob) + new_eyes.Insert(affected_mob) + playsound(affected_mob, 'sound/effects/cartoon_sfx/cartoon_pop.ogg', 50, TRUE) + affected_mob.visible_message("[affected_mob]'s [eyes ? eyes : "eye holes"] suddenly sprout stalks and turn into [new_eyes]!") + ASYNC + affected_mob.emote("scream") + sleep(5 SECONDS) + if(!QDELETED(eyes)) + eyes.visible_message(span_danger("[eyes] rapidly turn to dust.")) + eyes.dust() + /datum/reagent/medicine/inacusiate name = "Inacusiate" description = "Rapidly repairs damage to the patient's ears to cure deafness, assuming the source of said deafness isn't from genetic mutations, chronic deafness, or a total defecit of ears." //by "chronic" deafness, we mean people with the "deaf" quirk @@ -808,7 +850,6 @@ /datum/reagent/medicine/atropine name = "Atropine" description = "If a patient is in critical condition, rapidly heals all damage types as well as regulating oxygen in the body. Excellent for stabilizing wounded patients, and said to neutralize blood-activated internal explosives found amongst clandestine black op agents." - reagent_state = LIQUID color = "#1D3535" //slightly more blue, like epinephrine metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 35 @@ -846,7 +887,6 @@ /datum/reagent/medicine/epinephrine name = "Epinephrine" description = "Very minor boost to stun resistance. Slowly heals damage if a patient is in critical condition, as well as regulating oxygen loss. Overdose causes weakness and toxin damage." - reagent_state = LIQUID color = "#D2FFFA" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -906,7 +946,6 @@ /datum/reagent/medicine/strange_reagent name = "Strange Reagent" description = "A miracle drug capable of bringing the dead back to life. Works topically unless anotamically complex, in which case works orally. Cannot revive targets under -%MAXHEALTHRATIO% health." - reagent_state = LIQUID color = "#A0E85E" metabolization_rate = 1.25 * REAGENTS_METABOLISM taste_description = "magnets" @@ -1022,7 +1061,6 @@ /datum/reagent/medicine/strange_reagent/fishy_reagent name = "Fishy Reagent" description = "This reagent has a chemical composition very similar to that of Strange Reagent, however, it seems to work purely and only on... fish. Or at least, aquatic creatures." - reagent_state = LIQUID color = "#5ee8b3" metabolization_rate = 1.25 * REAGENTS_METABOLISM taste_description = "magnetic scales" @@ -1221,7 +1259,6 @@ /datum/reagent/medicine/insulin name = "Insulin" description = "Increases sugar depletion rates." - reagent_state = LIQUID color = "#FFFFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM ph = 6.7 @@ -1237,7 +1274,6 @@ /datum/reagent/medicine/inaprovaline //is this used anywhere? name = "Inaprovaline" description = "Stabilizes the breathing of patients. Good for those in critical condition." - reagent_state = LIQUID color = "#A4D8D8" ph = 8.5 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE @@ -1251,7 +1287,6 @@ /datum/reagent/medicine/regen_jelly name = "Regenerative Jelly" description = "Gradually regenerates all types of damage, without harming slime anatomy." - reagent_state = LIQUID color = "#CC23FF" taste_description = "jelly" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1280,7 +1315,6 @@ /datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs name = "Restorative Nanites" description = "Miniature medical robots that swiftly restore bodily damage." - reagent_state = SOLID color = "#555555" overdose_threshold = 30 ph = 11 @@ -1369,7 +1403,6 @@ /datum/reagent/medicine/haloperidol name = "Haloperidol" description = "Increases depletion rates for most stimulating/hallucinogenic drugs. Reduces druggy effects and jitteriness. Severe stamina regeneration penalty, causes drowsiness. Small chance of brain damage." - reagent_state = LIQUID color = "#27870a" metabolization_rate = 0.4 * REAGENTS_METABOLISM ph = 4.3 @@ -1499,7 +1532,6 @@ /datum/reagent/medicine/modafinil name = "Modafinil" description = "Long-lasting sleep suppressant that very slightly reduces stun and knockdown times. Overdosing has horrendous side effects and deals lethal oxygen damage, will knock you unconscious if not dealt with." - reagent_state = LIQUID color = "#BEF7D8" // palish blue white metabolization_rate = 0.1 * REAGENTS_METABOLISM overdose_threshold = 20 // with the random effects this might be awesome or might kill you at less than 10u (extensively tested) @@ -1565,7 +1597,6 @@ /datum/reagent/medicine/psicodine name = "Psicodine" description = "Suppresses anxiety and other various forms of mental distress. Overdose causes hallucinations and minor toxin damage." - reagent_state = LIQUID color = "#07E79E" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -1592,7 +1623,6 @@ name = "Mitogen Metabolism Factor" description = "This enzyme catalyzes the conversion of nutricious food into healing peptides." metabolization_rate = 0.0625 * REAGENTS_METABOLISM //slow metabolism rate so the patient can self heal with food even after the troph has metabolized away for amazing reagent efficency. - reagent_state = SOLID color = "#FFBE00" overdose_threshold = 10 inverse_chem_val = 0.1 //Shouldn't happen - but this is so looking up the chem will point to the failed type @@ -1611,7 +1641,6 @@ /datum/reagent/medicine/silibinin name = "Silibinin" description = "A thistle derrived hepatoprotective flavolignan mixture that help reverse damage to the liver." - reagent_state = SOLID color = "#FFFFD0" metabolization_rate = 1.5 * REAGENTS_METABOLISM chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1624,7 +1653,6 @@ /datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems. name = "Polypyrylium Oligomers" description = "A purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals." - reagent_state = SOLID color = "#9423FF" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 50 @@ -1655,7 +1683,6 @@ name = "Granibitaluri" //achieve "GRANular" amounts of C2 description = "A mild painkiller useful as an additive alongside more potent medicines. Speeds up the healing of small wounds and burns, but is ineffective at treating severe injuries. Extremely large doses are toxic, and may eventually cause liver failure." color = "#E0E0E0" - reagent_state = LIQUID overdose_threshold = 50 metabolization_rate = 0.5 * REAGENTS_METABOLISM //same as C2s chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1681,7 +1708,6 @@ /datum/reagent/medicine/coagulant name = "Sanguirite" description = "A proprietary coagulant used to help bleeding wounds clot faster. It is purged by heparin." - reagent_state = LIQUID color = "#bb2424" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 20 @@ -1787,7 +1813,6 @@ /datum/reagent/medicine/ondansetron name = "Ondansetron" description = "Prevents nausea and vomiting. May cause drowsiness and wear." - reagent_state = LIQUID color = "#74d3ff" metabolization_rate = 0.5 * REAGENTS_METABOLISM ph = 10.6 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 6c4ba9d35e6de..b718ee94cc1c9 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -989,7 +989,6 @@ /datum/reagent/oxygen name = "Oxygen" description = "A colorless, odorless gas. Grows on trees but is still pretty valuable." - reagent_state = GAS color = COLOR_GRAY taste_mult = 0 // oderless and tasteless ph = 9.2//It's acutally a huge range and very dependant on the chemistry but ph is basically a made up var in its implementation anyways @@ -1005,7 +1004,6 @@ /datum/reagent/copper name = "Copper" description = "A highly ductile metal. Things made out of copper aren't very durable, but it makes a decent material for electrical wiring." - reagent_state = SOLID color = "#6E3B08" // rgb: 110, 59, 8 taste_description = "metal" ph = 5.5 @@ -1024,7 +1022,6 @@ /datum/reagent/nitrogen name = "Nitrogen" description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen." - reagent_state = GAS color = COLOR_GRAY taste_mult = 0 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1037,7 +1034,6 @@ /datum/reagent/hydrogen name = "Hydrogen" description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." - reagent_state = GAS color = COLOR_GRAY taste_mult = 0 ph = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve phes? (not 0 so I don't get div/0 errors) @@ -1046,7 +1042,6 @@ /datum/reagent/potassium name = "Potassium" description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water." - reagent_state = SOLID color = "#A0A0A0" // rgb: 160, 160, 160 taste_description = "sweetness" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1070,7 +1065,6 @@ /datum/reagent/sulfur name = "Sulfur" description = "A sickly yellow solid mostly known for its nasty smell. It's actually much more helpful than it looks in biochemisty." - reagent_state = SOLID color = "#BF8C00" // rgb: 191, 140, 0 taste_description = "rotten eggs" ph = 4.5 @@ -1079,7 +1073,6 @@ /datum/reagent/carbon name = "Carbon" description = "A crumbly black solid that, while unexciting on a physical level, forms the base of all known life. Kind of a big deal." - reagent_state = SOLID color = "#1C1300" // rgb: 30, 20, 0 taste_description = "sour chalk" ph = 5 @@ -1095,7 +1088,6 @@ /datum/reagent/chlorine name = "Chlorine" description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless." - reagent_state = GAS color = "#FFFB89" //pale yellow? let's make it light gray taste_description = "chlorine" ph = 7.4 @@ -1119,7 +1111,6 @@ /datum/reagent/fluorine name = "Fluorine" description = "A comically-reactive chemical element. The universe does not want this stuff to exist in this form in the slightest." - reagent_state = GAS color = COLOR_GRAY taste_description = "acid" ph = 2 @@ -1140,7 +1131,6 @@ /datum/reagent/sodium name = "Sodium" description = "A soft silver metal that can easily be cut with a knife. It's not salt just yet, so refrain from putting it on your chips." - reagent_state = SOLID color = COLOR_GRAY taste_description = "salty metal" ph = 11.6 @@ -1149,7 +1139,6 @@ /datum/reagent/phosphorus name = "Phosphorus" description = "A ruddy red powder that burns readily. Though it comes in many colors, the general theme is always the same." - reagent_state = SOLID color = "#832828" // rgb: 131, 40, 40 taste_description = "vinegar" ph = 6.5 @@ -1164,7 +1153,6 @@ /datum/reagent/lithium name = "Lithium" description = "A silver metal, its claim to fame is its remarkably low density. Using it is a bit too effective in calming oneself down." - reagent_state = SOLID color = COLOR_GRAY taste_description = "metal" ph = 11.3 @@ -1207,7 +1195,6 @@ /datum/reagent/iron name = "Iron" description = "Pure iron is a metal." - reagent_state = SOLID taste_description = "iron" material = /datum/material/iron chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1222,7 +1209,6 @@ /datum/reagent/gold name = "Gold" description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known." - reagent_state = SOLID color = "#F7C430" // rgb: 247, 196, 48 taste_description = "expensive metal" material = /datum/material/gold @@ -1231,7 +1217,6 @@ /datum/reagent/silver name = "Silver" description = "A soft, white, lustrous transition metal, it has the highest electrical conductivity of any element and the highest thermal conductivity of any metal." - reagent_state = SOLID color = "#D0D0D0" // rgb: 208, 208, 208 taste_description = "expensive yet reasonable metal" material = /datum/material/silver @@ -1240,7 +1225,6 @@ /datum/reagent/uranium name = "Uranium" description = "A jade-green metallic chemical element in the actinide series, weakly radioactive." - reagent_state = SOLID color = "#5E9964" //this used to be silver, but liquid uranium can still be green and it's more easily noticeable as uranium like this so why bother? taste_description = "the inside of a reactor" ph = 4 @@ -1273,7 +1257,6 @@ /datum/reagent/uranium/radium name = "Radium" description = "Radium is an alkaline earth metal. It is extremely radioactive." - reagent_state = SOLID color = "#00CC00" // ditto taste_description = "the colour blue and regret" tox_damage = 1 @@ -1284,7 +1267,6 @@ /datum/reagent/bluespace name = "Bluespace Dust" description = "A dust composed of microscopic bluespace crystals, with minor space-warping properties." - reagent_state = SOLID color = "#0000CC" taste_description = "fizzling blue" material = /datum/material/bluespace @@ -1310,7 +1292,6 @@ /datum/reagent/aluminium name = "Aluminium" description = "A silvery white and ductile member of the boron group of chemical elements." - reagent_state = SOLID color = "#A8A8A8" // rgb: 168, 168, 168 taste_description = "metal" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -1318,7 +1299,6 @@ /datum/reagent/silicon name = "Silicon" description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon." - reagent_state = SOLID color = "#A8A8A8" // rgb: 168, 168, 168 taste_mult = 0 material = /datum/material/glass @@ -1536,7 +1516,6 @@ /datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually. name = "Foaming Agent" description = "An agent that yields metallic foam when mixed with light metal and a strong acid." - reagent_state = SOLID color = "#664B63" // rgb: 102, 75, 99 taste_description = "metal" ph = 11.5 @@ -1545,7 +1524,6 @@ /datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls. name = "Smart Foaming Agent" description = "An agent that yields metallic foam which conforms to area boundaries when mixed with light metal and a strong acid." - reagent_state = SOLID color = "#664B63" // rgb: 102, 75, 99 taste_description = "metal" ph = 11.8 @@ -1554,7 +1532,6 @@ /datum/reagent/ammonia name = "Ammonia" description = "A caustic substance commonly used in fertilizer or household cleaners." - reagent_state = GAS color = "#404030" // rgb: 64, 64, 48 taste_description = "mordant" ph = 11.6 @@ -1588,7 +1565,6 @@ /datum/reagent/carbondioxide name = "Carbon Dioxide" - reagent_state = GAS description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs." color = "#B0B0B0" // rgb : 192, 192, 192 taste_description = "something unknowable" @@ -1604,7 +1580,6 @@ name = "Nitrous Oxide" description = "A potent oxidizer used as fuel in rockets and as an anaesthetic during surgery. As it is an anticoagulant, nitrous oxide is best \ used alongside sanguirite to allow blood clotting to continue." - reagent_state = LIQUID metabolization_rate = 1.5 * REAGENTS_METABOLISM color = COLOR_GRAY taste_description = "sweetness" @@ -1654,11 +1629,10 @@ /datum/reagent/colorful_reagent/powder name = "Mundane Powder" //the name's a bit similar to the name of colorful reagent, but hey, they're practically the same chem anyway - var/colorname = "none" description = "A powder that is used for coloring things." - reagent_state = SOLID color = COLOR_WHITE taste_description = "the back of class" + var/colorname = "none" /datum/reagent/colorful_reagent/powder/New() if(colorname == "none") @@ -1872,7 +1846,6 @@ /datum/reagent/fuel/oil name = "Oil" description = "Burns in a small smoky fire, can be used to get Ash." - reagent_state = LIQUID color = "#2D2D2D" taste_description = "oil" burning_temperature = 1200//Oil is crude @@ -1884,7 +1857,6 @@ /datum/reagent/stable_plasma name = "Stable Plasma" description = "Non-flammable plasma locked into a liquid form that cannot ignite or become gaseous/solid." - reagent_state = LIQUID color = "#2D2D2D" taste_description = "bitterness" taste_mult = 1.5 @@ -1898,7 +1870,6 @@ /datum/reagent/iodine name = "Iodine" description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing." - reagent_state = LIQUID color = "#BC8A00" taste_description = "metal" ph = 4.5 @@ -1907,7 +1878,6 @@ /datum/reagent/carpet name = "Carpet" description = "For those that need a more creative way to roll out a red carpet." - reagent_state = LIQUID color = "#771100" taste_description = "carpet" // Your tounge feels furry. var/carpet_type = /turf/open/floor/carpet @@ -2126,7 +2096,6 @@ /datum/reagent/bromine name = "Bromine" description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption." - reagent_state = LIQUID color = "#D35415" taste_description = "chemicals" ph = 7.8 @@ -2135,7 +2104,6 @@ /datum/reagent/pentaerythritol name = "Pentaerythritol" description = "Slow down, it ain't no spelling bee!" - reagent_state = SOLID color = "#E66FFF" taste_description = "acid" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2143,7 +2111,6 @@ /datum/reagent/acetaldehyde name = "Acetaldehyde" description = "Similar to plastic. Tastes like dead people." - reagent_state = SOLID color = "#EEEEEF" taste_description = "dead people" //made from formaldehyde, ya get da joke ? chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2151,7 +2118,6 @@ /datum/reagent/acetone_oxide name = "Acetone Oxide" description = "Enslaved oxygen" - reagent_state = LIQUID color = "#966199cb" taste_description = "acid" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2165,7 +2131,6 @@ /datum/reagent/phenol name = "Phenol" description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own." - reagent_state = LIQUID color = "#E7EA91" taste_description = "acid" ph = 5.5 @@ -2174,7 +2139,6 @@ /datum/reagent/ash name = "Ash" description = "Supposedly phoenixes rise from these, but you've never seen it." - reagent_state = LIQUID color = "#515151" taste_description = "ash" ph = 6.5 @@ -2189,7 +2153,6 @@ /datum/reagent/acetone name = "Acetone" description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life." - reagent_state = LIQUID color = "#AF14B7" taste_description = "acid" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2197,7 +2160,6 @@ /datum/reagent/colorful_reagent name = "Colorful Reagent" description = "Thoroughly sample the rainbow." - reagent_state = LIQUID var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") color = COLOR_GRAY taste_description = "rainbows" @@ -2233,7 +2195,6 @@ /datum/reagent/hair_dye name = "Quantum Hair Dye" description = "Has a high chance of making you look like a mad scientist." - reagent_state = LIQUID var/list/potential_colors = list("#00aadd","#aa00ff","#ff7733","#dd1144","#dd1144","#00bb55","#00aadd","#ff7733","#ffcc22","#008844","#0055ee","#dd2222","#ffaa00") // fucking hair code color = COLOR_GRAY taste_description = "sourness" @@ -2259,7 +2220,6 @@ /datum/reagent/barbers_aid name = "Barber's Aid" description = "A solution to hair loss across the world." - reagent_state = LIQUID color = "#A86B45" //hair is brown taste_description = "sourness" penetrates_skin = NONE @@ -2282,7 +2242,6 @@ /datum/reagent/concentrated_barbers_aid name = "Concentrated Barber's Aid" description = "A concentrated solution to hair loss across the world." - reagent_state = LIQUID color = "#7A4E33" //hair is dark browmn taste_description = "sourness" penetrates_skin = NONE @@ -2321,7 +2280,6 @@ /datum/reagent/baldium name = "Baldium" description = "A major cause of hair loss across the world." - reagent_state = LIQUID color = "#ecb2cf" taste_description = "bitterness" penetrates_skin = NONE @@ -2340,7 +2298,6 @@ /datum/reagent/saltpetre name = "Saltpetre" description = "Volatile. Controversial. Third Thing." - reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 taste_description = "cool salt" ph = 11.2 @@ -2355,7 +2312,6 @@ /datum/reagent/lye name = "Lye" description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming." - reagent_state = LIQUID color = "#FFFFD6" // very very light yellow taste_description = "acid" ph = 11.9 @@ -2364,7 +2320,6 @@ /datum/reagent/drying_agent name = "Drying Agent" description = "A desiccant. Can be used to dry things." - reagent_state = LIQUID color = "#A70FFF" taste_description = "dryness" ph = 10.7 @@ -2477,7 +2432,6 @@ /datum/reagent/magillitis name = "Magillitis" description = "An experimental serum which causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." - reagent_state = LIQUID color = "#00f041" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE @@ -2538,9 +2492,8 @@ description = "if you can see this description, contact a coder." color = COLOR_WHITE //pure white taste_description = "plastic" - reagent_state = SOLID - var/glitter_type = /obj/effect/decal/cleanable/glitter chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + var/glitter_type = /obj/effect/decal/cleanable/glitter /datum/reagent/glitter/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -2815,7 +2768,6 @@ /datum/reagent/cellulose name = "Cellulose Fibers" description = "A crystaline polydextrose polymer, plants swear by this stuff." - reagent_state = SOLID color = "#E6E6DA" taste_mult = 0 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2824,7 +2776,6 @@ /datum/reagent/determination name = "Determination" description = "For when you need to push on a little more. Do NOT allow near plants." - reagent_state = LIQUID color = "#D2FFFA" metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~34 seconds chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -2915,7 +2866,6 @@ /datum/reagent/ants name = "Ants" description = "A genetic crossbreed between ants and termites, their bites land at a 3 on the Schmidt Pain Scale." - reagent_state = SOLID color = "#993333" taste_mult = 1.3 taste_description = "tiny legs scuttling down the back of your throat" @@ -3020,7 +2970,6 @@ name = "Lead" description = "A dull metallic element with a low melting point." taste_description = "metal" - reagent_state = SOLID color = "#80919d" metabolization_rate = 0.4 * REAGENTS_METABOLISM @@ -3049,7 +2998,6 @@ /datum/reagent/brimdust name = "Brimdust" description = "A brimdemon's dust. Consumption is not recommended, although plants like it." - reagent_state = SOLID color = "#522546" taste_description = "burning" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 0ad3b55fb59d3..a4cb1fdee7595 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -2,7 +2,6 @@ /datum/reagent/thermite name = "Thermite" description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls." - reagent_state = SOLID chemical_flags = REAGENT_CAN_BE_SYNTHESIZED color = "#550000" taste_description = "sweet tasting metal" @@ -33,7 +32,6 @@ /datum/reagent/stabilizing_agent name = "Stabilizing Agent" description = "Keeps unstable chemicals stable. This does not work on everything." - reagent_state = LIQUID color = COLOR_YELLOW taste_description = "metal" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -45,7 +43,6 @@ /datum/reagent/clf3 name = "Chlorine Trifluoride" description = "Makes a temporary 3x3 fireball when it comes into existence, so be careful when mixing. ClF3 applied to a surface burns things that wouldn't otherwise burn, sometimes through the very floors of the station and exposing it to the vacuum of space." - reagent_state = LIQUID color = "#FFC8C8" metabolization_rate = 10 * REAGENTS_METABOLISM taste_description = "burning" @@ -84,7 +81,6 @@ /datum/reagent/sorium name = "Sorium" description = "Sends everything flying from the detonation point." - reagent_state = LIQUID color = "#5A64C8" taste_description = "air and bitterness" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -92,7 +88,6 @@ /datum/reagent/liquid_dark_matter name = "Liquid Dark Matter" description = "Sucks everything into the detonation point." - reagent_state = LIQUID color = "#210021" taste_description = "compressed bitterness" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -100,7 +95,6 @@ /datum/reagent/gunpowder name = "Gunpowder" description = "Explodes. Violently." - reagent_state = LIQUID color = COLOR_BLACK metabolization_rate = 0.125 * REAGENTS_METABOLISM taste_description = "salt" @@ -129,7 +123,6 @@ /datum/reagent/rdx name = "RDX" description = "Military grade explosive" - reagent_state = SOLID color = COLOR_WHITE taste_description = "salt" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -137,7 +130,6 @@ /datum/reagent/tatp name = "TaTP" description = "Suicide grade explosive" - reagent_state = SOLID color = COLOR_WHITE taste_description = "death" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -145,7 +137,6 @@ /datum/reagent/flash_powder name = "Flash Powder" description = "Makes a very bright flash." - reagent_state = LIQUID color = "#C8C8C8" taste_description = "salt" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -153,7 +144,6 @@ /datum/reagent/smoke_powder name = "Smoke Powder" description = "Makes a large cloud of smoke that can carry reagents." - reagent_state = LIQUID color = "#C8C8C8" taste_description = "smoke" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -161,7 +151,6 @@ /datum/reagent/sonic_powder name = "Sonic Powder" description = "Makes a deafening noise." - reagent_state = LIQUID color = "#C8C8C8" taste_description = "loud noises" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -169,7 +158,6 @@ /datum/reagent/phlogiston name = "Phlogiston" description = "Catches you on fire and makes you ignite." - reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" self_consuming = TRUE @@ -191,7 +179,6 @@ /datum/reagent/napalm name = "Napalm" description = "Very flammable." - reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" self_consuming = TRUE @@ -302,7 +289,6 @@ /datum/reagent/teslium //Teslium. Causes periodic shocks, and makes shocks against the target much more effective. name = "Teslium" description = "An unstable, electrically-charged metallic slurry. Periodically electrocutes its victim, and makes electrocutions against them more deadly. Excessively heating teslium results in dangerous destabilization. Do not allow to come into contact with water." - reagent_state = LIQUID color = "#20324D" //RGB: 32, 50, 77 metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "charged metal" @@ -341,7 +327,6 @@ /datum/reagent/teslium/energized_jelly name = "Energized Jelly" description = "Electrically-charged jelly. Boosts jellypeople's nervous system, but only shocks other lifeforms." - reagent_state = LIQUID color = "#CAFF43" taste_description = "jelly" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -360,7 +345,6 @@ /datum/reagent/firefighting_foam name = "Firefighting Foam" description = "A historical fire suppressant. Originally believed to simply displace oxygen to starve fires, it actually interferes with the combustion reaction itself. Vastly superior to the cheap water-based extinguishers found on NT vessels." - reagent_state = LIQUID color = "#A6FAFF55" taste_description = "the inside of a fire extinguisher" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 22c5902ad4136..9dcf7955a31c3 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -152,7 +152,6 @@ /datum/reagent/toxin/hot_ice name = "Hot Ice Slush" description = "Frozen plasma, worth its weight in gold, to the right people." - reagent_state = SOLID color = "#724cb8" // rgb: 114, 76, 184 taste_description = "thick and smokey" specific_heat = SPECIFIC_HEAT_PLASMA @@ -245,7 +244,6 @@ name = "Zombie Powder" description = "A strong neurotoxin that puts the subject into a death-like state." silent_toxin = TRUE - reagent_state = SOLID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#669900" // rgb: 102, 153, 0 @@ -294,7 +292,6 @@ /datum/reagent/toxin/ghoulpowder name = "Ghoul Powder" description = "A strong neurotoxin that slows metabolism to a death-like state, while keeping the patient fully active. Causes toxin buildup if used too long." - reagent_state = SOLID color = "#664700" // rgb: 102, 71, 0 creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY @@ -469,7 +466,6 @@ name = "Chloral Hydrate" description = "A powerful sedative that induces confusion and drowsiness before putting its target to sleep." silent_toxin = TRUE - reagent_state = SOLID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#000067" // rgb: 0, 0, 103 @@ -526,7 +522,6 @@ /datum/reagent/toxin/coffeepowder name = "Coffee Grounds" description = "Finely ground coffee beans, used to make coffee." - reagent_state = SOLID color = "#5B2E0D" // rgb: 91, 46, 13 toxpwr = 0.5 ph = 4.2 @@ -536,7 +531,6 @@ /datum/reagent/toxin/teapowder name = "Ground Tea Leaves" description = "Finely shredded tea leaves, used for making tea." - reagent_state = SOLID color = "#7F8400" // rgb: 127, 132, 0 toxpwr = 0.1 taste_description = "green tea" @@ -547,7 +541,6 @@ /datum/reagent/toxin/mushroom_powder name = "Mushroom Powder" description = "Finely ground polypore mushrooms, ready to be steeped in water to make mushroom tea." - reagent_state = SOLID color = "#67423A" // rgb: 127, 132, 0 toxpwr = 0.1 taste_description = "mushrooms" @@ -589,7 +582,6 @@ /datum/reagent/toxin/polonium name = "Polonium" description = "An extremely radioactive material in liquid form. Ingestion results in fatal irradiation." - reagent_state = LIQUID color = "#787878" metabolization_rate = 0.125 * REAGENTS_METABOLISM toxpwr = 0 @@ -607,7 +599,6 @@ name = "Histamine" description = "Histamine's effects become more dangerous depending on the dosage amount. They range from mildly annoying to incredibly lethal." silent_toxin = TRUE - reagent_state = LIQUID color = "#FA6464" metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 @@ -644,7 +635,6 @@ name = "Formaldehyde" description = "Formaldehyde, on its own, is a fairly weak toxin. It contains trace amounts of Histamine, very rarely making it decay into Histamine. When used in a dead body, will prevent organ decay." silent_toxin = TRUE - reagent_state = LIQUID color = "#B4004B" metabolization_rate = 0.5 * REAGENTS_METABOLISM creation_purity = REAGENT_STANDARD_PURITY @@ -668,7 +658,6 @@ /datum/reagent/toxin/venom name = "Venom" description = "An exotic poison extracted from highly toxic fauna. Causes scaling amounts of toxin damage and bruising depending and dosage. Often decays into Histamine." - reagent_state = LIQUID color = "#F0FFF0" metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0 @@ -700,7 +689,6 @@ /datum/reagent/toxin/fentanyl name = "Fentanyl" description = "Fentanyl will inhibit brain function and cause toxin damage before eventually knocking out its victim." - reagent_state = LIQUID color = "#64916E" metabolization_rate = 0.5 * REAGENTS_METABOLISM creation_purity = REAGENT_STANDARD_PURITY @@ -726,7 +714,6 @@ /datum/reagent/toxin/cyanide name = "Cyanide" description = "An infamous poison known for its use in assassination. Causes small amounts of toxin damage with a small chance of oxygen damage or a stun." - reagent_state = LIQUID color = "#00B4FF" creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY @@ -751,7 +738,6 @@ /datum/reagent/toxin/bad_food name = "Bad Food" description = "The result of some abomination of cookery, food so bad it's toxic." - reagent_state = LIQUID color = "#d6d6d8" metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0.5 @@ -762,7 +748,6 @@ name = "Itching Powder" description = "A powder that induces itching upon contact with the skin. Causes the victim to scratch at their itches and has a very low chance to decay into Histamine." silent_toxin = TRUE - reagent_state = LIQUID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#C8C8C8" @@ -799,7 +784,6 @@ name = "Initropidril" description = "A powerful poison with insidious effects. It can cause stuns, lethal breathing failure, and cardiac arrest." silent_toxin = TRUE - reagent_state = LIQUID color = "#7F10C0" metabolization_rate = 0.5 * REAGENTS_METABOLISM toxpwr = 2.5 @@ -833,7 +817,6 @@ name = "Pancuronium" description = "An undetectable toxin that swiftly incapacitates its victim. May also cause breathing failure." silent_toxin = TRUE - reagent_state = LIQUID color = "#195096" metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0 @@ -852,7 +835,6 @@ name = "Sodium Thiopental" description = "Sodium Thiopental induces heavy weakness in its target as well as unconsciousness." silent_toxin = TRUE - reagent_state = LIQUID color = LIGHT_COLOR_BLUE metabolization_rate = 0.75 * REAGENTS_METABOLISM toxpwr = 0 @@ -870,7 +852,6 @@ name = "Sulfonal" description = "A stealthy poison that deals minor toxin damage and eventually puts the target to sleep." silent_toxin = TRUE - reagent_state = LIQUID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#7DC3A0" @@ -888,7 +869,6 @@ name = "Amanitin" description = "A very powerful delayed toxin. Upon full metabolization, a massive amount of toxin damage will be dealt depending on how long it has been in the victim's bloodstream." silent_toxin = TRUE - reagent_state = LIQUID color = COLOR_WHITE toxpwr = 0 metabolization_rate = 0.5 * REAGENTS_METABOLISM @@ -909,7 +889,6 @@ description = "A powerful toxin that will destroy fat cells, massively reducing body weight in a short time. Deadly to those without nutriment in their body." silent_toxin = TRUE taste_description = "mothballs" - reagent_state = LIQUID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#F0FFF0" @@ -930,7 +909,6 @@ /datum/reagent/toxin/coniine name = "Coniine" description = "Coniine metabolizes extremely slowly, but deals high amounts of toxin damage and stops breathing." - reagent_state = LIQUID color = "#7DC3A0" metabolization_rate = 0.06 * REAGENTS_METABOLISM toxpwr = 1.75 @@ -945,7 +923,6 @@ /datum/reagent/toxin/spewium name = "Spewium" description = "A powerful emetic, causes uncontrollable vomiting. May result in vomiting organs at high doses." - reagent_state = LIQUID color = "#2f6617" //A sickly green color metabolization_rate = REAGENTS_METABOLISM overdose_threshold = 29 @@ -977,7 +954,6 @@ /datum/reagent/toxin/curare name = "Curare" description = "Causes slight toxin damage followed by chain-stunning and oxygen damage." - reagent_state = LIQUID color = "#191919" metabolization_rate = 0.125 * REAGENTS_METABOLISM toxpwr = 1 @@ -994,7 +970,6 @@ name = "Heparin" description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster. It directly purges sanguirite, a coagulant." silent_toxin = TRUE - reagent_state = LIQUID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#C8C8C8" //RGB: 200, 200, 200 @@ -1013,7 +988,6 @@ name = "Rotatium" description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild." silent_toxin = TRUE - reagent_state = LIQUID creation_purity = REAGENT_STANDARD_PURITY purity = REAGENT_STANDARD_PURITY color = "#AC88CA" //RGB: 172, 136, 202 @@ -1044,7 +1018,6 @@ /datum/reagent/toxin/anacea name = "Anacea" description = "A toxin that quickly purges medicines and metabolizes very slowly." - reagent_state = LIQUID color = "#3C5133" metabolization_rate = 0.08 * REAGENTS_METABOLISM creation_purity = REAGENT_STANDARD_PURITY @@ -1152,7 +1125,6 @@ /datum/reagent/toxin/delayed name = "Toxin Microcapsules" description = "Causes heavy toxin damage after a brief time of inactivity." - reagent_state = LIQUID metabolization_rate = 0 //stays in the system until active. var/actual_metaboliztion_rate = REAGENTS_METABOLISM toxpwr = 0 @@ -1263,7 +1235,6 @@ /datum/reagent/toxin/leadacetate name = "Lead Acetate" description = "Used hundreds of years ago as a sweetener, before it was realized that it's incredibly poisonous." - reagent_state = SOLID color = "#2b2b2b" // rgb: 127, 132, 0 toxpwr = 0.5 taste_mult = 1.3 @@ -1302,7 +1273,6 @@ name = "Tetrodotoxin" description = "A colorless, odorless, tasteless neurotoxin usually carried by livers of animals of the Tetraodontiformes order." silent_toxin = TRUE - reagent_state = SOLID color = COLOR_VERY_LIGHT_GRAY metabolization_rate = 0.1 * REAGENTS_METABOLISM liver_tolerance_multiplier = 0.1 diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index ccd9c4169a5a3..e69e1bd298677 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -559,7 +559,7 @@ desc = "The most advanced coffeepot the eggheads could cook up: sleek design; graduated lines; connection to a pocket dimension for coffee containment; yep, it's got it all. Contains 8 standard cups." volume = 240 icon_state = "coffeepot_bluespace" - fill_icon_thresholds = list(0) + fill_icon_thresholds = null ///Test tubes created by chem master and pandemic and placed in racks /obj/item/reagent_containers/cup/tube diff --git a/code/modules/research/part_replacer.dm b/code/modules/research/part_replacer.dm index 6c5bb5f64646e..916fbdd01407f 100644 --- a/code/modules/research/part_replacer.dm +++ b/code/modules/research/part_replacer.dm @@ -11,7 +11,7 @@ storage_type = /datum/storage/rped /obj/item/storage/part_replacer/interact_with_atom(obj/attacked_object, mob/living/user, list/modifiers) - if(user.combat_mode || !istype(attacked_object) || HAS_TRAIT(attacked_object, TRAIT_COMBAT_MODE_SKIP_INTERACTION)) + if(user.combat_mode) return ITEM_INTERACT_SKIP_TO_ATTACK //its very important to NOT block so frames can still interact with it diff --git a/code/modules/spells/spell_types/pointed/_pointed.dm b/code/modules/spells/spell_types/pointed/_pointed.dm index 39d6fb9d6736f..6d65d70734d6d 100644 --- a/code/modules/spells/spell_types/pointed/_pointed.dm +++ b/code/modules/spells/spell_types/pointed/_pointed.dm @@ -64,13 +64,13 @@ build_all_button_icons() return TRUE -/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/target) +/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/clicker, params, atom/target) var/atom/aim_assist_target if(aim_assist) - aim_assist_target = aim_assist(caller, target) - return ..(caller, params, aim_assist_target || target) + aim_assist_target = aim_assist(clicker, target) + return ..(clicker, params, aim_assist_target || target) -/datum/action/cooldown/spell/pointed/proc/aim_assist(mob/living/caller, atom/target) +/datum/action/cooldown/spell/pointed/proc/aim_assist(mob/living/clicker, atom/target) if(!isturf(target)) return diff --git a/code/modules/spells/spell_types/pointed/swap.dm b/code/modules/spells/spell_types/pointed/swap.dm index 884504efc8edc..57b74fba05625 100644 --- a/code/modules/spells/spell_types/pointed/swap.dm +++ b/code/modules/spells/spell_types/pointed/swap.dm @@ -35,29 +35,30 @@ return FALSE return TRUE -/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/caller, params, atom/target) - if(LAZYACCESS(params2list(params), RIGHT_CLICK)) - if(!IsAvailable(feedback = TRUE)) - return FALSE +/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/clicker, params, atom/target) + if(!LAZYACCESS(params2list(params), RIGHT_CLICK)) + return ..() + + if(!IsAvailable(feedback = TRUE)) + return FALSE + if(!target) + return FALSE + if(!isliving(target) || isturf(target)) + // Find any living being in the list. We aren't picky, it's aim assist after all + target = locate(/mob/living) in target if(!target) + to_chat(owner, span_warning("You can only select living beings as secondary target!")) return FALSE - if(!isliving(target) || isturf(target)) - // Find any living being in the list. We aren't picky, it's aim assist after all - target = locate(/mob/living) in target - if(!target) - to_chat(owner, span_warning("You can only select living beings as secondary target!")) - return FALSE - if(target == owner) - if(!isnull(second_target)) - to_chat(owner, span_notice("You cancel your secondary swap target!")) - second_target = null - else - to_chat(owner, span_warning("You have no secondary swap target!")) - return FALSE - second_target = target - to_chat(owner, span_notice("You select [target.name] as a secondary swap target!")) + if(target == owner) + if(!isnull(second_target)) + to_chat(owner, span_notice("You cancel your secondary swap target!")) + second_target = null + else + to_chat(owner, span_warning("You have no secondary swap target!")) return FALSE - return ..() + second_target = target + to_chat(owner, span_notice("You select [target.name] as a secondary swap target!")) + return FALSE /datum/action/cooldown/spell/pointed/swap/cast(mob/living/carbon/cast_on) . = ..() diff --git a/code/modules/spells/spell_types/touch/_touch.dm b/code/modules/spells/spell_types/touch/_touch.dm index 49d1f24e39c67..a783874c14cff 100644 --- a/code/modules/spells/spell_types/touch/_touch.dm +++ b/code/modules/spells/spell_types/touch/_touch.dm @@ -153,9 +153,9 @@ return ..() | SPELL_NO_FEEDBACK | SPELL_NO_IMMEDIATE_COOLDOWN /datum/action/cooldown/spell/touch/cast(mob/living/carbon/cast_on) - if(SEND_SIGNAL(cast_on, COMSIG_TOUCH_HANDLESS_CAST) & COMPONENT_CAST_HANDLESS) + if(SEND_SIGNAL(cast_on, COMSIG_TOUCH_HANDLESS_CAST, src) & COMPONENT_CAST_HANDLESS) StartCooldown() - return ..() + return if(!QDELETED(attached_hand) && (attached_hand in cast_on.held_items)) remove_hand(cast_on, reset_cooldown_after = TRUE) diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm index 26b089333b2e5..7d8cd6cf403e8 100644 --- a/code/modules/surgery/organs/external/_visual_organs.dm +++ b/code/modules/surgery/organs/external/_visual_organs.dm @@ -83,10 +83,10 @@ Unlike normal organs, we're actually inside a persons limbs at all times bodypart_overlay.set_appearance(typed_accessory) - if(bodypart_owner) //are we in a limb? - bodypart_owner.update_icon_dropped() - else if(owner && !(owner.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) //are we a person? + if(owner && !(owner.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) //are we a person? owner.update_body_parts() + else + bodypart_owner?.update_icon_dropped() //are we in a limb? /obj/item/organ/update_overlays() . = ..() diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm index acd19dfa6411c..ca49e46cdffad 100644 --- a/code/modules/tgs/v5/undefs.dm +++ b/code/modules/tgs/v5/undefs.dm @@ -18,6 +18,7 @@ #undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER #undef DMAPI5_PARAMETER_CUSTOM_COMMANDS +#undef DMAPI5_PARAMETER_TOPIC_PORT #undef DMAPI5_CHUNK #undef DMAPI5_CHUNK_PAYLOAD diff --git a/code/modules/vehicles/cars/speedwagon.dm b/code/modules/vehicles/cars/speedwagon.dm index 1fa9e2dcc6c92..ee3eac8a59525 100644 --- a/code/modules/vehicles/cars/speedwagon.dm +++ b/code/modules/vehicles/cars/speedwagon.dm @@ -14,9 +14,11 @@ ///Determines whether we throw all things away when ramming them or just mobs, varedit only var/crash_all = FALSE -/obj/vehicle/sealed/car/speedwagon/Initialize(mapload) +/obj/vehicle/sealed/car/speedwagon/update_overlays() . = ..() - add_overlay(image(icon, "speedwagon_cover", ABOVE_MOB_LAYER)) + var/mutable_appearance/cover_overlay = mutable_appearance(icon, "speedwagon_cover", ABOVE_MOB_LAYER, src, appearance_flags = KEEP_APART) + cover_overlay = color_atom_overlay(cover_overlay) + . += cover_overlay /obj/vehicle/sealed/car/speedwagon/Bump(atom/bumped) . = ..() diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm index dfcf2896b5b74..6395b39393ef8 100644 --- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm +++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm @@ -145,7 +145,7 @@ chassis.mecha_flags |= QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT chassis.phasing = "flying" chassis.movedelay = 1 - chassis.density = FALSE + chassis.set_density(FALSE) chassis.layer = ABOVE_ALL_MOB_LAYER animate(chassis, alpha = 0, time = 8, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL) animate(chassis, pixel_z = 400, time = 10, easing = QUAD_EASING|EASE_IN, flags = ANIMATION_PARALLEL) //Animate our rising mech (just like pods hehe) @@ -176,7 +176,7 @@ chassis.mecha_flags &= ~(QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT) chassis.phasing = initial(chassis.phasing) chassis.movedelay = initial(chassis.movedelay) - chassis.density = TRUE + chassis.set_density(TRUE) chassis.layer = initial(chassis.layer) SET_PLANE(chassis, initial(chassis.plane), landed_on) skyfall_charge_level = 0 diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm index 6a38f65e3bf09..cc11e713e614f 100644 --- a/code/modules/vehicles/motorized_wheelchair.dm +++ b/code/modules/vehicles/motorized_wheelchair.dm @@ -66,7 +66,7 @@ speed += servo.tier var/chair_icon = "motorized_wheelchair[speed > delay_multiplier ? "_fast" : ""]" if(icon_state != chair_icon) - wheels_overlay = image(icon, chair_icon + "_overlay", ABOVE_MOB_LAYER) + overlay_icon = chair_icon + "_overlay" icon_state = chair_icon diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm index 3e375b59c2e0e..c7cf18240ae4e 100644 --- a/code/modules/vehicles/speedbike.dm +++ b/code/modules/vehicles/speedbike.dm @@ -7,7 +7,6 @@ /obj/vehicle/ridden/speedbike/Initialize(mapload) . = ..() - add_overlay(image(icon, cover_iconstate, ABOVE_MOB_LAYER)) AddElement(/datum/element/ridable, /datum/component/riding/vehicle/speedbike) /obj/vehicle/ridden/speedbike/Move(newloc,move_dir) @@ -15,6 +14,12 @@ new /obj/effect/temp_visual/dir_setting/speedbike_trail(loc,move_dir) return ..() +/obj/vehicle/ridden/speedbike/update_overlays() + . = ..() + var/mutable_appearance/cover_overlay = mutable_appearance(icon, cover_iconstate, ABOVE_MOB_LAYER, src, appearance_flags = KEEP_APART) + cover_overlay = color_atom_overlay(cover_overlay) + . += cover_overlay + /obj/vehicle/ridden/speedbike/red icon_state = "speedbike_red" cover_iconstate = "cover_red" diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index b94257bb45f2b..cc6af6a2f1be1 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -13,7 +13,6 @@ var/delay_multiplier = 6.7 /// This variable is used to specify which overlay icon is used for the wheelchair, ensures wheelchair can cover your legs var/overlay_icon = "wheelchair_overlay" - var/image/wheels_overlay ///Determines the typepath of what the object folds into var/foldabletype = /obj/item/wheelchair ///Bell attached to the wheelchair, if we have one. @@ -36,7 +35,6 @@ /obj/vehicle/ridden/wheelchair/Initialize(mapload) . = ..() make_ridable() - wheels_overlay = image(icon, overlay_icon, ABOVE_MOB_LAYER) ADD_TRAIT(src, TRAIT_NO_IMMOBILIZE, INNATE_TRAIT) AddComponent(/datum/component/simple_rotation) //Since it's technically a chair I want it to have chair properties AddElement(/datum/element/noisy_movement, volume = 75) @@ -69,7 +67,9 @@ /obj/vehicle/ridden/wheelchair/update_overlays() . = ..() if(has_buckled_mobs()) - . += wheels_overlay + var/mutable_appearance/wheel_overlay = mutable_appearance(icon, overlay_icon, ABOVE_MOB_LAYER, src, appearance_flags = KEEP_APART) + wheel_overlay = color_atom_overlay(wheel_overlay) + . += wheel_overlay if(bell_attached) . += "wheelchair_bell" diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 6fdd8f5d25e1c..5d19644d363ff 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -199,14 +199,14 @@ GLOBAL_VAR_INIT(roaches_deployed, FALSE) /obj/item/storage/backpack/satchel/leather = 3, /obj/item/storage/backpack/duffelbag = 3, /obj/item/storage/backpack/messenger = 3, - /obj/item/storage/bag/mail = 3, /obj/item/radio/headset/headset_cargo = 3, /obj/item/clothing/accessory/pocketprotector = 3, - /obj/item/flatpack/mailsorter = 1, ) premium = list( + /obj/item/storage/bag/mail = 3, /obj/item/clothing/head/costume/mailman = 1, /obj/item/clothing/under/misc/mailman = 1, + /obj/item/flatpack/mailsorter = 1, /obj/item/clothing/under/rank/cargo/miner = 3, /obj/item/clothing/under/rank/cargo/miner/lavaland = 3, /obj/item/clothing/under/rank/cargo/bitrunner = 3, diff --git a/html/changelogs/AutoChangeLog-pr-88478.yml b/html/changelogs/AutoChangeLog-pr-88478.yml new file mode 100644 index 0000000000000..87ba8bf5daf38 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88478.yml @@ -0,0 +1,5 @@ +author: "grungussuss" +delete-after: True +changes: + - rscadd: "computers and airlocks are now leanable" + - refactor: "changed how density/collision of some objects is changed, report any oddities!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88568.yml b/html/changelogs/AutoChangeLog-pr-88568.yml deleted file mode 100644 index 0be95af6bb764..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88568.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix holodeck computer using wrong power settings and not updating properly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88578.yml b/html/changelogs/AutoChangeLog-pr-88578.yml deleted file mode 100644 index 34877c2d38dfe..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88578.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Wallem" -delete-after: True -changes: - - rscadd: "Rare collectors radios have been reported around Nanotrasen stations!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88597.yml b/html/changelogs/AutoChangeLog-pr-88597.yml deleted file mode 100644 index 1310118179f3a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88597.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SyncIt21" -delete-after: True -changes: - - bugfix: "skull cookies are visible again" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88636.yml b/html/changelogs/AutoChangeLog-pr-88636.yml new file mode 100644 index 0000000000000..04193e1590d71 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88636.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - qol: "you can adjust diagonal walls to be not diagonal walls with a wrench" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-88764.yml b/html/changelogs/AutoChangeLog-pr-88764.yml new file mode 100644 index 0000000000000..0e7b7cd8beb19 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88764.yml @@ -0,0 +1,4 @@ +author: "00-Steven" +delete-after: True +changes: + - bugfix: "Photocopying no longer removes the stamp overlays from the original paper, and actually copies them to the copy." \ No newline at end of file diff --git a/html/changelogs/archive/2024-12.yml b/html/changelogs/archive/2024-12.yml index f79a0fb07e5b2..763a62a1c6230 100644 --- a/html/changelogs/archive/2024-12.yml +++ b/html/changelogs/archive/2024-12.yml @@ -621,3 +621,146 @@ - bugfix: computer laptops will not block projectiles lovegreenstuff: - rscadd: catalyst function for plumbing reaction chambers +2024-12-26: + LordHookie: + - bugfix: The Syndicate Medical Space Suit is no longer labelled a 'green space + suit' despite being a noticeably non-green color. + - bugfix: Syndicate Medical and Engineering space helmets now display themselves + as such. + SmArtKar: + - image: Returned plasmafire and clockwork UI's transparency, slightly adjusted + active hand slot overlays + SyncIt21: + - bugfix: skull cookies are visible again + Wallem: + - rscadd: Rare collectors radios have been reported around Nanotrasen stations! + grungussuss: + - bugfix: picking stuff up actually respects the vary settings of an item + mc-oofert: + - image: girders and reinforced girders smooth now (except cult girders, bronze + girders, and whatever other special type) + rintherat: + - bugfix: Fixes alert level changing during a Delta+ scenario + timothymtorres: + - bugfix: Fix holodeck computer using wrong power settings and not updating properly +2024-12-27: + 00-Steven: + - bugfix: Produce, bitrunning, and mining order consoles no longer have broken icons + when swapping tabs. + - bugfix: Items in produce, bitrunning, and mining order consoles with especially + long names no longer make the information tooltip and item order buttons wonky. + - qol: The information tooltip button for items in produce, bitrunning, and mining + order consoles no longer moves with the item name, and instead sits next to + the item order buttons. + AyIong: + - qol: Now you can hide `Initialized some shit within 0s` messages, by unchecking + `Debug Log` checkbox into the chat tabs settings + Ghommie: + - rscadd: Added fish mounts to the game. They can be crafted with 3 sheets of wood. + Otherwise there's one at the bar that stores the fish between rounds. + JohnFulpWillard: + - bugfix: Smartfridges on grid mode (like botany's) will no longer instantly spit + out all the items it has when you try to set how many it should spit out. + LT3: + - qol: Entertainment and newscaster broadcasts can be toggled in chat tabs + OrionTheFox: + - image: updated the cartridge coffeemaker + coffeepot sprites, and added bluespace + pot overlays to coffeemakers + - qol: the coffeemakers can now be interacted with while unpowered! No longer will + your coffeepot be stuck inside the machine because it's unplugged! (Still need + power to brew) + SmArtKar: + - refactor: Rewrote some of HUD code so they're no longer colored in their owner's + color + - bugfix: Space dragons no longer turn invisible when toggling seethrough mode + SyncIt21: + - bugfix: crowbars can be recycled in lathes only when the panel is closed + - balance: turbine now has higher max rpm & increased power output + - code_imp: further improved code for turbine + - code_imp: removes unused var from reagent code + TheRealSpriteMan1337: + - spellcheck: Fixes some usages of its, clarifies wording on the syndie medbot, + changes span_warning to notice. + Xander3359: + - rscadd: Bileworm crusher trophy now gives you AOE mining + - balance: The pk crusher no longer has click delay after shooting the projectile + - balance: The pk crusher gives mining XP when it mines rocks + - balance: the pk crusher charges faster when you mine rocks based on your skill + as a miner + - code_imp: cleaned up some of the kinetic crusher code + Y0SH1M4S73R: + - bugfix: The "Move Up" and "Move Down" verbs properly respect multi-z connectivity + when operating a remote camera. + grungussuss: + - image: added hat masking for berets + - bugfix: fixed being unable to place rpeds on tables + - sound: added sounds for locking/unlocking closets + necromanceranne: + - balance: A new maint-kata has taken shape in the periphery of Spinward control. + Borrowing techniques from an ancient Martian martial artist, as well as an entire + franchise of extremely muscular acrobats and performance artists, talented assistants + have discovered that a swift application of a flimsy chair to the back of the + head can end fights more promptly than just bashing the opponent's head in with + their foot. That, and it looks awesome. + - balance: Chairs start to break apart when you hit someone with them or block an + attack with them. + - balance: Breaking a chair against a target while attacking from behind or while + they're staggered will cause them to get knocked down. Chairs made of more sturdy + materials can even cause them to become vulnerable to shove stuns. + timothymtorres: + - bugfix: Fix holoparasite using gas ability while not summoned + - bugfix: Fix kidnapping pod returning a player to unsafe location where air is + bad + - bugfix: Fix vent clog event triggering on non-station areas + - bugfix: Fix custom map loading ignoring JSON values that were ignored previously. + (minetype, planetary, etc.) +2024-12-28: + 00-Steven: + - bugfix: Lesser quiver actually has less slots as intended. + LT3: + - bugfix: Premade/vending machine flatpacks now display what board is inside + SmArtKar: + - bugfix: Fixed forcing open airlocks only working once and then never again + - balance: You can no longer check if budget insuls work via examine tags + SyncIt21: + - bugfix: breaking out of a closet won't spam chat or shake like it's having a seizure + - code_imp: plumbing reaction chamber won't waste extra ticks for the pipeline when + sending out catalysts + carlarctg: + - rscadd: Adds rift fishing to the game. Includes new wacky fish! + - rscadd: Drained and undrained influences can be fished in, the latter only by + heretics. Fishing in an undrained influence shows a bobber floating over nothing + to other people, so don't be stupid! + - rscadd: influences cannot be bombed for fish. + - rscadd: Heretics can now infuse their fishing rod, and fish for knowledge. +2024-12-29: + 00-Steven: + - spellcheck: Give alert 'examiante' > 'examine'. + Absolucy: + - code_imp: Very slightly improved the performance of code related to adding and + removing traits. + Ben10Omintrix: + - bugfix: radial pet commanding emotes will now not appear if the command is impossible + to execute + FlufflesTheDog: + - bugfix: welding sparks no longer break on transitioning to a different floor + LT3: + - bugfix: Fixed lead acid cell having extremely high max charge + Paxilmaniac: + - bugfix: fixes crafting menu-made rice dough being unusable for bread + SmArtKar: + - qol: Iron material tiles can now be used to tile lattice to make plating + - bugfix: Fixed podperson hair not updating + - bugfix: Fixed chair, echair, wheelchair and vehicle overlays on painted objects + SyncIt21: + - bugfix: Changing gather mode on storage items won't drop it's stored items + - bugfix: Fixes shattering element dropping stuff on blocked turfs + necromanceranne: + - bugfix: Tackling resulting in a neutral outcome does not force you to the floor. + - bugfix: Getting up is now properly influenced by spinal implants. + timothymtorres: + - refactor: Sound has been heavily optimized and will now ignore low volume sounds + from far away. + - admin: Add debugging sound earmuffs to admin equipment inside the debug box. Wear + them to determine a sounds max range, distance, volume, and sound name. Highly + recommended to walk otherwise you will get spammed with footstep sounds. diff --git a/icons/hud/screen_clockwork.dmi b/icons/hud/screen_clockwork.dmi index d620da7e7903e..ea0e545d4e3ed 100644 Binary files a/icons/hud/screen_clockwork.dmi and b/icons/hud/screen_clockwork.dmi differ diff --git a/icons/hud/screen_glass.dmi b/icons/hud/screen_glass.dmi index 08db68e4d247b..f60603ef63814 100644 Binary files a/icons/hud/screen_glass.dmi and b/icons/hud/screen_glass.dmi differ diff --git a/icons/hud/screen_midnight.dmi b/icons/hud/screen_midnight.dmi index d748823d4ce4c..496982bfa9e3c 100644 Binary files a/icons/hud/screen_midnight.dmi and b/icons/hud/screen_midnight.dmi differ diff --git a/icons/hud/screen_plasmafire.dmi b/icons/hud/screen_plasmafire.dmi index 652beabadd806..8cb1230ea5030 100644 Binary files a/icons/hud/screen_plasmafire.dmi and b/icons/hud/screen_plasmafire.dmi differ diff --git a/icons/hud/screen_slimecore.dmi b/icons/hud/screen_slimecore.dmi index 790575deae7df..6b1d25d2689d3 100644 Binary files a/icons/hud/screen_slimecore.dmi and b/icons/hud/screen_slimecore.dmi differ diff --git a/icons/obj/aquarium/fish.dmi b/icons/obj/aquarium/fish.dmi index 49856cc649fe9..4d18520cd9154 100644 Binary files a/icons/obj/aquarium/fish.dmi and b/icons/obj/aquarium/fish.dmi differ diff --git a/icons/obj/aquarium/rift.dmi b/icons/obj/aquarium/rift.dmi new file mode 100644 index 0000000000000..63c739fb32f9b Binary files /dev/null and b/icons/obj/aquarium/rift.dmi differ diff --git a/icons/obj/aquarium/wide.dmi b/icons/obj/aquarium/wide.dmi index 33c8e43950f96..02393fb3a7f7c 100644 Binary files a/icons/obj/aquarium/wide.dmi and b/icons/obj/aquarium/wide.dmi differ diff --git a/icons/obj/fishing.dmi b/icons/obj/fishing.dmi index 58ab9944366dd..59c40c02103c7 100644 Binary files a/icons/obj/fishing.dmi and b/icons/obj/fishing.dmi differ diff --git a/icons/obj/machines/coffeemaker.dmi b/icons/obj/machines/coffeemaker.dmi index 13bf70c93fe62..a42c0bebde1fd 100644 Binary files a/icons/obj/machines/coffeemaker.dmi and b/icons/obj/machines/coffeemaker.dmi differ diff --git a/icons/obj/medical/chemical.dmi b/icons/obj/medical/chemical.dmi index 8b1a3f574f828..6cadd13c60e3a 100644 Binary files a/icons/obj/medical/chemical.dmi and b/icons/obj/medical/chemical.dmi differ diff --git a/icons/obj/medical/reagent_fillings.dmi b/icons/obj/medical/reagent_fillings.dmi index 163f41641ddc0..0e4bd7f53ddf8 100644 Binary files a/icons/obj/medical/reagent_fillings.dmi and b/icons/obj/medical/reagent_fillings.dmi differ diff --git a/icons/obj/smooth_structures/girder.dmi b/icons/obj/smooth_structures/girder.dmi new file mode 100644 index 0000000000000..7360273cd1281 Binary files /dev/null and b/icons/obj/smooth_structures/girder.dmi differ diff --git a/icons/obj/smooth_structures/girder.png b/icons/obj/smooth_structures/girder.png new file mode 100644 index 0000000000000..6180650c22932 Binary files /dev/null and b/icons/obj/smooth_structures/girder.png differ diff --git a/icons/obj/smooth_structures/girder.png.toml b/icons/obj/smooth_structures/girder.png.toml new file mode 100644 index 0000000000000..781b9b2abf22a --- /dev/null +++ b/icons/obj/smooth_structures/girder.png.toml @@ -0,0 +1,2 @@ +output_name = "girder" +template = "bitmask/diagonal_32x32.toml" diff --git a/icons/obj/smooth_structures/reinforced_girder.dmi b/icons/obj/smooth_structures/reinforced_girder.dmi new file mode 100644 index 0000000000000..0e7d2f520bcee Binary files /dev/null and b/icons/obj/smooth_structures/reinforced_girder.dmi differ diff --git a/icons/obj/smooth_structures/reinforced_girder.png b/icons/obj/smooth_structures/reinforced_girder.png new file mode 100644 index 0000000000000..fba248a74e25b Binary files /dev/null and b/icons/obj/smooth_structures/reinforced_girder.png differ diff --git a/icons/obj/smooth_structures/reinforced_girder.png.toml b/icons/obj/smooth_structures/reinforced_girder.png.toml new file mode 100644 index 0000000000000..4e30db6adaea2 --- /dev/null +++ b/icons/obj/smooth_structures/reinforced_girder.png.toml @@ -0,0 +1,2 @@ +output_name = "reinforced" +template = "bitmask/diagonal_32x32.toml" diff --git a/icons/obj/wallmounts.dmi b/icons/obj/wallmounts.dmi index e70024a9edb23..3bc4510a47f15 100644 Binary files a/icons/obj/wallmounts.dmi and b/icons/obj/wallmounts.dmi differ diff --git a/modular_bandastation/aesthetics_sounds/code/closet.dm b/modular_bandastation/aesthetics_sounds/code/closet.dm index 3986cc77608d1..27fe8caa2a96a 100644 --- a/modular_bandastation/aesthetics_sounds/code/closet.dm +++ b/modular_bandastation/aesthetics_sounds/code/closet.dm @@ -1,18 +1,9 @@ /obj/structure/closet - var/list/togglelock_sound = list( + var/list/togglelock_sounds = list( 'modular_bandastation/aesthetics_sounds/sound/lock_1.ogg', 'modular_bandastation/aesthetics_sounds/sound/lock_2.ogg', 'modular_bandastation/aesthetics_sounds/sound/lock_3.ogg' ) -/obj/structure/closet/secure_closet/togglelock(mob/living/user, silent) - var/temp_locked = locked - . = ..() - if(temp_locked != locked) - playsound(loc, pick(togglelock_sound), 10, TRUE, -3) - -/obj/structure/closet/crate/secure/togglelock(mob/living/user, silent) - var/temp_locked = locked - . = ..() - if(temp_locked != locked) - playsound(loc, pick(togglelock_sound), 10, TRUE, -3) +/obj/structure/closet/play_closet_lock_sound() + playsound(loc, pick(togglelock_sounds), 10, TRUE, -3) diff --git a/sound/effects/compressed_air/attribution.txt b/sound/effects/compressed_air/attribution.txt index 1eff1ab751225..12d30ee0e19e7 100644 --- a/sound/effects/compressed_air/attribution.txt +++ b/sound/effects/compressed_air/attribution.txt @@ -1,8 +1,6 @@ -compressed_air1.ogg is taken from Freesound and converted to ogg: +tank_insert_clunky.ogg was created by mixing https://freesound.org/people/Geoff-Bremner-Audio/sounds/682952/ -compressed_air2.ogg is taken from Freesound and converted to ogg: -https://freesound.org/people/Geoff-Bremner-Audio/sounds/682816/ -tank_insert_clunky.ogg was created by mixing compressed_air1 and clunk sound from Freesound: +and https://freesound.org/people/BinaryMonkFlint/sounds/333296/ tank_remove_thunk.ogg was made by mixing two sound tracks from Freesound: https://freesound.org/people/lowdjinn/sounds/533885/ and; diff --git a/sound/effects/compressed_air/compressed_air1.ogg b/sound/effects/compressed_air/compressed_air1.ogg deleted file mode 100644 index 95ff29fcb07ab..0000000000000 Binary files a/sound/effects/compressed_air/compressed_air1.ogg and /dev/null differ diff --git a/sound/effects/compressed_air/compressed_air2.ogg b/sound/effects/compressed_air/compressed_air2.ogg deleted file mode 100644 index b05f52ee48575..0000000000000 Binary files a/sound/effects/compressed_air/compressed_air2.ogg and /dev/null differ diff --git a/sound/machines/closet/attribution.txt b/sound/machines/closet/attribution.txt new file mode 100644 index 0000000000000..b3a195838e8f3 --- /dev/null +++ b/sound/machines/closet/attribution.txt @@ -0,0 +1,2 @@ +closet_unlock.ogg made by sadboysuss, license: CC-BY-SA +closet_lock.ogg made by sadboysuss, license: CC-BY-SA \ No newline at end of file diff --git a/sound/machines/closet/closet_lock.ogg b/sound/machines/closet/closet_lock.ogg new file mode 100644 index 0000000000000..d66d0cafbe93c Binary files /dev/null and b/sound/machines/closet/closet_lock.ogg differ diff --git a/sound/machines/closet/closet_unlock.ogg b/sound/machines/closet/closet_unlock.ogg new file mode 100644 index 0000000000000..0c78ba219b0b8 Binary files /dev/null and b/sound/machines/closet/closet_unlock.ogg differ diff --git a/sound/machines/door/door_locked.ogg b/sound/machines/door/door_locked.ogg deleted file mode 100644 index 81807127b0910..0000000000000 Binary files a/sound/machines/door/door_locked.ogg and /dev/null differ diff --git a/strings/round_start_sounds.txt b/strings/round_start_sounds.txt index 9981097c30850..908abe2e58e4c 100644 --- a/strings/round_start_sounds.txt +++ b/strings/round_start_sounds.txt @@ -1,3 +1,4 @@ +sound/music/lobby_music/title0.ogg sound/music/lobby_music/title1.mod sound/music/lobby_music/title2.ogg sound/music/lobby_music/title3.ogg diff --git a/tgstation.dme b/tgstation.dme index 8fa36ea742eb2..0fb0b25756864 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -759,6 +759,7 @@ #include "code\controllers\subsystem\persistence\scars.dm" #include "code\controllers\subsystem\persistence\tattoos.dm" #include "code\controllers\subsystem\persistence\trophies.dm" +#include "code\controllers\subsystem\persistence\trophy_fishes.dm" #include "code\controllers\subsystem\processing\acid.dm" #include "code\controllers\subsystem\processing\ai_basic_avoidance.dm" #include "code\controllers\subsystem\processing\ai_behaviors.dm" @@ -2404,6 +2405,7 @@ #include "code\game\objects\items\extinguisher.dm" #include "code\game\objects\items\fireaxe.dm" #include "code\game\objects\items\flamethrower.dm" +#include "code\game\objects\items\flatpacks.dm" #include "code\game\objects\items\frog_statue.dm" #include "code\game\objects\items\gift.dm" #include "code\game\objects\items\gun_maintenance.dm" @@ -4216,6 +4218,7 @@ #include "code\modules\fishing\admin.dm" #include "code\modules\fishing\bait.dm" #include "code\modules\fishing\fish_catalog.dm" +#include "code\modules\fishing\fish_mount.dm" #include "code\modules\fishing\fish_movement.dm" #include "code\modules\fishing\fishing_equipment.dm" #include "code\modules\fishing\fishing_minigame.dm" @@ -4234,6 +4237,7 @@ #include "code\modules\fishing\fish\types\freshwater.dm" #include "code\modules\fishing\fish\types\holographic.dm" #include "code\modules\fishing\fish\types\mining.dm" +#include "code\modules\fishing\fish\types\rift.dm" #include "code\modules\fishing\fish\types\ruins.dm" #include "code\modules\fishing\fish\types\saltwater.dm" #include "code\modules\fishing\fish\types\station.dm" @@ -4762,7 +4766,6 @@ #include "code\modules\mining\equipment\explorer_gear.dm" #include "code\modules\mining\equipment\grapple_gun.dm" #include "code\modules\mining\equipment\kheiral_cuffs.dm" -#include "code\modules\mining\equipment\kinetic_crusher.dm" #include "code\modules\mining\equipment\lazarus_injector.dm" #include "code\modules\mining\equipment\marker_beacons.dm" #include "code\modules\mining\equipment\mineral_scanner.dm" @@ -4772,6 +4775,11 @@ #include "code\modules\mining\equipment\survival_pod.dm" #include "code\modules\mining\equipment\vent_pointer.dm" #include "code\modules\mining\equipment\wormhole_jaunter.dm" +#include "code\modules\mining\equipment\kinetic_crusher\kinetic_crusher.dm" +#include "code\modules\mining\equipment\kinetic_crusher\kinetic_crusher_trophies.dm" +#include "code\modules\mining\equipment\kinetic_crusher\trophies_fauna.dm" +#include "code\modules\mining\equipment\kinetic_crusher\trophies_megafauna.dm" +#include "code\modules\mining\equipment\kinetic_crusher\trophies_misc.dm" #include "code\modules\mining\equipment\monster_organs\brimdust_sac.dm" #include "code\modules\mining\equipment\monster_organs\monster_organ.dm" #include "code\modules\mining\equipment\monster_organs\regenerative_core.dm" @@ -4978,7 +4986,6 @@ #include "code\modules\mob\living\basic\lavaland\goliath\goliath.dm" #include "code\modules\mob\living\basic\lavaland\goliath\goliath_actions.dm" #include "code\modules\mob\living\basic\lavaland\goliath\goliath_ai.dm" -#include "code\modules\mob\living\basic\lavaland\goliath\goliath_trophy.dm" #include "code\modules\mob\living\basic\lavaland\goliath\tentacle.dm" #include "code\modules\mob\living\basic\lavaland\gutlunchers\gutluncher_foodtrough.dm" #include "code\modules\mob\living\basic\lavaland\gutlunchers\gutlunchers.dm" @@ -4995,7 +5002,6 @@ #include "code\modules\mob\living\basic\lavaland\legion\spawn_legions.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_ai.dm" -#include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_trophy.dm" #include "code\modules\mob\living\basic\lavaland\mook\mook.dm" #include "code\modules\mob\living\basic\lavaland\mook\mook_abilities.dm" #include "code\modules\mob\living\basic\lavaland\mook\mook_ai.dm" diff --git a/tgui/packages/tgui-panel/chat/constants.ts b/tgui/packages/tgui-panel/chat/constants.ts index 7a9798e005330..096149d075d99 100644 --- a/tgui/packages/tgui-panel/chat/constants.ts +++ b/tgui/packages/tgui-panel/chat/constants.ts @@ -24,6 +24,7 @@ export const MESSAGE_TYPE_INTERNAL = 'internal'; export const MESSAGE_TYPE_SYSTEM = 'system'; export const MESSAGE_TYPE_LOCALCHAT = 'localchat'; export const MESSAGE_TYPE_RADIO = 'radio'; +export const MESSAGE_TYPE_ENTERTAINMENT = 'entertainment'; export const MESSAGE_TYPE_INFO = 'info'; export const MESSAGE_TYPE_WARNING = 'warning'; export const MESSAGE_TYPE_DEADCHAT = 'deadchat'; @@ -60,7 +61,13 @@ export const MESSAGE_TYPES = [ name: 'Radio', description: 'All departments of radio messages', selector: - '.alert, .minorannounce, .syndradio, .centcomradio, .aiprivradio, .enteradio, .comradio, .secradio, .justiceradio, .gangradio, .engradio, .medradio, .sciradio, .suppradio, .servradio, .radio, .deptradio, .binarysay, .newscaster, .resonate, .abductor, .alien, .changeling', + '.alert, .minorannounce, .syndradio, .centcomradio, .aiprivradio, .comradio, .secradio, .justiceradio, .gangradio, .engradio, .medradio, .sciradio, .suppradio, .servradio, .radio, .deptradio, .binarysay, .resonate, .abductor, .alien, .changeling', + }, + { + type: MESSAGE_TYPE_ENTERTAINMENT, + name: 'Entertainment', + description: 'Entertainment and newscaster broadcasts', + selector: '.enteradio, .newscaster', }, { type: MESSAGE_TYPE_INFO, diff --git a/tgui/packages/tgui/interfaces/PaperSheet.tsx b/tgui/packages/tgui/interfaces/PaperSheet/Preview.tsx similarity index 56% rename from tgui/packages/tgui/interfaces/PaperSheet.tsx rename to tgui/packages/tgui/interfaces/PaperSheet/Preview.tsx index 50dd73a88ed86..84f9fe88f5d5c 100644 --- a/tgui/packages/tgui/interfaces/PaperSheet.tsx +++ b/tgui/packages/tgui/interfaces/PaperSheet/Preview.tsx @@ -1,99 +1,12 @@ -/** - * @license MIT - */ - -import { clamp } from 'common/math'; -import { classes } from 'common/react'; import { marked } from 'marked'; -import { Component, createRef, RefObject } from 'react'; - -import { useBackend, useLocalState } from '../backend'; -import { Box, Button, Flex, Section, TextArea } from '../components'; -import { Window } from '../layouts'; -import { sanitizeText } from '../sanitize'; - -const Z_INDEX_STAMP = 1; -const Z_INDEX_STAMP_PREVIEW = 2; - -const TEXTAREA_INPUT_HEIGHT = 200; - -type PaperContext = { - // ui_static_data - user_name: string; - raw_text_input?: PaperInput[]; - raw_field_input?: FieldInput[]; - raw_stamp_input?: StampInput[]; - max_length: number; - max_input_field_length: number; - paper_color: string; - paper_name: string; - default_pen_font: string; - default_pen_color: string; - signature_font: string; - sanitize_text: boolean; - - // ui_data - held_item_details?: WritingImplement; -}; - -type PaperInput = { - raw_text: string; - font?: string; - color?: string; - bold?: boolean; - advanced_html?: boolean; -}; - -type StampInput = { - class: string; - x: number; - y: number; - rotation: number; -}; - -type FieldInput = { - field_index: string; - field_data: PaperInput; - is_signature: boolean; -}; +import { Component, RefObject } from 'react'; -type WritingImplement = { - interaction_mode: InteractionType; - font?: string; - color?: string; - use_bold?: boolean; - stamp_icon_state?: string; - stamp_class?: string; -}; - -type PaperSheetStamperState = { - x: number; - y: number; - rotation: number; - yOffset: number; -}; - -type PaperSheetStamperProps = { - scrollableRef: RefObject; -}; - -type FieldCreationReturn = { - nextCounter: number; - text: string; -}; - -type StampPosition = { - x: number; - y: number; - rotation: number; - yOffset: number; -}; - -enum InteractionType { - reading = 0, - writing = 1, - stamping = 2, -} +import { useBackend, useLocalState } from '../../backend'; +import { Box, Section } from '../../components'; +import { sanitizeText } from '../../sanitize'; +import { canEdit, tokenizer, walkTokens } from './helpers'; +import { StampView } from './StampView'; +import { FieldInput, InteractionType, PaperContext } from './types'; type PreviewViewProps = { scrollableRef: RefObject; @@ -101,344 +14,14 @@ type PreviewViewProps = { textArea: string; }; -const canEdit = (heldItemDetails?: WritingImplement): boolean => { - if (!heldItemDetails) { - return false; - } - - return heldItemDetails.interaction_mode === InteractionType.writing; +type FieldCreationReturn = { + nextCounter: number; + text: string; }; // Regex that finds [____] fields. const fieldRegex: RegExp = /\[((?:_+))\]/gi; -// Handles the ghost stamp when attempting to stamp paper sheets. -class PaperSheetStamper extends Component { - style: null; - state: PaperSheetStamperState = { x: 0, y: 0, rotation: 0, yOffset: 0 }; - scrollableRef: RefObject; - - constructor(props) { - super(props); - - this.style = null; - this.scrollableRef = props.scrollableRef; - } - - // Stops propagation of a given event. - pauseEvent = (e: Event): boolean => { - if (e.stopPropagation) { - e.stopPropagation(); - } - if (e.preventDefault) { - e.preventDefault(); - } - e.cancelBubble = true; - e.returnValue = false; - return false; - }; - - handleMouseMove = (e: MouseEvent): void => { - const pos = this.findStampPosition(e); - if (!pos) { - return; - } - - this.pauseEvent(e); - this.setState({ - x: pos.x, - y: pos.y, - rotation: pos.rotation, - yOffset: pos.yOffset, - }); - }; - - handleMouseClick = (e: MouseEvent): void => { - if (e.pageY <= 30) { - return; - } - const { act } = useBackend(); - - act('add_stamp', { - x: this.state.x, - y: this.state.y + this.state.yOffset, - rotation: this.state.rotation, - }); - }; - - findStampPosition(e: MouseEvent): StampPosition | void { - let rotating; - const scrollable = this.scrollableRef.current; - - if (!scrollable) { - return; - } - - const stampYOffset = scrollable.scrollTop || 0; - - const stamp = document.getElementById('stamp'); - if (!stamp) { - return; - } - - if (e.shiftKey) { - rotating = true; - } - - const stampHeight = stamp.clientHeight; - const stampWidth = stamp.clientWidth; - - const currentHeight = rotating ? this.state.y : e.pageY - stampHeight; - const currentWidth = rotating ? this.state.x : e.pageX - stampWidth / 2; - - const widthMin = 0; - const heightMin = 0; - - const widthMax = scrollable.clientWidth - stampWidth; - const heightMax = scrollable.clientHeight - stampHeight; - - const radians = Math.atan2( - currentWidth + stampWidth / 2 - e.pageX, - currentHeight + stampHeight - e.pageY, - ); - - const rotate = rotating - ? radians * (180 / Math.PI) * -1 - : this.state.rotation; - - return { - x: clamp(currentWidth, widthMin, widthMax), - y: clamp(currentHeight, heightMin, heightMax), - rotation: rotate, - yOffset: stampYOffset, - }; - } - - componentDidMount() { - document.addEventListener('mousemove', this.handleMouseMove); - document.addEventListener('click', this.handleMouseClick); - } - - componentWillUnmount() { - document.removeEventListener('mousemove', this.handleMouseMove); - document.removeEventListener('click', this.handleMouseClick); - } - - render() { - const { data } = useBackend(); - const { held_item_details } = data; - - if (!held_item_details?.stamp_class) { - return; - } - - return ( - - ); - } -} - -// Creates a full stamp div to render the given stamp to the preview. -export const Stamp = (props) => { - const { activeStamp, sprite, x, y, rotation, opacity, yOffset = 0 } = props; - const stamp_transform = { - left: x + 'px', - top: y + yOffset + 'px', - transform: 'rotate(' + rotation + 'deg)', - opacity: opacity || 1.0, - zIndex: activeStamp ? Z_INDEX_STAMP_PREVIEW : Z_INDEX_STAMP, - }; - - return ( -
- ); -}; - -// Overarching component that holds the primary view for papercode. -export class PrimaryView extends Component { - // Reference that gets passed to the
holding the main preview. - // Eventually gets filled with a reference to the section's scroll bar - // funtionality. - scrollableRef: RefObject; - - // The last recorded distance the scrollbar was from the bottom. - // Used to implement "text scrolls up instead of down" behaviour. - lastDistanceFromBottom: number; - - // Event handler for the onscroll event. Also gets passed to the
- // holding the main preview. Updates lastDistanceFromBottom. - onScrollHandler: (this: GlobalEventHandlers, ev: Event) => any; - - constructor(props) { - super(props); - this.scrollableRef = createRef(); - this.lastDistanceFromBottom = 0; - - this.onScrollHandler = (ev) => { - const scrollable = ev.currentTarget as HTMLDivElement; - if (scrollable) { - this.lastDistanceFromBottom = - scrollable.scrollHeight - scrollable.scrollTop; - } - }; - } - - render() { - const { act, data } = useBackend(); - const { - raw_text_input, - raw_field_input, - default_pen_font, - default_pen_color, - paper_color, - held_item_details, - max_length, - } = data; - - const useFont = held_item_details?.font || default_pen_font; - const useColor = held_item_details?.color || default_pen_color; - const useBold = held_item_details?.use_bold || false; - - const [inputFieldData, setInputFieldData] = useLocalState( - 'inputFieldData', - {}, - ); - - const [textAreaText, setTextAreaText] = useLocalState('textAreaText', ''); - - const interactMode = - held_item_details?.interaction_mode || InteractionType.reading; - - const savableData = - textAreaText.length || Object.keys(inputFieldData).length; - - const dmCharacters = - raw_text_input?.reduce((lhs: number, rhs: PaperInput) => { - return lhs + rhs.raw_text.length; - }, 0) || 0; - - const usedCharacters = dmCharacters + textAreaText.length; - - const tooManyCharacters = usedCharacters > max_length; - - return ( - <> - - - - - - {interactMode === InteractionType.writing && ( - -
- - {`${usedCharacters} / ${max_length}`} - - { - if (textAreaText.length) { - act('add_text', { text: textAreaText }); - setTextAreaText(''); - } - if (Object.keys(inputFieldData).length) { - act('fill_input_field', { - field_data: inputFieldData, - }); - setInputFieldData({}); - } - }} - /> - - } - > -