From a7ef55b672cd3ae8ecbe532e2565249bcbbc3eb0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:26:21 +0000 Subject: [PATCH 001/142] Automatic changelog for PR #86523 [ci skip] --- html/changelogs/AutoChangeLog-pr-86523.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86523.yml diff --git a/html/changelogs/AutoChangeLog-pr-86523.yml b/html/changelogs/AutoChangeLog-pr-86523.yml new file mode 100644 index 00000000000..f576366ad7d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86523.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - qol: "Medical HUD and crew console can now detect broken (shorted out) suit sensors needing repair" \ No newline at end of file From aa851c788586de73acd93fd409b1183d48876c8b Mon Sep 17 00:00:00 2001 From: Zytolg <33048583+Zytolg@users.noreply.github.com> Date: Sat, 14 Sep 2024 14:17:32 -0600 Subject: [PATCH 002/142] Tool Storage Supply Drop (#86558) ## About The Pull Request The Birdshot Quartermaster has finally restocked Birdshot's tool storage and cleaned up some of the leftover garbage. ## Why It's Good For The Game Should add some freebie tools for the initial assistant rush. Basically there's stuff worth fighting over in there now. Like Fortnite. Also this is a continuation of an earlier topic on discord. Birdshot gets actionable feedback, I fix. Repeat. etc.etc. ## Changelog :cl: qol: The Birdshot Tool Storage has been resupplied. New tools are at the crews displosal. /:cl: --- _maps/map_files/Birdshot/birdshot.dmm | 545 ++++++++++++++------------ 1 file changed, 287 insertions(+), 258 deletions(-) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 026e22524e9..12dae68ff37 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -1677,23 +1677,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/central/lesser) -"aGI" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/trash/can/food/pine_nuts{ - pixel_x = 16; - pixel_y = 6 - }, -/obj/machinery/cell_charger{ - pixel_x = -1; - pixel_y = 2 - }, -/obj/item/stock_parts/power_store/cell/high{ - pixel_x = -1; - pixel_y = 1 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "aGU" = ( /obj/machinery/light/small/directional/west, /turf/open/floor/iron, @@ -7158,6 +7141,15 @@ /obj/machinery/door/poddoor/incinerator_atmos_aux, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) +"cMH" = ( +/obj/structure/table, +/obj/item/toy/foamblade, +/obj/item/analyzer{ + pixel_y = 8; + pixel_x = -9 + }, +/turf/open/floor/iron/dark/small, +/area/station/commons/fitness/locker_room) "cMS" = ( /obj/structure/cable, /obj/structure/chair/stool/directional/north, @@ -7213,23 +7205,6 @@ /obj/structure/window/spawner/directional/west, /turf/open/misc/sandy_dirt, /area/station/commons/fitness/recreation/entertainment) -"cOB" = ( -/obj/structure/table/reinforced, -/obj/item/folder/yellow{ - pixel_x = 13; - pixel_y = 1 - }, -/obj/item/flashlight/lamp{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/clothing/ears/earmuffs{ - pixel_x = 15; - pixel_y = 7 - }, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "cOC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8792,6 +8767,14 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) +"dpz" = ( +/obj/machinery/atmospherics/pipe/smart/simple/purple/visible, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light_switch/directional/west, +/obj/effect/landmark/event_spawn, +/obj/machinery/portable_atmospherics/pump/lil_pump, +/turf/open/floor/iron/dark, +/area/station/science/ordnance) "dpH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/mix_output{ dir = 8 @@ -12153,6 +12136,26 @@ /obj/machinery/camera/directional/west, /turf/open/floor/iron/smooth, /area/station/commons/storage/tools) +"eEu" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/crowbar/large{ + pixel_y = 18 + }, +/obj/item/clothing/head/costume/pirate{ + pixel_x = 15; + pixel_y = -3 + }, +/obj/item/clothing/suit/hazardvest{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/item/wrench{ + pixel_y = 15 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "eEL" = ( /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, @@ -13707,15 +13710,6 @@ /obj/structure/closet/secure_closet/atmospherics, /turf/open/floor/iron/dark, /area/station/engineering/atmos/office) -"fks" = ( -/obj/structure/chair/stool/directional/south, -/obj/effect/turf_decal/siding/yellow{ - dir = 1 - }, -/obj/effect/landmark/start/atmospheric_technician, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "fkF" = ( /obj/structure/table/wood, /obj/item/pen/red{ @@ -15972,18 +15966,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) -"fVO" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/siding/yellow{ - dir = 4 - }, -/obj/effect/spawner/random/food_or_drink/donkpockets{ - pixel_y = 6 - }, -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/turf/open/floor/wood, -/area/station/engineering/break_room) "fVU" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -18650,22 +18632,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/maintenance/disposal/incinerator) -"gQG" = ( -/obj/structure/window/spawner/directional/east, -/obj/structure/closet/crate, -/obj/effect/turf_decal/bot_white, -/obj/item/stack/package_wrap{ - pixel_y = 5 - }, -/obj/item/stack/package_wrap{ - pixel_y = 2 - }, -/obj/item/storage/box{ - desc = "It smells of monkey business..."; - name = "Empty Gorillacube Box" - }, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) "gRm" = ( /obj/structure/flora/bush/flowers_br, /obj/structure/flora/bush/flowers_pp/style_random, @@ -19609,22 +19575,6 @@ dir = 4 }, /area/station/commons/storage/tools) -"hgd" = ( -/obj/structure/table, -/obj/item/clothing/head/collectable/paper{ - pixel_x = -6; - pixel_y = -2 - }, -/obj/item/paper/crumpled{ - pixel_x = 5; - pixel_y = 8 - }, -/obj/item/trash/candle{ - pixel_x = 7; - pixel_y = 1 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "hgf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/green{ @@ -19976,17 +19926,6 @@ dir = 4 }, /area/station/commons/storage/tools) -"hmj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 5; - pixel_y = 3 - }, -/obj/item/storage/toolbox/emergency/old, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "hmk" = ( /obj/structure/chair/stool/directional/east, /turf/open/floor/iron/smooth, @@ -20032,27 +19971,6 @@ dir = 1 }, /area/station/service/bar/backroom) -"hmQ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/toolbox/mechanical/old{ - pixel_x = 15; - pixel_y = 15 - }, -/obj/item/crowbar/large{ - pixel_y = 18 - }, -/obj/item/clothing/head/costume/pirate{ - pixel_x = 17; - pixel_y = -10 - }, -/obj/item/clothing/suit/hazardvest{ - pixel_x = -3; - pixel_y = -2 - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "hnf" = ( /obj/item/bikehorn/rubberducky{ pixel_x = -6; @@ -20424,19 +20342,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"huh" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white, -/obj/structure/rack, -/obj/item/stack/cable_coil/five, -/obj/item/pickaxe, -/obj/item/wrench, -/obj/item/radio/off, -/obj/structure/sign/poster/official/random/directional/west, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) "huj" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -25820,6 +25725,21 @@ /obj/machinery/light_switch/directional/south, /turf/open/floor/iron/dark/small, /area/station/service/chapel/storage) +"jes" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/tank/internals/emergency_oxygen{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/gps{ + pixel_y = 5; + pixel_x = 13 + }, +/obj/item/storage/toolbox/emergency/old, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "jeC" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -33494,6 +33414,23 @@ }, /turf/open/floor/grass, /area/station/service/chapel) +"lzH" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/cell_charger{ + pixel_x = -1; + pixel_y = 4 + }, +/obj/item/stock_parts/power_store/cell/high{ + pixel_x = -1; + pixel_y = 4 + }, +/obj/item/assembly/timer{ + pixel_x = 14; + pixel_y = 6 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "lzM" = ( /turf/closed/wall, /area/station/security/tram) @@ -34473,11 +34410,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/diagonal, /area/station/engineering/lobby) -"lNN" = ( -/obj/structure/table, -/obj/item/toy/foamblade, -/turf/open/floor/iron/dark/small, -/area/station/commons/fitness/locker_room) "lNQ" = ( /obj/effect/turf_decal/bot_white/right, /obj/machinery/firealarm/directional/north, @@ -34886,6 +34818,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"lVv" = ( +/obj/structure/chair/stool/directional/south, +/obj/effect/turf_decal/siding/yellow{ + dir = 1 + }, +/obj/effect/landmark/start/atmospheric_technician, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/engineering/break_room) "lVy" = ( /obj/effect/turf_decal/tile/green/anticorner/contrasted{ dir = 8 @@ -35258,17 +35199,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/hallway/secondary/dock) -"lZP" = ( -/obj/structure/table, -/obj/item/clothing/head/fedora/det_hat/minor{ - pixel_x = 7; - pixel_y = 9 - }, -/obj/item/toy/eightball{ - pixel_x = -4 - }, -/turf/open/floor/iron/dark/small, -/area/station/commons/fitness/locker_room) "lZR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, @@ -36187,25 +36117,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/station/hallway/secondary/dock) -"mrP" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table, -/obj/item/folder/red, -/obj/item/food/monkeycube/bee{ - name = "monkey cube"; - pixel_y = 17 - }, -/obj/item/food/monkeycube/chicken{ - pixel_y = 15; - pixel_x = 6; - name = "monkey cube"; - desc = "A new Nanotrasen classic, the monkey cube. Tastes like everything!" - }, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "msg" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -36683,13 +36594,6 @@ /obj/structure/sign/poster/official/soft_cap_pop_art/directional/north, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"mBP" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth_large, -/area/station/engineering/supermatter/room) "mCf" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/external/glass{ @@ -37926,11 +37830,6 @@ }, /turf/open/floor/iron/smooth, /area/station/security/checkpoint/customs) -"mYk" = ( -/obj/machinery/atmospherics/pipe/smart/simple/dark/visible, -/obj/machinery/portable_atmospherics/pump, -/turf/open/floor/iron/dark, -/area/station/science/ordnance) "mYm" = ( /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 10 @@ -38048,20 +37947,6 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron/smooth, /area/station/maintenance/solars/starboard/aft) -"nai" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/holopad, -/obj/effect/decal/cleanable/dirt/dust, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "nay" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/airlock/public/glass{ @@ -39837,6 +39722,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/engineering/main) +"nGS" = ( +/obj/structure/table, +/obj/item/screwdriver{ + pixel_y = -6 + }, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 7 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "nHd" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -39859,6 +39754,23 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/office) +"nHq" = ( +/obj/structure/table/reinforced, +/obj/item/folder/yellow{ + pixel_x = 13; + pixel_y = 1 + }, +/obj/item/flashlight/lamp{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/clothing/ears/earmuffs{ + pixel_x = 15; + pixel_y = 7 + }, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/engineering/break_room) "nHu" = ( /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/plating, @@ -40350,6 +40262,20 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron/smooth, /area/station/engineering/break_room) +"nQE" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/holopad, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "nQH" = ( /obj/structure/closet{ name = "Paramedic Supplies" @@ -41369,15 +41295,6 @@ /obj/machinery/light/floor, /turf/open/floor/iron/dark, /area/station/security/lockers) -"okh" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/plating/elevatorshaft, -/area/station/engineering/break_room) "okk" = ( /obj/structure/table, /obj/item/screwdriver, @@ -43823,6 +43740,29 @@ /obj/machinery/portable_atmospherics/pipe_scrubber, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage) +"pdQ" = ( +/obj/structure/window/spawner/directional/east, +/obj/structure/closet/crate, +/obj/effect/turf_decal/bot_white, +/obj/item/clothing/gloves/color/fyellow, +/obj/item/stack/package_wrap{ + pixel_y = 5 + }, +/obj/item/stack/package_wrap{ + pixel_y = 2 + }, +/obj/item/storage/box{ + desc = "It smells of monkey business..."; + name = "Empty Gorillacube Box" + }, +/obj/item/weldingtool, +/obj/item/radio{ + pixel_y = 3; + pixel_x = -6 + }, +/obj/item/assembly/signaler, +/turf/open/floor/iron/smooth, +/area/station/commons/storage/tools) "pdR" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -46289,6 +46229,30 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"pUG" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table, +/obj/item/folder/red{ + pixel_y = 3 + }, +/obj/item/food/monkeycube/bee{ + name = "monkey cube"; + pixel_y = 17 + }, +/obj/item/food/monkeycube/chicken{ + pixel_y = 15; + pixel_x = 6; + name = "monkey cube"; + desc = "A new Nanotrasen classic, the monkey cube. Tastes like everything!" + }, +/obj/item/wirecutters{ + pixel_y = 6 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "pUL" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/table/reinforced/plastitaniumglass, @@ -47015,14 +46979,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/white/small, /area/station/commons/toilet/restrooms) -"qgK" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/kirbyplants/random, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/smooth, -/area/station/commons/storage/tools) "qhh" = ( /obj/structure/cable, /obj/structure/table/glass, @@ -47810,6 +47766,15 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/tcommsat/server) +"qxF" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating/elevatorshaft, +/area/station/engineering/break_room) "qxN" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -51227,6 +51192,18 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet/lone, /area/station/service/abandoned_gambling_den) +"rDc" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/siding/yellow{ + dir = 4 + }, +/obj/effect/spawner/random/food_or_drink/donkpockets{ + pixel_y = 6 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/turf/open/floor/wood, +/area/station/engineering/break_room) "rDj" = ( /obj/structure/chair/sofa/bench/left{ dir = 8 @@ -53636,6 +53613,15 @@ }, /turf/open/floor/iron/textured_half, /area/station/cargo/miningoffice) +"stM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/item/kirbyplants/random, +/obj/machinery/firealarm/directional/south, +/obj/item/storage/belt/utility, +/turf/open/floor/iron/smooth, +/area/station/commons/storage/tools) "stP" = ( /obj/effect/turf_decal/siding{ dir = 1 @@ -56719,14 +56705,6 @@ /obj/structure/flora/grass/jungle/b/style_random, /turf/open/floor/grass, /area/station/service/chapel) -"ttj" = ( -/obj/machinery/atmospherics/pipe/smart/simple/purple/visible, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light_switch/directional/west, -/obj/effect/landmark/event_spawn, -/obj/machinery/portable_atmospherics/pump/lil_pump, -/turf/open/floor/iron/dark, -/area/station/science/ordnance) "tts" = ( /obj/structure/altar_of_gods, /obj/item/book/bible, @@ -57547,6 +57525,26 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"tGW" = ( +/obj/effect/decal/cleanable/molten_object, +/obj/effect/landmark/event_spawn, +/obj/structure/table, +/obj/item/reagent_containers/cup/bottle/welding_fuel{ + pixel_y = -3; + pixel_x = 13 + }, +/obj/item/stack/sheet/iron/ten{ + pixel_y = -6; + pixel_x = -2 + }, +/obj/item/hand_labeler{ + pixel_y = -15 + }, +/obj/item/reagent_containers/cup/watering_can{ + pixel_y = 12 + }, +/turf/open/floor/iron/dark, +/area/station/commons/storage/tools) "tHa" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -59067,6 +59065,13 @@ }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) +"ugt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "ugA" = ( /obj/effect/turf_decal/siding/yellow{ dir = 1 @@ -63714,6 +63719,12 @@ /obj/effect/turf_decal/tile/dark_red/opposingcorners, /turf/open/floor/iron, /area/station/security/lockers) +"vDS" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/obj/item/clothing/suit/hooded/wintercoat/engineering, +/obj/structure/cable, +/turf/open/floor/iron/small, +/area/station/engineering/break_room) "vDV" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/cmo) @@ -65723,6 +65734,13 @@ /obj/structure/tank_holder/extinguisher, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"wjw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/engineering/supermatter/room) "wjG" = ( /obj/structure/filingcabinet, /turf/open/floor/iron/dark/small, @@ -66667,13 +66685,6 @@ /obj/machinery/light/warm/directional/east, /turf/open/floor/iron/dark, /area/station/science/genetics) -"wyG" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "wyH" = ( /obj/machinery/door/airlock/maintenance{ name = "Maintenance" @@ -67220,6 +67231,20 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/station/maintenance/department/science/xenobiology) +"wJr" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/obj/structure/rack, +/obj/item/hand_labeler, +/obj/item/stack/cable_coil/five, +/obj/item/pickaxe, +/obj/item/wrench, +/obj/item/radio/off, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron/smooth, +/area/station/commons/storage/tools) "wJv" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood/corner{ @@ -67694,12 +67719,6 @@ /obj/effect/landmark/navigate_destination/disposals, /turf/open/floor/iron, /area/station/maintenance/hallway/abandoned_command) -"wOZ" = ( -/obj/effect/decal/cleanable/molten_object, -/obj/effect/landmark/event_spawn, -/obj/structure/table, -/turf/open/floor/iron/dark, -/area/station/commons/storage/tools) "wPd" = ( /turf/closed/wall/r_wall, /area/station/maintenance/starboard/lesser) @@ -68633,12 +68652,6 @@ }, /turf/open/floor/iron/small, /area/station/engineering/atmos/pumproom) -"xcX" = ( -/obj/structure/closet/secure_closet/engineering_personal, -/obj/item/clothing/suit/hooded/wintercoat/engineering, -/obj/structure/cable, -/turf/open/floor/iron/small, -/area/station/engineering/break_room) "xda" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -70062,6 +70075,11 @@ /obj/structure/bed/maint, /turf/open/floor/light/colour_cycle/dancefloor_b, /area/station/maintenance/starboard/central) +"xwn" = ( +/obj/machinery/atmospherics/pipe/smart/simple/dark/visible, +/obj/machinery/portable_atmospherics/pump, +/turf/open/floor/iron/dark, +/area/station/science/ordnance) "xwr" = ( /obj/effect/turf_decal/siding/thinplating_new/light, /obj/machinery/recharge_station, @@ -70737,6 +70755,17 @@ }, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/security/checkpoint/escape) +"xGr" = ( +/obj/structure/table, +/obj/item/toy/eightball{ + pixel_x = -4 + }, +/obj/item/wirecutters{ + pixel_y = 17; + pixel_x = 4 + }, +/turf/open/floor/iron/dark/small, +/area/station/commons/fitness/locker_room) "xGw" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -88388,7 +88417,7 @@ kMe nDJ lWV cYt -mBP +wjw gAV tDu ccA @@ -89463,7 +89492,7 @@ aus voz sRg hmb -huh +wJr slY slY qQP @@ -90232,8 +90261,8 @@ slY slY eVc hbw -wOZ -hmj +tGW +jes arL sRg slY @@ -90487,10 +90516,10 @@ sRg cJT eEq sRg -gQG +pdQ hbw -aGI -hmQ +lzH +eEu pGE jug rqq @@ -90746,8 +90775,8 @@ mGY hXf xGf jLb -hgd -mrP +nGS +pUG xrZ sRg xat @@ -90964,10 +90993,10 @@ gAV qkq wRy urz -xcX -wyG -fks -cOB +vDS +ugt +lVv +nHq exQ fib cca @@ -91224,7 +91253,7 @@ ayK swK jTf nCC -fVO +rDc qQi sVu wfn @@ -91263,7 +91292,7 @@ hgZ hgZ kaz eOk -qgK +stM xPX wzo hLm @@ -91481,7 +91510,7 @@ ayK nXC nmi cED -nai +nQE rLj gNt iIK @@ -91738,7 +91767,7 @@ ayK wfn wfn osT -okh +qxF wap wfn gKL @@ -105158,7 +105187,7 @@ sRL bCP dqB pIf -lZP +xGr jgF wqj rEa @@ -105670,7 +105699,7 @@ nVa fuD xVV eWP -lNN +cMH lWp xhD heN @@ -122153,7 +122182,7 @@ lkV iJL rci vTv -ttj +dpz boY agI kQt @@ -122924,7 +122953,7 @@ nWh xnR aLC wLZ -mYk +xwn cns vwJ kQt From f99b4a4d068e379086f082abb3b385705defce97 Mon Sep 17 00:00:00 2001 From: lessthanthree <83487515+lessthnthree@users.noreply.github.com> Date: Sat, 14 Sep 2024 13:17:53 -0700 Subject: [PATCH 003/142] Fix disposal bin label on Icebox (#86644) ## About The Pull Request Fixes a mislabelled disposal bin on Icebox ## Why It's Good For The Game Less cargo yelling at medbay for flushing dead bodies down disposals. Less coroner yelling at medbay wondering where the bodies are. ## Changelog :cl: LT3 fix: Fixed a mislabelled corpse disposal in Icebox medbay, probably less dead bodies showing up in cargo /:cl: --- _maps/map_files/IceBoxStation/IceBoxStation.dmm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index d10c4403a0b..e58006155f9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -40898,10 +40898,7 @@ /turf/open/floor/iron, /area/station/maintenance/department/electrical) "lOV" = ( -/obj/machinery/disposal/bin{ - desc = "A pneumatic waste disposal unit. This one leads to the morgue."; - name = "corpse disposal" - }, +/obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 4 }, From 40d76b6cab42c7ba938ad561d10b64b013564123 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:17:54 +0000 Subject: [PATCH 004/142] Automatic changelog for PR #86558 [ci skip] --- html/changelogs/AutoChangeLog-pr-86558.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86558.yml diff --git a/html/changelogs/AutoChangeLog-pr-86558.yml b/html/changelogs/AutoChangeLog-pr-86558.yml new file mode 100644 index 00000000000..f7de2e9a907 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86558.yml @@ -0,0 +1,4 @@ +author: "Zytolg" +delete-after: True +changes: + - qol: "The Birdshot Tool Storage has been resupplied. New tools are at the crews displosal." \ No newline at end of file From 7b8308c710cea9bf664ae6222555af1e446aa3f0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:18:13 +0000 Subject: [PATCH 005/142] Automatic changelog for PR #86644 [ci skip] --- html/changelogs/AutoChangeLog-pr-86644.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86644.yml diff --git a/html/changelogs/AutoChangeLog-pr-86644.yml b/html/changelogs/AutoChangeLog-pr-86644.yml new file mode 100644 index 00000000000..bfad1cb60da --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86644.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - bugfix: "Fixed a mislabelled corpse disposal in Icebox medbay, probably less dead bodies showing up in cargo" \ No newline at end of file From dea709b57c09047830a31ae1dcd027afca9f8b77 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:24:29 +0300 Subject: [PATCH 006/142] Fixes a typo in DeForest medical crates (#86629) ## About The Pull Request Closes #86628 ## Changelog :cl: spellcheck: Fixed a typo in DeForest medical crates /:cl: --- code/game/objects/structures/crates_lockers/crates.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 26c183adc96..2fed72c5bab 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -228,7 +228,7 @@ /obj/structure/closet/crate/deforest name = "deforest medical crate" - desc = "A DeFortest brand crate of medical supplies." + desc = "A DeForest brand crate of medical supplies." icon_state = "deforest" base_icon_state = "deforest" From 1c621071fef1a7a9d6f639a9c780977e7fc6f1b5 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:25:00 +0300 Subject: [PATCH 007/142] Updates glowing yellow extract sprite (#86626) ## About The Pull Request Slime extracts got updated in #83891 but poor slime flashlight was forgotten about ![image](https://github.com/user-attachments/assets/10ca2494-d933-493c-a71c-8e50af5c4255) ## Why It's Good For The Game Consistent spritework ## Changelog :cl: image: Updated glowing yellow extract sprite /:cl: --- icons/obj/lighting.dmi | Bin 79480 -> 75535 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index 2bda7341e518f5098aecf1afd29bc38db4f98d57..0a953cff78272e30c1e1ea98750ef1fb298dd8ad 100644 GIT binary patch literal 75535 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

-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

I1H^MnE;ZG~L0_t_NYg0738!+8)JGAXf#lAfp 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 w>8oY%oX#xX2rlWGG2dGq1HICY!wuF?Ve@CN$Cf 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 From 708e526c9f1d024deddcd9eb00750a81ad8b632f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:25:07 +0000 Subject: [PATCH 008/142] Automatic changelog for PR #86629 [ci skip] --- html/changelogs/AutoChangeLog-pr-86629.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86629.yml diff --git a/html/changelogs/AutoChangeLog-pr-86629.yml b/html/changelogs/AutoChangeLog-pr-86629.yml new file mode 100644 index 00000000000..5160a9eb11b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86629.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - spellcheck: "Fixed a typo in DeForest medical crates" \ No newline at end of file From f41b47d8284113f5168237f8ba1bd37b2d2696ee Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:25:21 +0000 Subject: [PATCH 009/142] Automatic changelog for PR #86626 [ci skip] --- html/changelogs/AutoChangeLog-pr-86626.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86626.yml diff --git a/html/changelogs/AutoChangeLog-pr-86626.yml b/html/changelogs/AutoChangeLog-pr-86626.yml new file mode 100644 index 00000000000..a3c5a6ab1e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86626.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Updated glowing yellow extract sprite" \ No newline at end of file From df4ed37aeec77374afadade3d92d4f1176ad1b87 Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:25:37 +0300 Subject: [PATCH 010/142] basic ai pauses during do afters (#86615) ## About The Pull Request when making able_to_run event based, we forgot to account for this! ## Why It's Good For The Game closes #86614 ## Changelog :cl: fix: fixes basic AI that are supposed to pause during actions not pausing /:cl: --- code/datums/ai/basic_mobs/base_basic_controller.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/datums/ai/basic_mobs/base_basic_controller.dm b/code/datums/ai/basic_mobs/base_basic_controller.dm index a14630fa0e8..f21d31b0500 100644 --- a/code/datums/ai/basic_mobs/base_basic_controller.dm +++ b/code/datums/ai/basic_mobs/base_basic_controller.dm @@ -19,9 +19,12 @@ /datum/ai_controller/basic_controller/setup_able_to_run() . = ..() RegisterSignal(pawn, COMSIG_MOB_INCAPACITATE_CHANGED, PROC_REF(update_able_to_run)) + if(ai_traits & PAUSE_DURING_DO_AFTER) + RegisterSignals(pawn, list(COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED), PROC_REF(update_able_to_run)) + /datum/ai_controller/basic_controller/clear_able_to_run() - UnregisterSignal(pawn, list(COMSIG_MOB_INCAPACITATE_CHANGED, COMSIG_MOB_STATCHANGE)) + UnregisterSignal(pawn, list(COMSIG_MOB_INCAPACITATE_CHANGED, COMSIG_MOB_STATCHANGE, COMSIG_DO_AFTER_BEGAN, COMSIG_DO_AFTER_ENDED)) return ..() /datum/ai_controller/basic_controller/get_able_to_run() From 06085005bdf93c87a6d49b859c7e5457866114a4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:25:56 +0000 Subject: [PATCH 011/142] Automatic changelog for PR #86615 [ci skip] --- html/changelogs/AutoChangeLog-pr-86615.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86615.yml diff --git a/html/changelogs/AutoChangeLog-pr-86615.yml b/html/changelogs/AutoChangeLog-pr-86615.yml new file mode 100644 index 00000000000..ca33994d978 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86615.yml @@ -0,0 +1,4 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - bugfix: "fixes basic AI that are supposed to pause during actions not pausing" \ No newline at end of file From 072a8466204c5842ce4988c786ec9734dbef788d Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:26:10 +0300 Subject: [PATCH 012/142] Updates tank holder sprites (#86627) ## About The Pull Request ![image](https://github.com/user-attachments/assets/0edff89b-1287-48ae-9874-c89efccb7b8b) Updates sprites for tanks inside of tank holders to fit in with their own new sprites ## Why It's Good For The Game Currently tank holders are still using outdated tank palettes/shading which is a bit annoying ## Changelog :cl: image: Tanks inside of tank holders have received new sprites /:cl: --- icons/obj/canisters.dmi | Bin 16553 -> 15815 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/canisters.dmi b/icons/obj/canisters.dmi index 1555cf0a4782e2990bde2ac7b2a19bc16fd5ee89..0b38b08f98cf1ae21c6a3998d9ea75f3e251293c 100644 GIT binary patch literal 15815 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 literal 16553 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 From 386d468ea346fe813887c14dd2151f19f7dfce19 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:26:32 +0000 Subject: [PATCH 013/142] Automatic changelog for PR #86627 [ci skip] --- html/changelogs/AutoChangeLog-pr-86627.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86627.yml diff --git a/html/changelogs/AutoChangeLog-pr-86627.yml b/html/changelogs/AutoChangeLog-pr-86627.yml new file mode 100644 index 00000000000..e84b93326d6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86627.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Tanks inside of tank holders have received new sprites" \ No newline at end of file From 4ad0ebbac3a8e05bcb3da38c08da2db3c5b2e206 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:27:16 +0300 Subject: [PATCH 014/142] Humans that never had a player controlling them no longer count towards changeling absorption counter (#86631) ## About The Pull Request If a DNA absorption victim doesn't have a client/mind (i.e. monkey or spawned corpse, most of the time) they no longer count towards the absorption counter / refresh your respec. This affects only one ability, that being bloody spiders which requires you to succ 3 people in order to buy it. ## Why It's Good For The Game Blood spiders is a potent tool in right hands and I don't think that it should be acquirable by just visiting genetics/xenobiology/virology/cargo for some monkey cubes. This will force antags who want to get a strong ability to interact with the crew a bit more instead of spending first 15 minutes "powering up" ## Changelog :cl: balance: Humans that never had a player controlling them no longer count towards changeling absorption counter /:cl: --- code/modules/antagonists/changeling/powers/absorb.dm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 7e13612153b..d5ee0c2fc87 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -41,9 +41,14 @@ owner.visible_message(span_danger("[owner] sucks the fluids from [target]!"), span_notice("We have absorbed [target].")) to_chat(target, span_userdanger("You are absorbed by the changeling!")) + var/true_absorbtion = (!isnull(target.client) || !isnull(target.mind) || !isnull(target.last_mind)) + if (!true_absorbtion) + to_chat(owner, span_changeling(span_bold("You absorb [target], but their weak DNA is not enough to satisfy your hunger."))) + if(!changeling.has_profile_with_dna(target.dna)) changeling.add_new_profile(target) - changeling.true_absorbs++ + if (true_absorbtion) + changeling.true_absorbs++ if(owner.nutrition < NUTRITION_LEVEL_WELL_FED) owner.set_nutrition(min((owner.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)) @@ -57,7 +62,8 @@ is_absorbing = FALSE changeling.adjust_chemicals(10) - changeling.can_respec = TRUE + if (true_absorbtion) + changeling.can_respec = TRUE if(target.stat != DEAD) target.investigate_log("has died from being changeling absorbed.", INVESTIGATE_DEATHS) From a09e237169d8c9a8490ce732054d7b0c1ac2f414 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:27:35 +0000 Subject: [PATCH 015/142] Automatic changelog for PR #86631 [ci skip] --- html/changelogs/AutoChangeLog-pr-86631.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86631.yml diff --git a/html/changelogs/AutoChangeLog-pr-86631.yml b/html/changelogs/AutoChangeLog-pr-86631.yml new file mode 100644 index 00000000000..f41f5e29f86 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86631.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - balance: "Humans that never had a player controlling them no longer count towards changeling absorption counter" \ No newline at end of file From fd0dc6f9e996b9cfb734afe74547ee038e13664e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Il=C3=A1n=20Mori?= Date: Sat, 14 Sep 2024 17:38:24 -0300 Subject: [PATCH 016/142] Z Level Button: Redone and ReBETTER. (#86465) ## About The Pull Request Second crack at my z-level changing HUD button. I felt that my last attempt left a lot to be desired, so here I am with it again!
Images Widescreen: ![image](https://github.com/user-attachments/assets/148744b5-a748-49df-88d2-2f6b93e7c3ef) ![image](https://github.com/user-attachments/assets/d077c0ef-2bb8-4dae-ba45-d82e27828582) Non-widescreen: ![image](https://github.com/user-attachments/assets/82cc4d52-c457-48d7-8e73-edd12eb6b2bd) ![image](https://github.com/user-attachments/assets/bfa7b643-2db0-4aa8-9ca7-579b530a928e) Basic/Simple mobs: ![image](https://github.com/user-attachments/assets/e13e84cf-77e2-4ccc-b0b7-ea50bb4da9ce)
TODOs: - [x] Apply to cyborgs - [x] Apply to xenomorphs - [x] Sprites: Glass UI Style - [x] Sprites: Detective UI Style - [x] Sprites: Clockwork UI Style - [x] Sprites: Operative UI STyle I still wanted to get the PR up to both get feedback on this method and to see if I could garner a little bit of help with the spriting bit (PLEEEEASE) ## Why It's Good For The Game The current button leaves a lot to be desired, mainly: - It isn't applied to every possess-able mob - It has weird positioning and sizing that doesn't match anything else in the game - It's confusing and inconsistent to use (it straight up would not work for observers, and I had to add the option to do alt click to go down) This PR aims to fix all this, and more! - One, big, long button that matches other similar ones that already exist! - Click the up arrow to go up, click the down arrow to go down. Always. No fuzz! - Two types: Horizontal and Vertical! Choose whichever fits your needs! ## Changelog :cl: qol: The z-level button got a refresh! It's now applied to more places and it should be simpler to use. /:cl: --- code/__DEFINES/hud.dm | 13 +++--- code/_onclick/hud/alien.dm | 9 +++-- code/_onclick/hud/alien_larva.dm | 9 +++-- code/_onclick/hud/generic_dextrous.dm | 4 ++ code/_onclick/hud/ghost.dm | 8 ++-- code/_onclick/hud/hud.dm | 2 + code/_onclick/hud/human.dm | 9 +++-- code/_onclick/hud/living.dm | 4 ++ code/_onclick/hud/robot.dm | 10 ++--- code/_onclick/hud/screen_objects.dm | 55 +++++++++++++------------- icons/hud/screen_alien.dmi | Bin 19868 -> 20119 bytes icons/hud/screen_clockwork.dmi | Bin 16431 -> 22092 bytes icons/hud/screen_cyborg.dmi | Bin 27032 -> 27428 bytes icons/hud/screen_detective.dmi | Bin 9283 -> 10127 bytes icons/hud/screen_glass.dmi | Bin 14418 -> 16080 bytes icons/hud/screen_midnight.dmi | Bin 28804 -> 31957 bytes icons/hud/screen_operative.dmi | Bin 10181 -> 12712 bytes icons/hud/screen_plasmafire.dmi | Bin 31524 -> 33813 bytes icons/hud/screen_retro.dmi | Bin 13366 -> 14952 bytes icons/hud/screen_slimecore.dmi | Bin 28656 -> 31826 bytes icons/hud/screen_trasenknox.dmi | Bin 9629 -> 11075 bytes 21 files changed, 69 insertions(+), 54 deletions(-) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index e762b406d1e..3c465890024 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -77,7 +77,7 @@ #define ui_building "EAST-4:22,SOUTH:21" #define ui_language_menu "EAST-4:6,SOUTH:21" #define ui_navigate_menu "EAST-4:22,SOUTH:5" -#define ui_floor_menu "EAST-4:14,SOUTH:37" +#define ui_floor_changer "EAST-3:24, SOUTH+1:3" //Upper left (action buttons) #define ui_action_palette "WEST+0:23,NORTH-1:5" @@ -110,6 +110,9 @@ #define ui_living_pull "EAST-1:28,CENTER-3:15" #define ui_living_healthdoll "EAST-1:28,CENTER-1:15" +//Humans +#define ui_human_floor_changer "EAST-4:22, SOUTH+1:7" + //Drones #define ui_drone_drop "CENTER+1:18,SOUTH:5" #define ui_drone_pull "CENTER+1.5:2,SOUTH:5" @@ -132,7 +135,7 @@ #define ui_borg_alerts "CENTER+4:21,SOUTH:5" #define ui_borg_language_menu "CENTER+4:19,SOUTH+1:6" #define ui_borg_navigate_menu "CENTER+4:19,SOUTH+1:6" -#define ui_borg_floor_menu "CENTER+4:-13,SOUTH+1:6" +#define ui_borg_floor_changer "EAST-1:28,SOUTH+1:39" //Aliens #define ui_alien_health "EAST,CENTER-1:15" @@ -141,7 +144,6 @@ #define ui_alien_storage_r "CENTER+1:18,SOUTH:5" #define ui_alien_language_menu "EAST-4:20,SOUTH:5" #define ui_alien_navigate_menu "EAST-4:20,SOUTH:5" -#define ui_alien_floor_menu "EAST-4:-12,SOUTH:5" //AI #define ui_ai_core "BOTTOM:6,RIGHT-4" @@ -150,7 +152,6 @@ #define ui_ai_state_laws "BOTTOM:6,RIGHT-1" #define ui_ai_mod_int "BOTTOM:6,RIGHT" #define ui_ai_language_menu "BOTTOM+1:8,RIGHT-1:30" -#define ui_ai_floor_menu "BOTTOM+1:8,RIGHT-1:14" #define ui_ai_crew_monitor "BOTTOM:6,CENTER-1" #define ui_ai_crew_manifest "BOTTOM:6,CENTER" @@ -192,8 +193,8 @@ #define ui_ghost_teleport "SOUTH:6,CENTER:24" #define ui_ghost_pai "SOUTH: 6, CENTER+1:24" #define ui_ghost_minigames "SOUTH: 6, CENTER+2:24" -#define ui_ghost_language_menu "SOUTH: 22, CENTER+3:8" -#define ui_ghost_floor_menu "SOUTH: 6, CENTER+3:8" +#define ui_ghost_language_menu "SOUTH: 22, CENTER+3:22" +#define ui_ghost_floor_changer "SOUTH: 6, CENTER+3:23" //Blobbernauts #define ui_blobbernaut_overmind_health "EAST-1:28,CENTER+0:19" diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 476140acb1e..b9a0e3bf655 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -59,14 +59,15 @@ H.leap_icon.screen_loc = ui_alien_storage_r static_inventory += H.leap_icon + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = ui_style + floor_change.screen_loc = ui_above_intent + static_inventory += floor_change + using = new/atom/movable/screen/language_menu(null, src) using.screen_loc = ui_alien_language_menu static_inventory += using - using = new /atom/movable/screen/floor_menu(null, src) - using.screen_loc = ui_alien_floor_menu - static_inventory += using - using = new /atom/movable/screen/navigate(null, src) using.screen_loc = ui_alien_navigate_menu static_inventory += using diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 77d135ce2c6..bb2b9fcb14a 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -10,6 +10,11 @@ action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = ui_style + floor_change.screen_loc = ui_above_intent + static_inventory += floor_change + healths = new /atom/movable/screen/healths/alien(null, src) infodisplay += healths @@ -32,10 +37,6 @@ using.screen_loc = ui_alien_language_menu static_inventory += using - using = new /atom/movable/screen/floor_menu(null, src) - using.screen_loc = ui_alien_floor_menu - static_inventory += using - using = new /atom/movable/screen/navigate(null, src) using.screen_loc = ui_alien_navigate_menu static_inventory += using diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index aac5a2b75cc..4048fd91b16 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -33,6 +33,10 @@ action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = 'icons/hud/screen_midnight.dmi' + static_inventory += floor_change + zone_select = new /atom/movable/screen/zone_sel(null, src) zone_select.icon = ui_style diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index e20c1ede2f6..9f90076a3ac 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -91,10 +91,10 @@ using.icon = ui_style static_inventory += using - using = new /atom/movable/screen/floor_menu(null, src) - using.screen_loc = ui_ghost_floor_menu - using.icon = ui_style - static_inventory += using + floor_change = new /atom/movable/screen/floor_changer/vertical(null, src) + floor_change.icon = ui_style + floor_change.screen_loc = ui_ghost_floor_changer + static_inventory += floor_change /datum/hud/ghost/show_hud(version = 0, mob/viewmob) // don't show this HUD if observing; show the HUD of the observee diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 9dc95df3f6d..aea12726038 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -64,6 +64,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( var/atom/movable/screen/rest_icon var/atom/movable/screen/throw_icon var/atom/movable/screen/module_store_icon + var/atom/movable/screen/floor_change var/list/static_inventory = list() //the screen objects which are static var/list/toggleable_inventory = list() //the screen objects which can be hidden @@ -253,6 +254,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( zone_select = null pull_icon = null rest_icon = null + floor_change = null hand_slots.Cut() QDEL_LIST(toggleable_inventory) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 8c7c9fe05b4..a6670156443 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -70,15 +70,16 @@ using.icon = ui_style static_inventory += using - using = new /atom/movable/screen/floor_menu(null, src) - using.icon = ui_style - static_inventory += using - action_intent = new /atom/movable/screen/combattoggle/flashy(null, src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = ui_style + floor_change.screen_loc = ui_human_floor_changer + static_inventory += floor_change + using = new /atom/movable/screen/mov_intent(null, src) using.icon = ui_style diff --git a/code/_onclick/hud/living.dm b/code/_onclick/hud/living.dm index 70084b1ecd9..d70d2f7d55d 100644 --- a/code/_onclick/hud/living.dm +++ b/code/_onclick/hud/living.dm @@ -15,6 +15,10 @@ action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = 'icons/hud/screen_midnight.dmi' + static_inventory += floor_change + combo_display = new /atom/movable/screen/combo(null, src) infodisplay += combo_display diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index b6ca3a1889f..5e165f1cc70 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -87,11 +87,6 @@ using.screen_loc = ui_borg_navigate_menu static_inventory += using -// Z-level floor change - using = new /atom/movable/screen/floor_menu(null, src) - using.screen_loc = ui_borg_floor_menu - static_inventory += using - //Radio using = new /atom/movable/screen/robot/radio(null, src) using.screen_loc = ui_borg_radio @@ -149,6 +144,11 @@ action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent + floor_change = new /atom/movable/screen/floor_changer(null, src) + floor_change.icon = ui_style + floor_change.screen_loc = ui_borg_floor_changer + static_inventory += floor_change + //Health healths = new /atom/movable/screen/healths/robot(null, src) infodisplay += healths diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 171ba9dd114..5d88112d124 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -160,33 +160,6 @@ /atom/movable/screen/language_menu/Click() usr.get_language_holder().open_language_menu(usr) -/atom/movable/screen/floor_menu - name = "change floor" - icon = 'icons/hud/screen_midnight.dmi' - icon_state = "floor_change" - screen_loc = ui_floor_menu - -/atom/movable/screen/floor_menu/Initialize(mapload) - . = ..() - register_context() - -/atom/movable/screen/floor_menu/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - - context[SCREENTIP_CONTEXT_LMB] = "Go up a floor" - context[SCREENTIP_CONTEXT_RMB] = "Go down a floor" - return CONTEXTUAL_SCREENTIP_SET - -/atom/movable/screen/floor_menu/Click(location,control,params) - var/list/modifiers = params2list(params) - - if(LAZYACCESS(modifiers, RIGHT_CLICK) || LAZYACCESS(modifiers, ALT_CLICK)) - usr.down() - return - - usr.up() - return - /atom/movable/screen/inventory /// The identifier for the slot. It has nothing to do with ID cards. var/slot_id @@ -380,6 +353,34 @@ icon = 'icons/hud/screen_cyborg.dmi' screen_loc = ui_borg_intents +/atom/movable/screen/floor_changer + name = "change floor" + icon = 'icons/hud/screen_midnight.dmi' + icon_state = "floor_change" + screen_loc = ui_floor_changer + var/vertical = FALSE + +/atom/movable/screen/floor_changer/Click(location,control,params) + var/list/modifiers = params2list(params) + + var/mouse_position + + if(vertical) + mouse_position = text2num(LAZYACCESS(modifiers, ICON_Y)) + else + mouse_position = text2num(LAZYACCESS(modifiers, ICON_X)) + + if(mouse_position > 16) + usr.up() + return + + usr.down() + return + +/atom/movable/screen/floor_changer/vertical + icon_state = "floor_change_v" + vertical = TRUE + /atom/movable/screen/spacesuit name = "Space suit cell status" icon_state = "spacesuit_0" diff --git a/icons/hud/screen_alien.dmi b/icons/hud/screen_alien.dmi index 21d7cde0b0383d4bc6ebff28c04f0749372801a0..5f3806dc7bb578a0b3a07bddb74ba144c991f217 100644 GIT binary patch literal 20119 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 literal 19868 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 xawtW*e82zz literal 16431 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 WBq|=F(%`>eL8{7{H_8>wL;ni^FVVsP literal 27032 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 literal 9283 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 D_9{Tw diff --git a/icons/hud/screen_glass.dmi b/icons/hud/screen_glass.dmi index 6b6d9d515c5f0d30b8dcbfa087b53bae5452a654..3cf16106cd868c4bf7dad6ae8fda68a1ef61ec82 100644 GIT binary patch literal 16080 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 literal 14418 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 diff --git a/icons/hud/screen_midnight.dmi b/icons/hud/screen_midnight.dmi index 8a6f2e1e8e06c54db7778d87a9482a194d8d882c..5de157be030f430b58061968c9b081bb9e529906 100644 GIT binary patch literal 31957 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

3-G^@33^|7q4Jo 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�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 H8hrmh<9WPJ literal 28804 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 HyZ?Uxan|*J diff --git a/icons/hud/screen_plasmafire.dmi b/icons/hud/screen_plasmafire.dmi index b0b2c7999c92d34888bb2f1a30efe5002e560abe..d8b669c96c80578d13380bed19784d742aa27b0e 100644 GIT binary patch literal 33813 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%0Da|Axjn~j3@`(yc( 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 literal 31524 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

mtK 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 literal 13366 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

j;*f4mmHrYUfcbms3@ZLB#~?7J=^(ex-hkbfK}P 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 E1H#h($ diff --git a/icons/hud/screen_slimecore.dmi b/icons/hud/screen_slimecore.dmi index 84a7abec2be5ff73f51f42fae7c46b22dc405803..a6160087ab889dd46742f8cf11763a8801945425 100644 GIT binary patch literal 31826 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

dNX+_LJ3A>W{isYofz0MhS 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 literal 28656 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

7+aQe%~Q=evB726~ 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 diff --git a/icons/hud/screen_trasenknox.dmi b/icons/hud/screen_trasenknox.dmi index 00ad01258a36a989e8d3be762c905a3a58931bb3..4e17feb5211d0a5631a924e093c0c00810c00826 100644 GIT binary patch literal 11075 zcmXAvbzDjWntsNZz0MCrf93P z(9ooVccnt^C$&ry`1$2Im{|1kyBMchg}<_uJkJ}ICp|CmAlVJ0qcM&w&-(JZ67po^ zvQN>?`0u`#&Z&jZg<(ursUt(~a}A%+z=OWm(f?FD{r&lkP)(6GWL+}>uSi%A(066i&HYjFc&_8gjcEm+kXUv3*z^x%me7*-ZXvB3JaB#IzB2IxM`@YmNga z>IE#1aH~6>G%@Gi_Vr*)fG{9U%ZAjL&qyYXaBV{FOZYIn-AmjkUH>T^&D&QIoh8~+ ze8LyUDOztjO&e`MCOv*mf2o2@nyAu{`9BYyoVa22a+%AJh^$MM(GoTo(p}b*5t}8O zlbW4XqgYoI&(;KTB(CAp^u`j)YXGdN0Q%&RB(P!rLOrff&a8?GP;5!wa9(E1aV90u z{>u`zg;Q>6YF+)m5ky|9CDj@N|MgWJwjWkC87*qk1yrAUJ})RSao@}24ZuF$eN zibgBWn8elcch|M|s(qmZ6K?-R<~Gk8i7;D=%yY&i7UZ#eqj@f3Vsqy;W){JRGeEYl zquz^1bDW)?)mTWUPMVaDvbC#Drll%QB%TLt;*XtZ;kD`+A1y%YE@cLMKi1!=ILC<# z91K4*O~V`?qAU&KkIZ@rpuL$BO*}OSvd(S(GE~udm~R@c&%)rJ7Ln$;Ul{+s zZwD(PPYd=WuWZuVU;g^-8XYirDNL-}HmHfvnr`KI5;r*3&A8|Pr!`yYi7P+3uy|=& zz_mlqt%dUk_l0Zt@z@#UpPq>q|LDM9=d9RxM4oJaC~C`=*k&xW0i6BT*k}Wo)ejvR zp(J`b7fFKeu93$53yQ;KdDg4#1X)6W90%3J?KUs2(;jvoQQ8RsvaHL==U- zwMAJ-Bz24&U*~i6={KZ@qRHK0{;q)tg#gR0qfP^R;E(ZZ)RMThbGH2OS%@fhgtW1wjUSKH)GH$En7m!B&8t<#5s0>E#lk3%A6p+UKst^4his`|VVtF8 zkjaNESw_O5bcMX)L@i5gg8;>->&zbv{T zXyMOivcsSV7C(uap3g2_afCr$7Tlrc32=^kGUi%ZueNgH4vzM}xfV*-5ee5`X>?JR z8j@%i$ZY)n_aIy_|Am;-f?za)ej35cw9NsOP6+x0}`a@@$T=f;;vsU*2%Fvvs`wip97w%Wp#* z$X?3WWD#W34~di2z_wY0ieWh6fnvKNm8d&op61Nmj=@7mS67hWFyDuv9fS6Mo(d=^ zbxSwk$AvR7B*TdZCTJO}O4xY+a8{&ZBH^@Zao!8E(vH$#aS53H8L=u1`_Nf{`eb#e2}3LhzeX0UFC zpLY2-zX{~2y_gf1Da%;VM>#FczigXhAe1gQ`eZ!fSrVgo;6G5s zH6Y19t-Lv|k1#)>=-Vf@p%Uj;=*rSNKo+^!N3NK0QYvGGmn+(?rz1e%v7L9!tICm(A>T#`hy6Ol^N zrS)4_lR|*IPHlAq;d#Yhh0y^7DBGEuqMWd-Im?nEC%~9Y%-CD0JQAu1Y8QXlzEh88 zM6#vo9pq8>C#*N_dB&*M5v<$|b2CKNnWk*Kg2REV6=j(A&VylFhvx#)e&f#%owS_> z%Xfz=`ydH8M@tDZ{rc24Jhw@5hFaPrr&b+9201x}aizEp{L*bIA$F7&7r=s>5B!$@ z-n4IPT&3?ni*0m~_uus5+?Z;)L{npYO3#rP4FJbV?fsdg(0w(u6 zqEHVba#2U=E%rP^vYP8a{uqpMhjO#co_w7ay)eNXdsS%d)0#J2u@9I<+s(Oq#Ygc1 z`zmEzD^!7$VI>;j7PEZ9hO(0KV5Kh$@lHu=UWwr0jWLcamaOz-MSJEX`YbGzUnPl9 zZud|}G`Xk?alHoDN^iBG{3Dx1u0WT>J4x&I2KS2H$nix7!ZWKj{ceHNKRqBX3j_T@ z-ZJOnqnt&2EevTG78M_tTTD4AU#&}%b5R-=MsTHw?l!w(A_XsSm-kdz=l*T}-4YSX zC7Cly!({%DRKyy^AfM8sBB}9V$W@etN6d493sUN8LQS3g1%vUkrwy}tv}k(xL1z@u z1n^oa5ZKN6OgEK9%guoT>ytXIgIOm#7igH$4Dv=IF8*XSL{TzLU58dX*IGW$VUNKB zn!hY5N*dn%@ok|ZvvUs%pBLOAij7L%jLXc4BrN^cBxG0Pq2A8WAI(@Ij@JNF@{X}| z!cEl7I?L%vv~73#=+oo{X$Ns|{f-HePUZJ0jH zyGq%_NkT1#3e6^=z>Cs=vyd`d6My*c8TUtE40;l0&fp)$zOR~}^Pbl%Q}9rm1t`&s zvD5f=Tb@-jcoiyaVXezDMlo>2ld4fF8m%y}so>ZrVK~R~Bz9*<%~6ab7EeM_DlFyz zEt)yKoxJ&1q@+jGKj- zQo}8I+#@H<3ekhs#vZ<_r-_;3ijj$fBmUOPL|s2bF(Z#u)2?Tu&GlWc|I8RRPp&Gu zs{vo?!y^XB{?t8MD2G*)O)_p!CmG5mY4P{xgR(-%dcIH_4bgj^beQa%&f5=fTRYJ) zXMB)Kxwvmp47S=eZUgF$pAo)z@ghk?ycw^FxdH+k_F#bts){0(Ivx$!f$JN~$FK>I z(Ocv}m$jtn;493y)Ki4jrNT&)GuUM0=-JiikF41A0gm@s`g%W{Di?jWEFjO;qR4G6 zN0snyg+1*!ji3Eh7n)`4!+wKRzF>5CoD41hm%VVodyjhvMOm>|s?E zjFF|M*zIAG)q66&(^6sF22Wo_POPb#Uko|sL+^asM-ZdKzpoc`i+&N@af+NjaQfa( z_L^e#$13>|7i}Y}4|GN8Js#pq_{=N|hzC}WP46B=V1}qX@hz;=+mGo0t|ueGZ&*Dz z(~}r>IqX)J9$Fw>r~&*spF{Onu&fSkb${aHK-2f`*tGMKuKRjR5Wyz_ar8-0r-R~D zwz?C5X&1oB$(W-M3Gn{4at=(6;IN;&GE>uG*ncDY80v?0GJ5;VkwEgMt@keOImn6G z<*n|s#K=@(%Cg^~^2ZEWH;dz!SFxi1I9Tby8FSi!{V9dF4v{51?H-$JQ;MKVIqsZ8 zj}>Tw2;F*{=%CkDos01zs#8bh_Un5ud?vhV%vCeD8Ez2f!^sq^kRScZ*ZQlK&zOC8 ziA19(pXxVh%OWl)PmiOj_CvYVG~l{Y4pKXGd^-1G_^*s|00+yb1=G0m2bmL7r>)sn z7`j6KIbv+aI;wPI zUb55Q{*IWOvV`GoJ)&`IZKhSD9y-hK7r<;a+2AEHct@Yeg zGCmqmq-*=6VyC<1hpAAlA0VVupni)oZqP+cpL0lI4lnM?t6-u7>I-KGh6WQZK@NmQ zns)eQ5byf?oK6C7r9gN7){~MTE`+7*B48ltkEL>lyLTi1Fj>oN44`wT>a6Kx`ZPU% z(YM`a$=O&(hdM{1`C*Sz#eHOKcD_(TRXD;IpdRd~6g#T9yf_msDe35>I$4dR2it1I zU_{eoenqF`AC7!8o5|KZF79mT?lDo{pKfP+isWX}=8qe7EvFqWEw)gy`-Z_mfSN}*DI1LPuOO{aar;4Wrq!`;& zSePOj4gmf%22^tx61Ue4_WHfdHb?Iy*!P5>MUAFxrtTR>sn287ZRxKsh(to3cKo&_ zd`fE?bh^Ze_h(H*$P$|$osDUW&y3AgjA5njj(<`cs3tQ~9r$tHL#&ntdA{uND`^y! zTx^WaC$ki9ebHP-q|yoJ zAn%qBaFtU~sECl_5Lpw>L7Js>Wea06Wt8GKti9|)q zR)(SbtzZ1!UW0BB|O7(1c=h(+blM752O6EnZLyBF7{uDS=iYM_LA4|1N!qix9=uaL0l6ho7%}I zsQg!N1XFB9dVCV>PIW0!jkBI<4Y6`vO^$PL)kUnfc9t~7tqlO1znYBT9%Gz)l0CwY z41->j6v@+E#q$o+m&xF7`*G79p1{>pX*KAQw7m`QUCS?$XXvLXYKLP%IH@ZDPtjK> ztW^NT@LJwzhSiLh^W{~%`61K(_?5r|xyg5RWaX z8ZTGm#CTvd05CgCn;k|g+KH!zY8f6TM0qlhcI>o8vx z5pS_Y(5o8ABPv8)7;IFb*1ss?!tQWa#s4b+^R}M1p(M|J>yLSl)4CN)<06QT@=bIb zOf(QRJ|Rc!N1pJKqSx%Ak(GXeB0nHt!edTc=OLgg_vbX9VheD_&*;NNaDwU;YB{v2 z^JxM`yD(s0UKHI@5L9q^eWToInr8oSm6>7~C^6X+rb?5y(jRv9JTytJ$TX7-{BAR0 zMaq2{MMF@8t9o{L^Y3m43bxseGH9=`)OvXCo=v*VgS-xLFPDU(Q3^ch@ZI-d`_nho z|Cxj}KLsN5CWr(`9Q&P&GmKM-tT%XP5%sGEscDGwwz6{?p#{zu0BT5*QkrWfDXqrF zAQIGnSjLm_L)dQyD!>VRycRVj^1%$a(LV@-9%ikXqhU?3lHgF ztr@X!jweaP`8i_uZ;qOI5xeEe&)5yE0n(ubY=Fa^ei;@b4?ep8-oToCS!Iz#Wu)x> zD5KoO&&`+GcdRs9JBa73zh@$)Gt}P(N-ri;`v=0B$~$o-e~F{8X$yP(ciIo*Eu$qX zv8BrFw5E!dcU1JgakF=pBj}c|;MV$897nHly1ulVIk|3D6W@iH#qJGb?&iS_;|I*u zp+3Ia;MZ_2Xz6B(v*iZmkh%KlnoO?QOj%rS7-fSlN-f^*P0<@k?x}2S-W~0E004w^ zOQch!J*EI-BoNU`sQ3=KqMyai**w-oF8ji7_6vpKvdb&_o7y455I>^iOEZWF+)^-9 zkDam7KLYpJ(@A1~?VYmA_-KLCwZxwCo!No7LrVO>pKp6M+J-z-p}}DUM-gJGUx<1R zO{9|_M4Ln1u+RqKB!jvL#+L%6d{Fws;8nQPw)yc&%jxB!MCYO-^0|(l!R1k#q1PX6 zU(eL{yBEp8(bwJ`zmS;xKb#mLPv-4AZe zQ1g!_46?w)3|Rjy$7yA9{=wH%U$!Vk$iK+2J5Kv^Be9w`GSH#O2Kr2T{ApGU(MY`>2S|9u)6IDCCB6KDDblU}sy>Lw6)g^u08bEe@R#GF9# zXal$Z7><7YTeD&F{5iw*hKB!qjASv5)8+Kvt%|@5T_rx)Q{bDHgVynn; zaNxniP^C%AnKn@Z_;otZ9V0snK%eGdTRsEKU~&F~HMx}A($@FW3AL0X#oY>eeO#Jq-0 zqo-s~1Nicr8A|?T3_$} zi@uaX^~%xQnReMP7^q-Zoyz83^>a*=6~5S3udK3sIf4vrOX+(jb|_{5iU^K7lI29; zP)M=+h-O)Rz?95r*E3HfzSgrcD2}s1tFuq8pazcf9=3J)h=vxFVRn$~31X#22Nd6_ zU#P5c1`d>k(1-s*> z^x&d59QXjfdpQ-Qbu%{#l*LMx4e$o?>U<40K{LfW@r+b9wfdT-Z{#&P#MR=fDrDpj z%@PJ!e~8+lVs4$?`Wk;Y7<+J+X9<}3LQ%JPx$*JuulW#tjpU&GjRuI{es%i~KHE}f zIfoUv*u3WvvNdD(&K!AP)-*894-k<4iN&RsL-Ue}uSalZgErX+2mUkZJ$z%cv|{9= zxE#eZbV=QE1hcXtCwHkQX@d|nfRKxUt6^`UyvN2GrAw^dUAtQG0M^~_pfApValA@q z289W_Bl%MGCcyWwKEg>Zp~pslL6^60u65Z@JNqGf3!|h3Xsew#0i(15Z!qVpR$GIZ zFLC(`@)+YYdip*jHagRsi`gc4(PXWkyx)?dy@N?~>`C~LVIlXQt01eXwy?}>0Ln}~ zYP%n*hgv2$FRabfQj;J=$v%(AK!<)yZ_>V3&PqaqHC-k{O;BG;0G%y~VcZH`O`(gt zz5W-8g-v$Lrc24SFD_i;U6z4cw@RY4(0!ACQv_}sBu8C~hZ;@w_`~$WeHfB_=hG;* z1$=5x2+xi=X3L>unVai!;SV#Hlmmq{F{NF+^6VuUsm6o-S5QEFcjC{qd)tf$^VhQ3 zJN;;6IHfr1G3NPV{0Z-5l#?H7E+rU3Id3c(cf`*7Kkk^m!f|lb zRdLhVojWBI5WTGyiU>3V@;6%=1Jg0nQzl!YDW*S`xgEs1TDRDF^gXCN{i&;Dqze=% zAS=>??9ALad&n`d8}mE(CP;`2>2i3oP;>0aqF5&3~Q_qIteJk8i4M@b0 z_BEv9vcMvV!IWC5o|&kjn9bw_rN5XzzS8z}HH5#d-z+nmDqH`X&V@)AV1H7_1N##0 ztuOkg8|$jR9mcM_I>7)mbnG<7X*V_ClAME|mQE1DjPa8|PBs;S?WVbRt;?K-D!wRi z9*!n|<~w2iq9MgJ`cWaOHsWd>@FSn1f_#pRL>C|`wrT&5N$TeY#ih<^CeR zAm7=>KN3JZJiP0b1CWQ`;<(d{4{OlaS9cVtwl3PDV7=E@ph<4PhP^yA^3Q$-b9}_o zZ%%zT%hmK=(le|i`_3|aegp*vDKn?n8!&m-FG*VN(3uIxh$HyzJLQHA+B-;_A`LEp!vCYPsRi3j`)|9kwz!J1eHdX9xFpttZL z`6~|Q7zE`G;AGws<+!~ZR^Acyrv=2We0v>mbTW>-SP#u$P#r}!=a3|rV#p&9UGy~` zH~%!jRQR9mX@)@DF_>RW#qd_`cHfLiW$blxL^DTNgAJoYCrv``D8KE67vn?ez5D$kv2Z)T@LVQi3ZvS3fhHNjUqV0c zn9HTjeF_=*POV#J)!bTs*hjdTgeM)&+cW!>)!CE3s6(c3isAqM#VmSi>14zEtgkU* z@Kc7Qo4Mf6bO>clf{`6X_=%MtH2{F4_;?pUFeH~$a2tKM$GBEufmbB^nTdm{025GB zlMpRiL=dYgRI<0!=leuK%b_$TEsTeQB{z^>uAfdtsEPHcCevTBb5$MHk3N{Z zB&ZR@z)49(o*y_``7B4xOmC_GoyH(~O$Do%Vlz+<9v;rw@bL3S=R2nA0vW!c6ajnq zp@Nb?_9yY%WM(*i7;qN;{kMY z!9H|UCaNZgCB3COX?OBmZo6!ttW2f8Mtw<1Q`NgR7Z}Bm(OQ##*8pl{65|^?;y(Jb zfhB3t(+OiPg3jcm8m)bwvh+Ll z`MjRk+3u{YFzNl;;LfH1^KrtfUvg%-1ld-X)l!b}h-gjga9;DS8BvDVdSo80?8^=- zqh$jCn#v&x6(Zr1Q(f?cRXw!+2tonByG1vj? zCO3U5YGzw&HlcPA2l#@|3X!eo{;ev8$td+Hj(cn=%%;U2bioR+m*|{Mp`J7Av>jf& zWT3tIwn}=vI-c^{4Y|i#Q|)5+f&*bKQhDUYzw4bwQci94+V7hFE6brY3nPIGkD-7S zdCu;i>3N+O%2LERJ{2)uLHo_OVQgt5NP)1V_7-J~)!N8rSk+E;| z95qitR<4z!F%3)3<^$MICGOcCqv7wV9uh-7>B(ab%hdenTI=cXqqBl06oe!M6vx8y z{gzP(63-Ypz%(H?|8BrW$P7Rtxl&)(^v95RwJ%<_Q)ADu#l6RtR=o~9r5x~CVK%FL zvl+ERCtZH$YWP>*Aj`^hf4Kv{ZSCB8&tvbF>+)eTRX6oPi$Y7?We1|;PzT>{0f`*1 zr>Q5SpQzPs{Fk(geZnZiE)}PBx*{xvEy`@dP~9{ zl!hzG&%($BvUN3uS4bSuD%oK4B#8d{z|J&uq9HiC9mMDrGR&oTf^Qf;5-@Vf?<3&53q4hE;HvT8sS!6#TEIwn|(8GL2Q86JM5TQ*?F z7mAJbW5<;jcRasCiZ$SS942O_Y>6n6cBXWq4^8wI@<($Ky2r1)pJYoIto`eq*{l`d zQL>V&vQ%tfG?|krw0I`)UGJm`d!Z%l zXoB%Yi(RUqh+Oi6iOl5-5voTzc%A9sqnq096FU|F=YJXUU7=Qt-ko7 zLpg?WHTZa4kJ+_mUs)NV2CcfFSZlio!oEZfB5%ERyeTYyJ{AsIL|EWVWXM^43|3D&lifiRF%&a!WD3P{jXx{>xFw!Q|!B0qrNacbl!H* z%5!C(EEwO%2P!>1Jtqpt{qb1qeMx9&sH)Mh2UGe6zql{)0Q}w<8qAz8_WxP{fYIIF z+jsGA7f}EMl%mK>cOX1;Ufygm;$aB_>6ZXHP^a9K1maFm?as$z^`9c}-HK#cV7+C_ zhYTU#n+xHLchyELKJ0+nGmNdgB~l#{uE%5S=+hm1rBp6#)p;=W_jM#!(k&F)HTEZeSmXDU6SC5d2B?-m+&YY4 zhb%tHcKql^?65in|Kl8fyori}pTxe`<UDXQwlW4-}Ltp)1sdtskq55lc&Kde?~3;8-0ExlqJyWH9e+tZw}gX*0a;xe z$uQc-V)S&Tz2T6@oWJFK$ZnLPTfu(T@hE9ECV&dn(fLyg3{gb9h)7lcM$i{O1cOmg z4&+1-050merVc2YYQ65N#=|05ihBKZ1$|sUyU;YJS7$fX55GgxTZcM^u?o{PrWodV z8fs3t`_}rc;3K;u*+5OBdw1)^!g(NTsmxuJ3jBoGBVB*|& z_t3{7-P>Rc;5>0{huSgRSE5>N=hcK2CJLdUYF-@t^1%%q6xH7zcO@?kikGR|!qA7- zu3Swo3nY!;6r8oH?`&p*hbYo2&>5!)euwHl5Lmi@D9JLu%Cs1f+my>Ll!k^C<^{B( gY)TdC>I9Mjh-CD!tCKE&yd$e1qat1L;ZxB607N_F1^@s6 literal 9629 zcmZvBc|26_8}@x>BYU!yZ6rmq6h)SqL1kY;DYBHxmI#%7j-|8+St5x^gm0n6o@GQ) zgzQn7ipY|kk!9Zbet+-h{p+1SW}dm9bMEK!Ea$qf>pC~BEDU+Mws8Rfud&e~YXF4Z z1O_L8{XMByVZ{!-2(~>DaOj-BtDlE&fQQdTfI#Hoy?ToVRi5kZ6E?QKhCCI1dc;P= zNoLNve3R+VA324MT}ee3I1-*WDHV{K>Ldq$pIe_K7AP zlzvV;Q|;^WDr-17TCLyAQFK@~W^ePh+d2(tp^3$=dg4#?VndKuuIap`QwIZV>knV7 zJ)X2%fP6%yDdoIa>v5eK^y}F3!n}LGtU91 zor9FdcUm`YZM|#Sef~;*$Nd-5`dcT@T#utE2#*V!2mP?&zvXmGb;aUwgLPfhv++1# zVOd4p2%Se~EF7K)wC3k8rCe~oH`pooKE88#!e!5Hzo5vQvM=AO<7|a~`lvZMQTI~G zlUI_}7Fn|u_L;xctrDA7j-I*ybb9#lLDR3F#w<^#E_Mz6{C;(uyNg`UUvi7$;K0NktlUsdB4CO^#dLr zT|(-mo82EQ$Q2Y6MjyI$UF7ByUYgz+B*pqrbb9BAC9=en*V59#wckyqdhE>{d3UaPxXA;=Z_jruUXBqacQO9kK=U@XpdIkE~Br0 zTQU#Zf0;GmL2WsgdP-FzeE9Ai?wK*yd3`i^K!bBZSc_%5UR=J8hhKOPTTWFHRZh60 zg@mVY3%;hQ9bWDJCG@{;hQZVGoCDeacKTfJA#Jj6as6lM)1UutR+>KOHM;StEx2i| zVNv7jw;Xugrt9y74qjaCT=TbFty^ufD_m&s#7FebrM+CQTYsgvbBbCsB@SZXnRvo8 zXa+LU!?2X9^}=0JH48yQVf==J8gK!Kjhln6d39PupB3%dE^ws82X2(dhX*qE?^5!n z{`gVMp+|=V#tp0A)o=ED?0N%M1Q5JoP#j(@QM0bnOIkFTQQO_WG46jc?d$Txu==IP zKvB#*UQt$Ki)UH{J~L?4+J0QC*w=jErYa00l-F~oRVC_{FBQ+v`!y0=eh1%p(Y~Ir zsu?~VMG*w1Z~_54^e2j9hIhAfD*3re>f7v*8{>4&Lg(znB!@;;o!@pI_zk{}EBXBI zoDf&c^CP;^1AS`(k8TX=6BBUgW2ycTp5Q9o>y$@85oc!BM(T2ER&yEEms>!^_up>+ zXntFXk*vB0Gmb01Sqc8q6V%cP84i%RRpB^acNQvQo5b4i(61+MJ<~O9iUq~bJ*~Jw z;&XlzJiR8>=jo5YUCuRErx2PWeg%J84WWxtX=x{7G3XV1PK3NSKQBFv3uQGzgUfK1 zD~nRAxxaY4cDOTiBC6|au@X;_z_ocw?f7Is+8U5`V5VJQB78xOm;86zO= z?14Zbx1hi1p~SP~g+I3gE_VUL3(s7$d_B?7qJM4F;U8JPYxa)tEIu1LxQGbtofvw4 zXk;w63ThD}kKvvkNn<=*{W|~&_E6i)f2%w)|BM630=jzO+M|H)U3BARC0)+u;tk){ zw^d+|Xo7x}3I~k2r0b_sA3?%JZI5#8T!$P^u+OxGju&yqm7pZbPDpF!pHiGA&f_+I zV^rO{$bEk-(ro0PJEs`9PvadiYPKziVUENv;&Oj z#GR)*rgy|>{z_JR*#u)t9TDx;kPy9Uj3jcwK-~y&*ed1kdcR6<==SqG6zna<<{*ig z_S~JATpaZP%y>p~D0x4{LqM=`qJJ`h^5K{U2c(;S+x~_{bs6Nl0EV(BhQC)y@hou>Q?o8m9XM4Wdy2;#-gYva2}fy zL5ES9u(}h_K{3HYVNxe>)~p`&6HpD{p;)_fQ(i}QYCWs_(%qtz_XOHXbg8 zDX{v0Ch5~k3=QC>=ccQ@2>pt7FyayVm=YA6G%N0|zGzYcIsQfUX^J^`%7kUr56`QH z*6ma?xMzKHFWSv$$H4Tw701tAb??mfIGgSm9xmPjISi9yJW!(e=*l^MUH(db?Cd=# z!7#?9)!^YzY7JQJVBF?UKeF{@uf(4pl_L3plg z9ZB8_UyvLlau}<*cPMpdYxz$|t>~-6joH%;?FX{_mMAcR{`2aDFd0nIS^ip?{<;Uf_k;FWHo;H4c zaclTHIZ7D1vE*$|XU2TD#tv;l(}zG zP@A%$?2)}MS&L<44*1${vgQ)^j&;(UzRjJGWv3E&d%aR~GNtb@8Vc?}L;}cZU{6X7qeYuQ3 z>U8Ormqu?EH^0!)y)bA-k)YIA(mn~NI>5Ojhp7kS)P30GW=J?+u6Zb z^Q<{VDmwI7Zg=If{NFFN+;DKzt|eaP^8w)D0}q7*e{E0PjL{43qnd;J)6qsC?i|TL zTzDmYZK0x5Z4nv7~2vOBJMKhZr{QN4Ec_nkaK_wr16| zQ=iRu$u%(deJ{GaA_vh$nnL?5lCWsUC1OF3(Uuk=EamBBzRXQA*QEVV4!m_877zV^ zz-9U1Ga3_#CtlQB&Mz1n8+br8(CwNY{Zuc28(TRNLsO&;4uJi6!^M%&2OrPt1+7>k z0#!S-QqI?@L*Q18iR?7?iPLMJCv?0$x*r(Sj%ylvCE>H%^Y3)c_@`pf{!7HZ?EQy< z!F3~fvU)Et4sHs%lF^}aP44dxWsfBaLT zt^0qUef!HxeiJx%+S|K{$;-HcjQNFyrj8Rg5X$dMv7)^N1R=pd5L#{Z%)*SYRxG3*S2YQGLx9F4fk1$L&5DasDqktbGb z>3Osk?}+O>jn}T=9S}6tQhO;IWYru;9c%R|`$$)L^t~ecFld03ugfJIM8{%}A;24Kr3^XAr>Z?BOso_}@>2ITH|{8i zy@s}I@^{0`)z+3+R8KU<5NOlN{4sHaiT<0KMJu9f2hs>R8G0QF5t;*-hUHLoCq>f& zJ$lC_+K(*}IUCQ_w`G|yHambWLXSEs9^iim*F+%3@JTKtUwqa1=}K+!6@FbI=tRZ& z*ZLXl2+EBs5*jIhj!>1e68V}Cc-TD(J*WgqyD|?nH$JrRBN=y`m1g`A zfoy^P&M;R<&}JOxg3gt`cc<+!bPYb+Qf`{=4MDB#C&v%i<~LMMHaXpN4693==MNnv z=BbST!|IqcGS-$zUH^zs1hB|Dv}@a8eIyKmBpGuz7XfdC>qt_tb&Az^xH`#6OLh4{Bd$$y@k zalB^zH+zB)Nac0iT?w^8Q1o6y=G^YtJ!s3$`~e;G#HXO{y?l%$MNXT)=!=Lkueo~{ zgWLt0f8UN{@3=rm@Tlc->2sBo!w+Jlw?xYT-Jid6JomjVV}Q?P0%`nu&3Ni|5xe|! zPgb^%jADq#lzOqMaF%f9A#x&7>n-CE6DO3(&)&Ll?M9(Ck)+o{*^zVp65JLUJ8zu=vc32%l44V+nY|95Ng{u zbX5iiE_nR0lMLZN8&{_%&IU(~&~!nSkxU!5;;8ZSOt zCqMYxM^#xRpoEhVb{5bg_~j*!_4OYGPp_^om(<}S&j$e{iT& z*`@7#1l9xU+{k>N0rj6rT(Vm@vlExfTKmNM=!{@AH*aczUDVaGzQVPoSzVPq-=_OF zZmqcePWfX=wwe08`n7UPhq0B7=)*gkBA9g9cBNYF=?v$zuYvQ_XVr7lVXF;_S5`|r z#sW7C+B8_CZZdO46ahVJQzmO0*bhDdI-^(#MRCB~^EIw&*&*coF6q}_S3fML;>xMa zJw{miKA>c6d~tlWT(?}3yIfgJ6os*syiwJKwHPJ`nPmYTihc$33kXb6?XiqhpS9M` zQI)K#5eOZgJ3+!Xap+_xu;qd=>Q?9k^bPuMc`w?G0GY)k5d@5Z zwhwafWE`pXItDf2_Vq$au=E@UHm~?)Gl6mG5C{ltNs z7783~vxx*W+gyK2t>^32A=j&j5V(Lo`VIrR>x3w0%=3T^SA^bPe&rHlw656^HpHEY zO&H=YmcfUE+krmI7^Y#n(}W3pHx3*L6!6>ujGr%*q&QNg4(E;5^~O?uuel*mTq2`4 z!KI(--N$k-a~!#YfaKezaGl!G&LeBC0Fhg4Z8*iS^xf>adzv^1J?UGq#8BL4Dlu9( zkZZ~Qyi^MA9sb0MrOU<`xEwd|<94E%W6eZe-nu(9mI-)biRXv9l|k}--j9e(E*QrZ zo~^HY_HA*fC0q#3tbS8M1YT1Ahye%OAcXLN*%K))HYd)Z9S2S&2L*8dieOQXuR=I9 z*&(Ww1F`vVOb`~-E;_h@*a`A$@ZPTv{7*JApQs-^&X&;ZorTE(!m}EM#(Y zJmw~P8_pKgosz}Umgi@5CoNBYf{sX)U7QBqP4^xP!`M|J7^r=WpcdEGzuzX;^h^Dn z3>h2!86RBezk5%3lLNw(o}n)IyKl7`m}e4Dl-LNEl`2FDh&6fV6nW8vo1{nngd+qn zlkEBRB8ur&`*Asp6Dmwv>zyfVh06!LxZ0^oXf8d80l9yH=GlJmJFAGf!w(75Cj)Ea z%cx3V#F`G)Y+`S)D&R2mtHLRfq>^JDFY(0p|HZ`E2ZaDwD8|aSFK1G7UmcWOy-#>P z9TfOihs1#{P>c4ltJtJCoDk^kz0ndmGpsyz>ZD-^|a{ zu-8EGeuVvwF-HAR*8!~|4N?eeO^rf(LS*Xsgbi(K(EM)H-mv_fe9oM-U+gj|n&PcD z6F(gNzlGfjY)$2r^R&Y@D<-Ro2Oj!2JdjNf_M8LN`}U+;vEwP*GTHh+ZD--P-`_{C zXb=3`R>GkNHWgg&5W!Q}C&~$AQV`{}x;bjKX|4-%LrboY?}&C3S#~#Auiwl>?}c;o9`36PjO; zIsS_sdjSdQ-xk7}Q#9GAa(k%vcB#sG%ofP1D*7|9CSBp%X9D)&fi@~DnfMtz@diOg zekbT9hHc3E-3rqRJMrMACI=kH;8;uE#SR5IP0Q8K1M6H@6|?^b;sIw5LdSI%;$@IAuG(&h zMJT-N<6pL?BtR}ZD&{fJkA1s)c*5FV!XM1!mmm|iR+4dqe_l`58rE<#KJZH?y~^CU&Ozo#=v`;9G`7L>>GbUOZ+_Ej zi(zhAlhIF~ir>7>8o0BvIHI~)DxVh&7jfY8-bJmt=Pk$EsG8LE z_hh~dOy)N=PKO3RHExH9nhVQ1SuWJyr-{MbzwSBIB~+Uzh{kGVuK&5JMEY4s3=wO> zd9KJa-*BYFd84n2q%>ZD_Hu=})9Qm+tKhiqmP^UE85md~?f6jI z=-V7VKw2Q>AT9%*l_I!XMVt1P4}N0%vbXPXmLKGx$B-7Z=XbJrEy=F}9_Tr^#ty~J zOzkp19IcGBzS#$64xu~GCqY2#p$pzwR}Jj<+%TBB1$2e$)^U5QtPm4Z!waCgV!K_< z@>$9Kz-6b}!kgc|5sQxN8oB!H28ueZ^eOoR z9(FUofs6iDAYef3NxaILZD*YoDH9lXk7QohnT)uoLPd1>qCC!hChClIj5>Q31av=w zD)R2t2cZWKT0xafNqYf8RV~G_VC)!?5SjKw0ZV7V4DZGzkDo~G|NhhA25)#WKZXEX zKEU&xz=&#yWBV3u24b1Xb6d{U(g5}YaP@%5LJa*j?gO?eq zBQm!V72bRd&kR%A8-utI0WCQQ5>OGpr2go5!YPimnVzg0f4`=rI@_zmkr&0f=;0}4 z%!?nhU8O{;Zl4(@FR<0K*3Whh@VM?`4lZv$f$ydkKE4y38-_lt^8BH&g;wX?;cK;* zx3TBz*-c)QR36tp!BPiaz+zC6Sfgb&4gz%6%=y8ntqGg04y3R@^GEAKSmqqU90`iz zJOpy)XlGOVL>39Tm94Y|OW*dD&`9SG+t#6>6!;25@e9sZ{I)w{t`tWvo~jB|V0uZA zy(8R7`YOAvc4F!2t+<@H+q+V=_fO3~wr|Br@IvR$cA*>0T6HMd3&A5pVeOJVaamZD zPr?-2z}|~6u^W6dk3yruW$+5Zu(0`TbKZ5|A6EY$z(w|qegXW zg=ZM_m+2l}gfm=V-~>W(4_^?31S8w+kTX|?q1QQ4&AX>fIEVz2QPo3J>|Lh_uXY29 z$6`EkV*bPE9NCi<(zkJD%PKkKQ(ZBWi~(CkQ`L1A+pHNjOa*lPvk>?Sj%X6sMC*cQ z7CCb(IrmSk+76IDls>`gYLv!h^}hBwDwZiJW-E?aGie^`yAC*V>H96wy={WAO_dn< zD@Wcu@QlI*LzCoZfp-qcVTj2Y4?cyr9&^q4nM&&GHCpmmFaIED=G}%+xUcbFaY>48 z=R7n!x{*6AfaxE`oK{Ool5avhRt(N9H9c>S%1$}*VrcaeGbq^ij*bu{jx~z>*5(4^ zTs~4t#(65wYGG06%FtEm$X1(7lu=*8o`TeMgi^7pVc`|C9;dEwO&#L;kCKqpcBh6f%}dS(!esC%nlT)RC-9 z;-T;ChQb#@I$nPZpR@;hX;sG<_$tNj69m3)*2QO3t3pPe0BWbR@d!}MXAulzk`!Hi z%+-089C+mn7pf9E;?M?9^rTl!Sgwxtz;+sRSQ8j@px#nOm2IwR`FZ@3A=d}I-Oh8x zRuRw~#SJYCQT+y+WTQU-PIIFwD(`kl%}xy{uGa|yW3}58$@!Lzy~g9WmCeL;e4)}F2Nl}Fex{QoLLi4_-|xoGq5%lJMvb_GjOyG`Uf3rQUg&X*P@rKy((CpD(4 zy_W8bI@vBKNzjDg+odJFS1Mlx%XU)aAru>6yLQ6h;TQIEI2N>44;`7)sgXmejXQ*a zokf9Jx^99{f=RMH?{kC1I$t_TuyGYjVb@8%I@V{&c?Na9e7P+yWbV`FC?B0paj`Fm zK0+~E^ziknZ(ml#qaDZMO)+Tks2f|D1R(Tz{&4D*j!VTSHCHe1%F+s%I%?Qzp}pLs zSkCetN(5$>Th_z%)_M*VjCiE<1)XKZ@Q$(?uNu~#U{~$GUnJ-4*i3CEK>QDP@K}wT5Q2K$%L!`MUIhO!oLDOry}lG;t0`+PmF|{ch}29?(7pk8LO7N<{S7)}kIIeePK|kx_-Ee0b9sMk4_8 z;KgX35K*agplaAY>vwE{B!{enXLWzWnKkF3P zZ+o0Vn>6=Bbld6tlyu%hTgK*=IZIE2CE)q%Knnb1JyTAA z7{JYE#@EmS&jiHv$=<%U*c~3;>}x1d zR2&#tNDHogL97wld(kxofVVpfIn6gtLw-``SK&2UsRu&e^ZND0;A34P=u?)8<6>pk z+|bO>HK0teUPqFJw(SL4y~NXm;VlGI3uxt@xmu@g??nwRvOZ)pG^YO+?sNrvmPq>A z3!v3Ku3JPX>Ft&rE9_HEHKdBaA{t%nyp_Nz$LsNcDFl8Wb*@{$?pdSiE^oQ*T?nX6 z_@!jB2oU*@phd-ExySR*|ecss}fjoXM;brl#k#oNFK_{+$$i^Y(%di9AK&?X58Pdl=V*Q)DS`gziQYvrW^ z?IPP^N)e2d=B>56I#N^QoXPJ4BaYkC!y{`ca} zqK<33ehw3%}YRl2nzkYaPGhBUi0=_{F~|JP0G}N0W3xP-+>C)x?7~^P|0UK zOcQr;U~7fWRTXwTJE;r@?Z;o8lp#v8?GN>w$J=1Mo82lAi5uW%!&LR|{p)P4!CTM^ zjKKr`+^CNl@cfvxk&KS~IWou$QE=Sfu9ju*V`I{{Q&KVK_{2#zGi_X@(Gt9cFxHtX z-C9xSXOnHZ^z2JB&;489&OaK=H^I1kDEQ3-QFy$&NtD%EzZ_dRU{4l=tLFxIcfQyL uT3+K(R+Vq`p4pPKv2nD5+$R&doJ^M8SY3^?;b~c5e~b@X94gXxiTppke=el} From f6846fdfe1c966a4f0a3ad4c6692f885ca6c299e Mon Sep 17 00:00:00 2001 From: lessthanthree <83487515+lessthnthree@users.noreply.github.com> Date: Sat, 14 Sep 2024 13:39:14 -0700 Subject: [PATCH 017/142] Fixes uniforms with no/broken sensors sending basic medical HUD data (#86612) ## About The Pull Request Checks the uniform for the presence of suit sensors entirely before caring about the mode they're set to. Uniforms spawn with a random sensor_mode regardless if they have sensors or not, so currently a piece of clothing that spawns SENSOR_COORDS will be added to the basic medical HUD even though its has_sensor var is NO_SENSORS :cl: LT3 fix: Fixed certain clothing sending suit sensor data when it shouldn't be capable /:cl: --- code/game/data_huds.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 73aabc82f19..4a236b7a47b 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -28,6 +28,8 @@ var/obj/item/clothing/under/U = H.w_uniform if(!istype(U)) return FALSE + if(U.has_sensor < HAS_SENSORS) + return FALSE if(U.sensor_mode <= SENSOR_VITALS) return FALSE return TRUE From e153ed7093bb5a143cd9ae359decf01939719f65 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:39:17 +0000 Subject: [PATCH 018/142] Automatic changelog for PR #86465 [ci skip] --- html/changelogs/AutoChangeLog-pr-86465.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86465.yml diff --git a/html/changelogs/AutoChangeLog-pr-86465.yml b/html/changelogs/AutoChangeLog-pr-86465.yml new file mode 100644 index 00000000000..88e5ad71539 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86465.yml @@ -0,0 +1,4 @@ +author: "TheSmallBlue" +delete-after: True +changes: + - qol: "The z-level button got a refresh! It's now applied to more places and it should be simpler to use." \ No newline at end of file From 7db085d71c0c15ebd469e1d4864213a4836d179a Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:39:45 +0300 Subject: [PATCH 019/142] Replaces HAS_TRAIT_FROM with HAS_TRAIT in engraving checks (#86630) ## About The Pull Request Stumbled upon this by accident. If you add a trait that **should** prevent engraving from a source other than INNATE_TRAIT you'd probably want it to actually work. This doesn't actually do anything at the moment but could save someone a few hours in the future. ## Changelog :cl: code: Non-innate engraving blockers should work now (none as of now) /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/__DEFINES/traits/sources.dm | 3 +++ code/datums/components/engraved.dm | 4 ++-- code/datums/elements/wall_engraver.dm | 8 ++++---- code/datums/memory/tattoo_kit.dm | 8 ++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm index 0648dd4dd37..e3d1f9f065b 100644 --- a/code/__DEFINES/traits/sources.dm +++ b/code/__DEFINES/traits/sources.dm @@ -301,3 +301,6 @@ /// Trait added by style component #define STYLE_TRAIT "style" + +/// Trait from an engraving +#define ENGRAVED_TRAIT "engraved" diff --git a/code/datums/components/engraved.dm b/code/datums/components/engraved.dm index 60bfa5f6177..5db43b8076c 100644 --- a/code/datums/components/engraved.dm +++ b/code/datums/components/engraved.dm @@ -67,13 +67,13 @@ RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) //supporting component transfer means putting these here instead of initialize SSpersistence.wall_engravings += src - ADD_TRAIT(parent, TRAIT_NOT_ENGRAVABLE, TRAIT_GENERIC) + ADD_TRAIT(parent, TRAIT_NOT_ENGRAVABLE, ENGRAVED_TRAIT) /datum/component/engraved/UnregisterFromParent() UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) //supporting component transfer means putting these here instead of destroy SSpersistence.wall_engravings -= src - REMOVE_TRAIT(parent, TRAIT_NOT_ENGRAVABLE, TRAIT_GENERIC) + REMOVE_TRAIT(parent, TRAIT_NOT_ENGRAVABLE, ENGRAVED_TRAIT) /// Used to maintain the acid overlay on the parent [/atom]. /datum/component/engraved/proc/on_update_overlays(atom/parent_atom, list/overlays) diff --git a/code/datums/elements/wall_engraver.dm b/code/datums/elements/wall_engraver.dm index 7204d8cacef..2b319b0609a 100644 --- a/code/datums/elements/wall_engraver.dm +++ b/code/datums/elements/wall_engraver.dm @@ -31,12 +31,12 @@ /datum/element/wall_engraver/proc/try_chisel(obj/item/item, turf/closed/wall, mob/living/user) if(!istype(wall) || !user.mind) return - if(HAS_TRAIT_FROM(wall, TRAIT_NOT_ENGRAVABLE, INNATE_TRAIT)) - user.balloon_alert(user, "wall cannot be engraved!") - return - if(HAS_TRAIT_FROM(wall, TRAIT_NOT_ENGRAVABLE, TRAIT_GENERIC)) + if(HAS_TRAIT_FROM(wall, TRAIT_NOT_ENGRAVABLE, ENGRAVED_TRAIT)) user.balloon_alert(user, "wall has already been engraved!") return + if(HAS_TRAIT(wall, TRAIT_NOT_ENGRAVABLE)) + user.balloon_alert(user, "wall cannot be engraved!") + return if(!length(user.mind?.memories)) user.balloon_alert(user, "nothing memorable to engrave!") return diff --git a/code/datums/memory/tattoo_kit.dm b/code/datums/memory/tattoo_kit.dm index 98d47eaa285..62b4d73be28 100644 --- a/code/datums/memory/tattoo_kit.dm +++ b/code/datums/memory/tattoo_kit.dm @@ -46,11 +46,11 @@ if(!tattoo_target) balloon_alert(tattoo_artist, "no limb to tattoo!") return - if(HAS_TRAIT_FROM(tattoo_target, TRAIT_NOT_ENGRAVABLE, INNATE_TRAIT)) - balloon_alert(tattoo_artist, "bodypart cannot be engraved!") + if(HAS_TRAIT_FROM(tattoo_target, TRAIT_NOT_ENGRAVABLE, ENGRAVED_TRAIT)) + balloon_alert(tattoo_artist, "bodypart already tattooed!") return - if(HAS_TRAIT_FROM(tattoo_target, TRAIT_NOT_ENGRAVABLE, TRAIT_GENERIC)) - balloon_alert(tattoo_artist, "bodypart has already been engraved!") + if(HAS_TRAIT(tattoo_target, TRAIT_NOT_ENGRAVABLE)) + balloon_alert(tattoo_artist, "bodypart cannot be tattooed!") return var/datum/memory/memory_to_tattoo = tattoo_artist.mind.select_memory("tattoo") if(!memory_to_tattoo || !tattoo_artist.Adjacent(tattoo_holder) || !tattoo_holder.get_bodypart(selected_zone)) From 92e585028e25de63a3d49e68e2ff8ef127bf91c2 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:39:49 +0000 Subject: [PATCH 020/142] Automatic changelog for PR #86612 [ci skip] --- html/changelogs/AutoChangeLog-pr-86612.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86612.yml diff --git a/html/changelogs/AutoChangeLog-pr-86612.yml b/html/changelogs/AutoChangeLog-pr-86612.yml new file mode 100644 index 00000000000..e0a8724f07a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86612.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - bugfix: "Fixed certain clothing sending suit sensor data when it shouldn't be capable" \ No newline at end of file From c6eefb9e35999db39e04eba7ee8a5b9c81d11f70 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:40:08 +0000 Subject: [PATCH 021/142] Automatic changelog for PR #86630 [ci skip] --- html/changelogs/AutoChangeLog-pr-86630.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86630.yml diff --git a/html/changelogs/AutoChangeLog-pr-86630.yml b/html/changelogs/AutoChangeLog-pr-86630.yml new file mode 100644 index 00000000000..2f3938d6575 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86630.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - code_imp: "Non-innate engraving blockers should work now (none as of now)" \ No newline at end of file From a3c66fb923974374582d78344ff9390f0a05b9d1 Mon Sep 17 00:00:00 2001 From: IndieanaJones <47086570+IndieanaJones@users.noreply.github.com> Date: Sat, 14 Sep 2024 16:44:42 -0400 Subject: [PATCH 022/142] Self-Gorillafication Nerf (#86588) ## About The Pull Request So, I buffed gorillas a while back for traitors to get more mileage out of them, and outside of needing to adjust that one wizard spell I've been overall pleased with the results. However, while I knew that Geneticists were capable of turning themselves into gorillas without the magilitis injector, I thought it came with great difficulty but hoo boy I was wrong. Turns out, its quite easy to turn yourself into a gorilla with the three roundstart genetics setups you start with, and all you need a little bit of toxin-healing chems (which don't really have a downside and can stack!) or a medibot to pull it off. People have been using this to validhunt as the newly buffed gorillas as early as 7 minutes or less into the round, which I think sucks! So I'm here to change it. If you become a gorilla from genetics, you become a new subtype with nerfed stats. The stats are as follows: 180 health (from 220) Melee damage 15-18 (from 25-30) Obj Damage 25 (from 40) Speed 0.1 (from -0.1) Paralyze chance 0 (from 20) No limb ripping ## Why It's Good For The Game It's very easy to become a gorilla right now with little to no effort and to great effect, seeing as gorillas are pretty strong now. This brings crew gorillas back in line to before gorillas got buffed for traitor usage, which should ideally make this more balanced overall. ## Changelog :cl: balance: Gorillas made from giving monkeys genetic damage are weaker than their normal counterparts. /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- .../status_effects/debuffs/genetic_damage.dm | 2 +- .../basic/farm_animals/gorilla/gorilla.dm | 17 +++++++++++++++++ code/modules/mob/transform_procs.dm | 5 +++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/code/datums/status_effects/debuffs/genetic_damage.dm b/code/datums/status_effects/debuffs/genetic_damage.dm index 9a694409077..91cfc593fcc 100644 --- a/code/datums/status_effects/debuffs/genetic_damage.dm +++ b/code/datums/status_effects/debuffs/genetic_damage.dm @@ -34,7 +34,7 @@ /datum/status_effect/genetic_damage/tick(seconds_between_ticks) if(ismonkey(owner) && total_damage >= GORILLA_MUTATION_MINIMUM_DAMAGE && SPT_PROB(GORILLA_MUTATION_CHANCE_PER_SECOND, seconds_between_ticks)) var/mob/living/carbon/carbon_owner = owner - carbon_owner.gorillize() + carbon_owner.gorillize(genetics_gorilla = TRUE) qdel(src) return diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index d1b1aebf9eb..3a70afd7b62 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -167,4 +167,21 @@ ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) AddComponent(/datum/component/crate_carrier) +/// A version of the gorilla achieved by reaching enough genetic damage as a monkey +/mob/living/basic/gorilla/genetics + name = "Lab Gorilla" + maxHealth = 180 + health = 180 + desc = "A gorilla created via \"advanced genetic science\". While not quite as strong as their wildborne brethren, this simian still packs a punch." + melee_damage_lower = 15 + melee_damage_upper = 18 + obj_damage = 25 + speed = 0.1 + paralyze_chance = 0 + current_size = 0.9 + +/mob/living/basic/gorilla/genetics/Initialize(mapload) + . = ..() + qdel(GetComponent(/datum/component/amputating_limbs)) + #undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 28de95ff94d..45e54a8475c 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -311,7 +311,7 @@ qdel(src) return new_crab -/mob/living/carbon/proc/gorillize() +/mob/living/carbon/proc/gorillize(genetics_gorilla = FALSE) if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return ADD_TRAIT(src, TRAIT_NO_TRANSFORM, PERMANENT_TRANSFORMATION_TRAIT) @@ -327,7 +327,8 @@ regenerate_icons() icon = null SetInvisibility(INVISIBILITY_MAXIMUM) - var/mob/living/basic/gorilla/new_gorilla = new (get_turf(src)) + var/gorilla_type = genetics_gorilla ? /mob/living/basic/gorilla/genetics : /mob/living/basic/gorilla + var/mob/living/basic/gorilla/new_gorilla = new gorilla_type(get_turf(src)) new_gorilla.set_combat_mode(TRUE) if(mind) mind.transfer_to(new_gorilla) From d493704475ee4d42c891181c9d1e123842209bc2 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:45:34 +0000 Subject: [PATCH 023/142] Automatic changelog for PR #86588 [ci skip] --- html/changelogs/AutoChangeLog-pr-86588.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86588.yml diff --git a/html/changelogs/AutoChangeLog-pr-86588.yml b/html/changelogs/AutoChangeLog-pr-86588.yml new file mode 100644 index 00000000000..1509db98008 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86588.yml @@ -0,0 +1,4 @@ +author: "IndieanaJones" +delete-after: True +changes: + - balance: "Gorillas made from giving monkeys genetic damage are weaker than their normal counterparts." \ No newline at end of file From 3137c0c29f34a76370bcd1fe56f0a9292d93d5d0 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:03:50 +0300 Subject: [PATCH 024/142] New mediborg surgical saw sprite (#86643) ## About The Pull Request ![image](https://github.com/user-attachments/assets/28be1456-8de0-402d-ae90-0b70de6bba9f) ## Why It's Good For The Game Our surgical saw sprite is a bit confusing but the blue part is not, in fact, the sawing bit, so borgs ended up pointing the saw at themselves this whole time ## Changelog :cl: image: Added a new sprite for mediborg surgical saws /:cl: --- icons/mob/silicon/robot_items.dmi | Bin 10830 -> 8875 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/silicon/robot_items.dmi b/icons/mob/silicon/robot_items.dmi index 2cb809fe2724b1560da59300ab4c6a452edadf5b..bece0211ec8efe4033dfd0683e54ee275db6fabc 100644 GIT binary patch literal 8875 zcma)icT`hdlrITE2)*}C=v9hH4NaOLAiYRH1O!2fbOJ;=NR!@+NUsXgh0u}yfeJ_` z6s7l&&>ns>Z`RCOZ`OK$+}xXe&Ms$Xuk-ueeG;SpM1zEokq`$5heS(L?djcpoo_XNpWS#l>d|iULMWIprb0N$qiR4Xfp1N-*y>`rJ z^3rK6@_TFLD%K_rj4yHT?QO9TzEB!_#=Mc+m^U|Ipgg&9c>Ubb0BN7uxqJg(i>}`i zXS?Z}v8e_Myr23LBv%@LODDzqyEj@}`-S>Hj60RJ+r#P`c}l!b`8fQlEO^BXjY=6* zT%}1|i9n^(w{|5}=Ci>}^0kh- zf{aZ57{>T7+-8s>4jaWW8-8P7BhQ_RJ*aS7;^BAA$Z9f3**Jss2Q^?bmqf?Y&*vmH zWy9V*Qn8`+cuy*lm4AP5@5%Y}wUp6ZW1;0;z`#6b_tbJa?c3JC3+78I2)ZJQVaYv* zV>#%9kTA2UTfVO6!@WUE43WSR%y3+LrvL|sy+=z;*~stLULL+5^^bGp1YtOB0EupZ zpK@w))YI^xV$)SE1P&(|-bXGVg??|Kr1D2CL(GXj0lB|`u537`*-HWTA`l3|lZsFa zMU01xyX=c+jqZ={E@aKUm^ipR9&^c3m=1ok|FvNb6`h!fAIiSltqi0L4@yFSY`Gxp z%CiJuP4WjSccS?J5=CU@GhN}4*vqZwZ! zY8JqE1|88Cksz1vzxkbRCW{VS=l(kRSC$HGvcuPh#}+K2E*J3oP6N*>Pdr*Z+3ys8 z{Z;%M3DL!RiY|xG88gn2EIEx7WAMc)qC`$9mQ8Sgj!XUQGryv17tHlGhAO0c>1zW^ zQhZYZ79j)aH0CYn8bC*(mOC)?$_I)oQ}}RI=ExeGBhyg%ezd*DVYJ&LtB?e@AD!sI zy#ry%!#}|F21FP>8EwG%E|`OZ11IdBc>vphA-sw-v}~{WIm?yDWev3wLr7sFFw^5o zm(IN>9IUeQvu1TTO;Eo`1#h-9NNyDBH+klY(?Avu9c*5MoHkuM9N>m5-rS?rD!0GQ z5wS5d%lv-c?*<^IF6b5gz@w%{U}6RS+TXkeI-S{T=A?QNg>u_Ex8z(I%aOMImds76 z)8GG&F3M@TR12o*YV!|R>F5Wl%p8J%x9MNL; zz?r&EOY$lNWH7?0L^!*`5)(8BG8*|}2a9-1OlVeT{meGc zCzt?@v-g{({k4+1Dy@iTrRdbson^CPC-Z#Z`CKD=ioT#6sp+*9kM+m{J%@ncttPgQ z6($sP!WIx>2Jybr6B)~&_{3iNo&OYDhsnHIPGN2Emw=2yR@VN(*$9p}duH;=B0U4a z2g3*!+q#Wv9QH~7nRw7#Cimj3WHlbn zZi<~QwV5Q>V>NtNZbZpAUQfP^V#UzEDHDwvQq=ugOGg-OD8W5Sdj?Rr{vA(a?0LAg z$v8_7(^agJD1^Yw1_lc#CAEeOk%h;t95*p_{b$j%b`yw!`JM)XS#-aH^~SWo$`NWX z;;t~YkMC2QeR#CsV$8((P*sgO|1I6y@bLL5_{*0RhE?mcEHM5eV}?U(eUUP_>4y?#D9t4^x--*R3IR zRLSm^t|BO>h&O@th_A>>35L!~=W%JOAmdAn(p@^R4mPLk(n=wHZYrrB5Ik8(f3Yp- znBw;cH8Az&0=F^$)4@Z7R)eufbhr=x|LcnK}Hf&tvp-wDsAY!E>2}2UEejFXl{>U&l zVG4l3kEDuhd&>%KdmT##mxJ43-ZzVOI}-0K>mHY)h*ST~nkeI*fV^&$4c>WNq1 z_-mijP7Y(ecJqtj>uE(lLF;*dvw`MHut11Q09E5l&C=4cM$+S8jt@!t?+~+BLMHMc z?F=8%{Er_Oj-3>J_IO$Q+ncJTjQj*yNl&k()p&!5&vy1FI)UQgnqAz_fr-)b>BhRY z?WmC$@|lv?i)~rrg?>Fs9bjE+Eo57(gtWB5Mchq3gd@d}qv)q1yMuBukdx2$2c_kz zc4EK2OSgii&MmOBypw7Po`j#Tiy;vS@d7&t-w>ap{T|J*$7KzQ&)*gOi#|IZn*y?& zB7z6dPi%a#PTPFtRe!)qQbf;h#kf>I&z!}DCcu&{`7E2|o6qu_%jB+>*d2niK`#vGQd@*tchHraj zFWN`|Nsm-!`1n4&OxSF{Epq@wkzx%9YE36lfl~=A(_i*eYCDNeRG^W9!kvg85t~YN za>Yd_W0cwZ0C50Q)#*n6^@Qtf_EWYbG5iM?p~oD@#6zqntZ_$Y?S*{&qJS(vqKuy& zaQdSTatn5XI=iTQ$JRIA2}9{&5cYRpDETKjfp3nAG`nY z7CyEo0_;^!(3ZzBN@*jhLhT=pMo(#R2gdP^EwsLIr6d0*kc*YuD3G;31$xd?WTh5q za+C_h+Eabs$GW^FWP&Sq>#OrH<_uOagx&AFk(>HTFJ^BOtu>2^`JnH$YSALqh|jFo zK{VDGH$o}6kwQ@91-sr^K?8r87sNxn5)c9s1?F5uH^ZIh?^PBn@#MA5R-e1AYHt|J zJXY%a>myE{YR#@e9Oi?=-N*kxLy-51Xnk(n6hq!cm&ATWk(w}eDZuuB5uXC*zhM7= z-?sldIrw)Lr5JE6W$Y)2qxVLI8PuR4H{^G$cLiIMv&@$%sUDfOm2VzHN0V2o3_5 zQ!$3$Ck0;+P)tfJt?GMEV8^FWET+7o@v9zBM4sITQTNa-8KKyI>{)tGWIP+7mD+S zu7;9y|Au)t)(w4b2uB~ypGQZE>@jI3vXSv;I%O541V@qHw&VLYzedBo^L%L=HI6X6ExM zIVB}2*{!-WF-?_GMFKf8|rF0q7D2h;zuj%y$xcL zejPqJsXq%})uLbAWbL?Edp8w$UxM?3)t{%)2x;3J>3`i!;-g9}P3wy^^xj6Ip*O#O zQ8=(%(OJXzg$iV?hC`i?=F(6&-!k8hw!TTfBbt}XmZw=e*LI4EfUbiqG8S1y zJXp{f4a6}nf0Ly0-lKOV$|*d$>>M1*lw|g~l1`N0tIes#b7gSv@_AOLSoq60nxl&` z%Nu9|bw?s>v$8*!3^WH`UMqC60&bfz(Fol^iyy;UiOmNK75?i}^XD_KCxIfl3S46_ zQGSP}lmcYstS|HIa*FhQ7&(+zR@NeWaMSUQ%}Sh+QFKx3w^BKq)REdP`}KBrenN_& z)bvxxQ7B`x7-QZ0A#rZTv@gaK)(>nkQvGU}NU}Y_u?A%-W}$8aotlCo`&(4oSRN(U zx2?Ss{Q>WtpBOZI+%Hm_YsC_{!@0&f*9W15WA@BNwq&<1=s+_kQNlHvx7IcU6m=ur z7sNM~L5nZ%Fy<#WEql5nZHC<1_z2R7WAy3)C~^!rSGjcoqe5t`*|C6={AL&{mxtzag8FQneu`rH z}>Zl-vHL)>VWuFK-KVD)Q+_<=0WRLU2507Orxw0UC75RDQut_cJ zY01Z`6qg)&H>va_V=tw4SeH?ONPevtevO})wpnFdORyzsonA^{{pIMRov9m$ zjVopO_d#r;bZpncxp1S~^rTdOscB+oF;33(Mb_>K1;$Q~muvpU!%Z|Dt3T9kcyC8G zCZ2Gp$@b|f0n+jj-->9)xN=&h@v6%650Z}U{*32>dgkeTwB z7G#&ZX(6L;5%FjCZD9`S+QSuJ$`w;q0@Pri6dvP*8&wOlTug7(wPma7sL0F2y`bl@ zX-Lm|mRMy>W}Idqk{}r((tY-YZ-W|YheBOKa%lGAVy;I0tp<^BMu`dkqNvTx0eg1N{jb zqVMRQA*Uu&#>^JR-7&wO&VJ98dC;GuxfJ}>lA;3#7~qV!=b|dST4o5#r7pp)=dls` zA+DNV0AC_DpTl2o{$ON_eonoH_vs&t8VpejbAb!% zs#gKz129`&&i3J7dElCGdzIZpY*i^T>yQc=((tGS`Han44L~mKIKP%OG#L z!lbD~5V}9TOhN$O2vTubW0gI9rsN_`l>$1Y((e(WIq5E0C--PPSFASk;VOi@xYlXV zPWcbhF-2=}e(T1BRa>t}x;{y8Ce*=h46!dcZFhkKO9nwFGJ9wcbmsmIG% z#6X!OF)PFk2G{&gX7oWzsglgm4bHi>hIsqfc&B*PrYEqQtOPSN<*6F;l)EJeVEm+T zCW;HlWP0x-*8O~d7fAJgb===)7aFmRcV4L3aM}N-9e0m2K!sxN*CPdr6Z_BP)17g> zl^dx#d2)K051l{$eU|?j&~Z59bA9`EWye!n)_a%FWuft#?SQAqe=2HGFJ1GS{b*%i z&P=|i%Zv9a|9q*Qj5GwRK>wbcJK(d0adiB(n(tM4dFNp-Moo;9Lz^0VpVCw&y0vDbrjp9nqR-*6ueW#v@KpYlC%2-dl7YAjcj;mYv@lgCk^4{xNwrEkHti$$ zz@5r{Cq2Fm)$BSGlY*uWILo1?W4G8{n+RQt9g< zt-fd*NUi+e#e#nec7RT4tbv>*^Kyw=!@ql`8Z(N+CBG)I9>CwIbIc3VSgRVZ{hj#5& zSODwD@zUk1?bgi+ZtE%0!e3gNXMd{W51t?=xGe4cYuuwWpjx-{o1W&@2aL^OIS3e> zwhSv<8)o6Mj(Pol0pxOZn7?mNwmCkiiv(gk+ZWOM3Ehi{=9egICFS#s4X>T0d$&v z{rw!*L3t7QIVEX(dX5gJi>xJaZqGMt$BM6;u1+N8uJaU%<2rxCk&(f5?k*!P_n~|m zB)@|a#7lKlsxh@`kSLTM9Y!3xY`tc^FNpiu%<0IU{r8Ngd)KZpL4xLZ^4p+s#4*(* zY-gH;MOrWW`Fl!!7P;%so~F75+@ z;s?O(8nQ^PqK`ODtm6IPMMM0MX?x%;g^`8}C&%62fCYvN4 zChSK&*a-IiieI%<7}pWP$+GbZ?U^GqK_|!{q-#q0dh6FsIo|y0Wv{8ud;MT06<5f2 zmWRMtdK!0ot6Y6Z@xjh(h!M$XaI^tnN288r%I)Ef`|m&auOo4-UaNZ1O>{5#A8Vcj zVBcn5llKA#YAm;q0XWjNi-`Ua6D@D@dL1g0#JLs^yYvqy9e5pABNJ2dCTD-39stRj z?IEM6w?A-ao*q0Q>*YNlx45dprxrGtd&!44@Tob z!T;=Fqv<+eaEqmKgdOh_YU|k8(7rykf^=zt6*NUdI0e_d@^Hq9ODhE%1qFxv_35a&EuOOsBtBw-E>twNZ`E?{pHr1``VPo`_|`qNi7! zsz)1?!{%*X{KSlsLsG`5giOGr!3)CjRPx8?=X;Ca8WlOJw4$y-p#h3{?=ep2-H z@@llFT)T#Y zD!gypeU~B8pZBGilDZ8HSt&mUzTHB*;4{;t74On<3JHFw<`dBa#N^_m3raP>%a$#~ z0rJaF86~?fBRjaOpZ5B@)vuwx;Mg0Ij@PffCrI2Zw^9M&JCN^kRlZM$>t?U9kB2r} zzDI;xwh%>+O*u7`^@QK20z7_*Vvo<-XzPeiI#yBS3mfX9DZb~RM4b+T$lJ!=b+P(( z`{XWL!$^>EOwtsi)%x#(R4{hw;53^}RZYbnrcxsf6|jf1eUbLh-H#RHSzl)eP$p+yf1mw}VHE1)n8`b! zgcRP3ao*H>oB1KaYbNSlt2h4m$BcVilpoYE$6HYgtt@RQD4Y-Z_0;PxHh%wfV@S?w zt>=5y84^?~+|(yRkYA>7SS* zq_y#O;VG;;q|}e+cXF!5Xmxj29;|W~*3r`({<6!92;kPnFyGF`ztZ2XBZ%cQ514OHFl?lsS9SmA-SVn5q31|3OV~Kx>K7a{z%Bx>>c!`1Ko{!*J zncr%Sjhx9~aeV==etfs)J2}l#+XtS)1 z2*nWb5sJyk%U=mo@EKQ9d-;{VKfPL_g7%#LndW%#z$gF0zZePHjU5B!nm;({cKiZZ z_%Wb5a2=4BgNO(_sTjy8w#rzZ+V`NUH=lO&5^X;~&MagX=1iqKEgi%qbmO*2DWk1) z#*ed`e=$!Oi}dQ+uY51vOX6*ewFPX<>AmuXjD~iAj2xiC zXBhWOf3RQUVY<+Koe7!Blk4SQ9#oTt=Wm)7Gx7WhXDgqUXwSF%9+2V@(T0C`^iE~9 zCxQc}xRr)k?TtD-8f5F;Uu=(hSAbD;?;D@hQ5wZLCX{#n;ZKfvlL?3;EKh%H?y^B+ z*7`(VyuQm`N$=7!W{yF>ll2&dT*(8-y_<6kDprrTL6_|mj&xxkix-0YPc|d^4NFyK z8+2EZZ*ft56S;WIpCp>(ai2G(I4ZiG$cwX6=`Y=W&jx&A8-A?hf6r*d$9We}wxOf`N0C6b$ySvH0Tb?tBa2 z-zg;KMejvi%>aK~Ga}T4xPB_n@$+Jq0;H!?#=s6t0#2|1A>bJfu{id)KuZjsXDw}(-f40{51Hl2a(St70h zuxi`lTM0`MY-5K3z&uFy%ao1DLiDl+wo=SqU$kQg^H+}VYYy3c$c2-lFRG3g7ZXd# z*a!}rr^}tM`ZN2o8iW*PIq!7m_sOj_F_VO|XL7-ip(HB;s?>fe~fA%MdVS_CQdLNt7Q#oR1 z@a;#HDHAQZGWg7MTbs~I?l#31P(syV&UJlx+lKRn$3#qsJ(O~s{vzs4NJ!F|m44vf zlVO%<#!FK0&|{Uaxo?xjB!f%&&;F<{_@AddD39%VG7u{pjcIh_%VK?dPd45c9-zKJ!uXAxJO-6DYTyAzeN8)R^n?Y zRAQR2UB-3xGL%UKFFFXLDI-kyNo$^a?$jnWacy!ytXjbNccI28sW%`LHq*X8V{_db z+PU-Zr<8#R_-j@o8}F3n&gw$(W27nc=S>d#JDAr^IP=|E`u;ycHW>_f-XRy*-^*G` zp@#?ufcg2!Y5T?Sj2KZe0<_Bdj6vTVPc!DTEQ$Tycw8+pUmdd8r1(h|4L>erxT6;u zpkT~n+^Nox#4calPF9XTe5b`w2i(NUs_>bN`ZK9aX!6~a_uV4Vel&**Ed;j6Exq1v zy4c66f78^Wk%CBb#%;`A%L)JYYs0^FlftCeduFk77n8p7^eyf%_xF*K6r3N9Pwznp zq$F=OI_fC@BRr_q-LF8hqNRA}0my*WrT_0K{GVA}zXfbxY4x6v!`ANpgo2~>=!sgb IicRSM0g~6khX4Qo literal 10830 zcmbVyRahKB)9xTa5-dP)CrAhy2<{F+gS)#sVPSFC;0{3&g1fuBySpy#{%^kLoU8MH zH|Jt^=Gm?3s;;hj>z(QjRgjZFeM|5b002}eNzw1n>-xVB5(4y_fWdMD0ARvBl+~R@ zO`MDzE$p2w>}&zRJv~3ZLavJ$BWQ2?lUzB4=sUP?ILZOs<7(xlH#1y^^AiidHjnWM z!puVr{lBRHY#n?HJ(|MbKL zDdrvxd;l@HkW=gEw{w`MN*Hk15Bk>51M0L+(Bku$ZS3oZ zJ^?M$7~0hj%{lu7ravF5*rxu<$Wl$h75F3=h-Lfa|Nb4i!$2>F$>hSR3Y++&*;q4$ zMnagEiY~)%i^7l0HwTt3%%l4LnPs?K&DG7-)yyF4_Nd3o%*|}~GQ)uX(vzubO`@lg z9?4H32o%o<2-SZv7W7lV_(CQ`i-aFTh8=(+iSbq#;Um%;ayZNYzj@>KpD0}eDj1VA zUTV`x*6rVeHb@R%y(@8ouB6sxuBh z7(J+L$N*nZYAQj6;8*&hSak&GNJ%qEs|d@@_&Ym001@bx+-uTK`XLr2IlWmkA^yq@ z5R^G#`Dif{NDOlj2UeP>`-@v$U5(vmI$Umo%P#bgw>E#BworLKk=wTL(e^V`SEP;} z)y}QY#Dr7B`uaKT=dCpm2u{zt1$|(kh*-0981(kv_y1_8I$q3y@q z32h;d2Tj2@0dgvmSy5|$qrA8K>*~9L1sp?=ceue)?=jX-VMT)ZVSUhhq8cA#S{K$BWK@FzbK_L4^XfJfaqUB22)S7z|@bD1T40m)y%0DdK2y9Oy5`oat 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 G{r(4;a~FXC From 942616fddcc06273cdfe285f6578e16d9f16cb4f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:04:22 +0000 Subject: [PATCH 025/142] Automatic changelog for PR #86643 [ci skip] --- html/changelogs/AutoChangeLog-pr-86643.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86643.yml diff --git a/html/changelogs/AutoChangeLog-pr-86643.yml b/html/changelogs/AutoChangeLog-pr-86643.yml new file mode 100644 index 00000000000..9d2ed8a9e05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86643.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Added a new sprite for mediborg surgical saws" \ No newline at end of file From c78a6fb1fb03028d0b86272ef9fa32dbaa96f8fb Mon Sep 17 00:00:00 2001 From: Thunder12345 Date: Sat, 14 Sep 2024 22:16:32 +0100 Subject: [PATCH 026/142] Fixed Delta library disposals (#86621) ## About The Pull Request Reconnected this disposal's pipe in the curator's office ![image](https://github.com/user-attachments/assets/d14663aa-37cf-498b-91bc-dc198ccb15a3) ## Why It's Good For The Game Disposals should... dispose of things? ## Changelog :cl: fix: Delta: The disposal unit in the curator's office is now properly connected to the disposals system. /:cl: --- .../map_files/Deltastation/DeltaStation2.dmm | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 47eb8b28262..9a7f5ee7689 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -2842,6 +2842,9 @@ /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/landmark/event_spawn, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "aII" = ( @@ -16925,9 +16928,6 @@ /turf/open/floor/plating, /area/station/cargo/storage) "ehg" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/newscaster/directional/west, /obj/structure/table/wood, /obj/item/clipboard, @@ -42974,6 +42974,9 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "kHp" = ( @@ -46664,6 +46667,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "lDV" = ( @@ -56033,9 +56039,6 @@ /obj/structure/sign/painting/library_private{ pixel_y = -32 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/modular_computer/preset/curator{ dir = 1 }, @@ -64198,6 +64201,9 @@ dir = 8 }, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "qaF" = ( @@ -66387,9 +66393,6 @@ /turf/open/floor/iron/white, /area/station/medical/medbay) "qEj" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/light/small/directional/south, /obj/structure/table/wood, /obj/item/paper_bin{ @@ -80582,9 +80585,6 @@ /area/station/commons/toilet/locker) "ufz" = ( /obj/machinery/firealarm/directional/south, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, /obj/effect/turf_decal/bot_white, /obj/structure/filingcabinet, /turf/open/floor/iron/dark, @@ -89971,8 +89971,10 @@ "wwN" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, -/obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "wwP" = ( @@ -90329,9 +90331,6 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "wAZ" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/structure/table/wood, /obj/item/taperecorder, /obj/item/camera, From f52576618b513f3155952931cf12c2a2544a5fe6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:16:51 +0000 Subject: [PATCH 027/142] Automatic changelog for PR #86621 [ci skip] --- html/changelogs/AutoChangeLog-pr-86621.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86621.yml diff --git a/html/changelogs/AutoChangeLog-pr-86621.yml b/html/changelogs/AutoChangeLog-pr-86621.yml new file mode 100644 index 00000000000..3e88333c3c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86621.yml @@ -0,0 +1,4 @@ +author: "Thunder12345" +delete-after: True +changes: + - bugfix: "Delta: The disposal unit in the curator's office is now properly connected to the disposals system." \ No newline at end of file From 111ff5d8bdbd813299b70a48772b1530b1832236 Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Sat, 14 Sep 2024 18:54:07 -0400 Subject: [PATCH 028/142] Add distance output to direction circuit component, resizes several shells (#86577) ## About The Pull Request The direction component outputs the direction of an entity if it's within 7 tiles of the circuit. Since it already checks the distance, I added distance as one of its outputs. Besides that, I did a pass over the generics and shells and resized many of them. Most I resized to be small or tiny, except for the airlock shell, which I set to be bulky because it's a whole ass door. The shells I didn't touch remain at 'normal' size. 1) All handheld shells set to small, compact remote set to tiny 2) all components and the generic of the circuit set to tiny 3) drone shell set to small 4) airlock shell set to bulky ## Why It's Good For The Game Returning the distance spares any would be circuiteers from having to do a labyrinthine set of calculations to determine distance themselves. Making most circuits more portable makes them more attractive for people to tote around. ## Changelog :cl: Bisar qol: The 'direction' circuit component now also returns the distance of its target. balance: Most circuit shells and the generic component and generic circuit have had their size reduced. balance: The airlock circuit shell has had its size increased. /:cl: --------- Co-authored-by: Metekillot Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- code/modules/wiremod/components/atom/direction.dm | 10 ++++++++-- code/modules/wiremod/core/component.dm | 1 + code/modules/wiremod/core/integrated_circuit.dm | 1 + code/modules/wiremod/shell/compact_remote.dm | 1 + code/modules/wiremod/shell/controller.dm | 1 + code/modules/wiremod/shell/keyboard.dm | 1 + code/modules/wiremod/shell/scanner.dm | 1 + code/modules/wiremod/shell/shell_items.dm | 3 +++ 8 files changed, 17 insertions(+), 2 deletions(-) diff --git a/code/modules/wiremod/components/atom/direction.dm b/code/modules/wiremod/components/atom/direction.dm index c2bbd5026c8..1b14e6505a4 100644 --- a/code/modules/wiremod/components/atom/direction.dm +++ b/code/modules/wiremod/components/atom/direction.dm @@ -13,6 +13,7 @@ /// The result from the output var/datum/port/output/output + var/datum/port/output/distance // Directions outputs var/datum/port/output/north @@ -30,9 +31,10 @@ . += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info") /obj/item/circuit_component/direction/populate_ports() - input_port = add_input_port("Organism", PORT_TYPE_ATOM) + input_port = add_input_port("Targeted Entity", PORT_TYPE_ATOM) output = add_output_port("Direction", PORT_TYPE_STRING) + distance = add_output_port("Distance", PORT_TYPE_NUMBER) north = add_output_port("North", PORT_TYPE_SIGNAL) east = add_output_port("East", PORT_TYPE_SIGNAL) @@ -45,8 +47,9 @@ if(!object) return var/turf/location = get_location() + var/measured_distance = get_dist(location, object) - if(object.z != location.z || get_dist(location, object) > max_range) + if(object.z != location.z || measured_distance > max_range) output.set_output(null) return @@ -61,3 +64,6 @@ east.set_output(COMPONENT_SIGNAL) if(direction & WEST) west.set_output(COMPONENT_SIGNAL) + + distance.set_output(measured_distance) + diff --git a/code/modules/wiremod/core/component.dm b/code/modules/wiremod/core/component.dm index 02e88e53c23..07f3a5b55a3 100644 --- a/code/modules/wiremod/core/component.dm +++ b/code/modules/wiremod/core/component.dm @@ -15,6 +15,7 @@ lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' custom_materials = list(/datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT) + w_class = WEIGHT_CLASS_TINY /// The name of the component shown on the UI var/display_name = "Generic" diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm index db1fd8ac588..8afc963b5a3 100644 --- a/code/modules/wiremod/core/integrated_circuit.dm +++ b/code/modules/wiremod/core/integrated_circuit.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) inhand_icon_state = "electronic" lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + w_class = WEIGHT_CLASS_TINY /// The name that appears on the shell. var/display_name = "" diff --git a/code/modules/wiremod/shell/compact_remote.dm b/code/modules/wiremod/shell/compact_remote.dm index 0697a449dbe..3bf216a4c32 100644 --- a/code/modules/wiremod/shell/compact_remote.dm +++ b/code/modules/wiremod/shell/compact_remote.dm @@ -13,6 +13,7 @@ righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' light_system = OVERLAY_LIGHT_DIRECTIONAL light_on = FALSE + w_class = WEIGHT_CLASS_TINY /obj/item/compact_remote/Initialize(mapload) . = ..() diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm index ae0eb01b367..f68dd0c50b2 100644 --- a/code/modules/wiremod/shell/controller.dm +++ b/code/modules/wiremod/shell/controller.dm @@ -14,6 +14,7 @@ righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' light_system = OVERLAY_LIGHT_DIRECTIONAL light_on = FALSE + w_class = WEIGHT_CLASS_SMALL /obj/item/controller/Initialize(mapload) . = ..() diff --git a/code/modules/wiremod/shell/keyboard.dm b/code/modules/wiremod/shell/keyboard.dm index 0b28959aa9c..86a57d50681 100644 --- a/code/modules/wiremod/shell/keyboard.dm +++ b/code/modules/wiremod/shell/keyboard.dm @@ -8,6 +8,7 @@ righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' light_system = OVERLAY_LIGHT_DIRECTIONAL light_on = FALSE + w_class = WEIGHT_CLASS_SMALL /obj/item/keyboard_shell/Initialize(mapload) . = ..() diff --git a/code/modules/wiremod/shell/scanner.dm b/code/modules/wiremod/shell/scanner.dm index f32f91fa76f..29a061a535a 100644 --- a/code/modules/wiremod/shell/scanner.dm +++ b/code/modules/wiremod/shell/scanner.dm @@ -13,6 +13,7 @@ righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' light_system = OVERLAY_LIGHT_DIRECTIONAL light_on = FALSE + w_class = WEIGHT_CLASS_SMALL /obj/item/wiremod_scanner/Initialize(mapload) . = ..() diff --git a/code/modules/wiremod/shell/shell_items.dm b/code/modules/wiremod/shell/shell_items.dm index 06929e3a04c..bad787033f9 100644 --- a/code/modules/wiremod/shell/shell_items.dm +++ b/code/modules/wiremod/shell/shell_items.dm @@ -39,6 +39,7 @@ name = "drone assembly" icon_state = "setup_medium_med-open" shell_to_spawn = /mob/living/circuit_drone + w_class = WEIGHT_CLASS_SMALL /obj/item/shell/server name = "server assembly" @@ -52,6 +53,7 @@ icon_state = "construction" shell_to_spawn = /obj/machinery/door/airlock/shell screw_delay = 10 SECONDS + w_class = WEIGHT_CLASS_BULKY /obj/item/shell/dispenser name = "circuit dispenser assembly" @@ -62,6 +64,7 @@ name = "brain-computer interface assembly" icon_state = "bci-open" shell_to_spawn = /obj/item/organ/internal/cyberimp/bci + w_class = WEIGHT_CLASS_TINY /obj/item/shell/scanner_gate name = "scanner gate assembly" From f3a233668cf26b57432d1ea0543fb1db2c83f68e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:54:27 +0000 Subject: [PATCH 029/142] Automatic changelog for PR #86577 [ci skip] --- html/changelogs/AutoChangeLog-pr-86577.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86577.yml diff --git a/html/changelogs/AutoChangeLog-pr-86577.yml b/html/changelogs/AutoChangeLog-pr-86577.yml new file mode 100644 index 00000000000..1c770955504 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86577.yml @@ -0,0 +1,6 @@ +author: "Bisar" +delete-after: True +changes: + - qol: "The 'direction' circuit component now also returns the distance of its target." + - balance: "Most circuit shells and the generic component and generic circuit have had their size reduced." + - balance: "The airlock circuit shell has had its size increased." \ No newline at end of file From 44d1f743635977f1346230ad02b78742f7076664 Mon Sep 17 00:00:00 2001 From: Da Cool Boss <142358580+DaCoolBoss@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:58:07 +0100 Subject: [PATCH 030/142] Adds Icemoon Ruin: Syndicate Lab (#86545) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Pull Request Adds the Syndicate Lab to the Icemoon ruin pool. This can spawn on either the cave or deep cave layers. It's a fairly small ruin so it's easily missed, but it is packed full of danger and treasure. ![!](https://i.imgur.com/jHelQYi.png) The outside of the lab is mostly covered in snow. There are a few small gaps that may or may not be filled in by the cave generation algorithm. From most angles, it blends into the ice moon enviroment. However, meson glasses will reveal the structure at a glance. This lab has multiple hostiles to provide threat, there's a turret near the entrance (on the interior), a patrolling eviscerator, and two ranged syndicate agents with shotguns. The ruin is pressurised by default, so mining weapons are less effective. As loot, the lab contains a Donk Co musket (single-shot combat shotgun, like the old pipeguns), two syndicate explorer's suits, a syndeye disk, a syndicate toolbox and some small gimmick items. The agents blow up on death so you can't have their shotguns or gear. ## Why It's Good For The Game I collected feedback for a while on ruins and a common complaint is that Icebox's ruins are lacking in variety, especially in the loot and action departments. To address the loot issue, I've added a bunch of loot to this ruin that previously could not spawn on Icebox. Mostly this is the fluffy and gimmicky stuff currently exclusive to space ruins, like the Donk piñata and anomaly releasers. Nothing especially powerful or round defining, because the ruin can spawn close to the station and isn't particularly hard to clear. Threats are likewise all things that aren't usually avaliable on icebox. Prepare for lasers, buckshot, slashing damage and all relevant wounds. Without a syndicate card or agent ID the doors won't open and the ruin is powered, so miners can die to hacking the door open, then getting run over by a patrolling dedbot. Very funny. The ruin is designed not to be easily rolled by mining gear, but it remains a viable option. Lasers are designed to be particularly good here, to reward cooperation with security. ## Changelog :cl: add: Adds the Syndicate Lab to the Icemoon ruin pool. /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- .../icemoon_underground_syndielab.dmm | 1247 +++++++++++++++++ code/datums/ruins/icemoon.dm | 6 + code/game/area/areas/ruins/icemoon.dm | 4 + config/iceruinblacklist.txt | 1 + 4 files changed, 1258 insertions(+) create mode 100644 _maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm new file mode 100644 index 00000000000..8d90a5079db --- /dev/null +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm @@ -0,0 +1,1247 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/clipboard{ + pixel_y = 3; + pixel_x = -4 + }, +/obj/structure/noticeboard/directional/north, +/obj/item/petri_dish/random, +/obj/item/paper/fluff/junkmail_generic{ + name = "weird note" + }, +/obj/item/paper/guides/antag/supermatter_sliver, +/obj/item/stack/sheet/mineral/plasma{ + pixel_x = 5 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"aP" = ( +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/cup/soda_cans/beer{ + pixel_x = -6 + }, +/obj/item/reagent_containers/cup/soda_cans/beer{ + pixel_x = 6 + }, +/obj/structure/closet/mini_fridge, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"bn" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/petri_dish{ + pixel_x = -10; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/mortar{ + pixel_x = -17; + pixel_y = 1 + }, +/obj/item/pestle{ + pixel_x = -12; + pixel_y = -2 + }, +/obj/structure/microscope, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"bx" = ( +/obj/item/cigbutt, +/turf/template_noop, +/area/template_noop) +"bC" = ( +/obj/machinery/navbeacon{ + location = "syndielab_beacon1"; + codes_txt = "patrol;next_patrol=syndielab_beacon2" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"cd" = ( +/obj/structure/chair/sofa/corp/left, +/obj/structure/extinguisher_cabinet/directional/north, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"cg" = ( +/obj/structure/tank_dispenser/oxygen, +/obj/machinery/light/warm/directional/north, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/warning/gas_mask/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"ci" = ( +/obj/structure/flora/bush/pointy/style_3{ + pixel_y = -4; + pixel_x = 6 + }, +/obj/structure/flora/bush/ferny/style_2{ + pixel_y = 6; + pixel_x = -3 + }, +/turf/open/floor/grass{ + initial_gas_mix = "o2=1000;n2=1100;TEMP=280" + }, +/area/ruin/syndielab) +"cu" = ( +/obj/machinery/door/airlock/security{ + desc = "It opens and closes. Menacingly!"; + name = "Syndicate Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"cM" = ( +/mob/living/basic/trooper/syndicate/ranged/shotgun, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"cP" = ( +/obj/effect/mapping_helpers/bombable_wall, +/turf/closed/wall/r_wall/syndicate/nodiagonal{ + desc = "An ominous looking wall. It has extra insulation to keep the heat in."; + name = "plastitanium wall" + }, +/area/ruin/syndielab) +"dD" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/condiment/bbqsauce{ + pixel_y = 8; + pixel_x = -9 + }, +/obj/item/reagent_containers/condiment/donksauce{ + pixel_y = 5; + pixel_x = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"el" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"ex" = ( +/obj/structure/flora/tree/jungle/small/style_4{ + pixel_x = -14; + pixel_y = 5 + }, +/obj/structure/flora/bush/sunny{ + pixel_y = 12; + pixel_x = 12 + }, +/obj/structure/flora/bush/fullgrass/style_2, +/turf/open/floor/grass{ + initial_gas_mix = "o2=1000;n2=1100;TEMP=280" + }, +/area/ruin/syndielab) +"ey" = ( +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"gE" = ( +/obj/machinery/vending/donksnack{ + onstation_override = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"hl" = ( +/obj/machinery/navbeacon{ + location = "syndielab_beacon2"; + codes_txt = "patrol;next_patrol=syndielab_beacon3" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"hn" = ( +/obj/machinery/computer/telecomms/monitor{ + dir = 8; + icon_keyboard = "syndie_key" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"hu" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"iy" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"iQ" = ( +/obj/structure/closet/crate/preopen, +/obj/item/radio/off{ + pixel_x = 8 + }, +/obj/item/radio/off{ + pixel_x = -5 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"lW" = ( +/obj/structure/filingcabinet, +/obj/item/paper/fluff/ruins/hauntedtradingpost/receipt/alternate, +/obj/item/pen, +/obj/item/paper/guides/antag/nuke_instructions, +/obj/item/cigarette/syndicate, +/obj/item/poster/random_contraband, +/obj/item/poster/random_contraband, +/obj/item/sticker/syndicate, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"mi" = ( +/obj/structure/sign/poster/contraband/cybersun_six_hundred/directional/west, +/obj/item/vending_refill/donksoft{ + pixel_x = 2; + pixel_y = 8 + }, +/obj/item/vending_refill/donksnackvendor, +/obj/structure/closet/crate/freezer/donk, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"na" = ( +/obj/item/climbing_hook, +/obj/item/pickaxe/silver{ + pixel_x = 3; + pixel_y = 5 + }, +/obj/item/t_scanner/adv_mining_scanner{ + pixel_x = 3; + pixel_y = -1 + }, +/obj/item/hatchet/wooden{ + pixel_y = -7; + pixel_x = -3 + }, +/obj/structure/closet/crate/preopen, +/obj/structure/sign/poster/contraband/gorlex_recruitment/directional/west, +/obj/effect/decal/cleanable/plastic, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"nD" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/machinery/microwave, +/obj/machinery/light/warm/directional/east, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"nT" = ( +/obj/machinery/atmospherics/components/binary/pump/on/dark/hidden{ + dir = 1; + target_pressure = 180 + }, +/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"oA" = ( +/obj/structure/syndicate_uplink_beacon, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"oY" = ( +/obj/effect/mapping_helpers/apc/syndicate_access, +/obj/effect/mapping_helpers/apc/full_charge, +/obj/machinery/power/apc/auto_name/directional/east{ + cable_layer = 1 + }, +/obj/effect/mapping_helpers/apc/cut_AI_wire, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"pK" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/machinery/airalarm/directional/north, +/obj/item/implanter/radio, +/obj/item/implantcase{ + pixel_x = -5; + pixel_y = 8 + }, +/obj/item/traitor_bug{ + pixel_y = 6; + pixel_x = 6 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"qy" = ( +/obj/item/clothing/suit/hooded/explorer/syndicate{ + pixel_x = 8; + pixel_y = -2 + }, +/obj/item/clothing/mask/gas/syndicate, +/obj/structure/rack, +/obj/machinery/light/warm/directional/north, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"qC" = ( +/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"ry" = ( +/obj/item/clothing/shoes/workboots/mining{ + pixel_x = -7; + pixel_y = 10 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"rH" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"rO" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"sa" = ( +/obj/effect/decal/cleanable/ash, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"sj" = ( +/obj/structure/chair/office/tactical{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"sp" = ( +/obj/effect/decal/cleanable/plastic, +/obj/structure/mop_bucket/janitorialcart{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"sV" = ( +/obj/machinery/vending/donksofttoyvendor{ + onstation_override = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"tb" = ( +/obj/machinery/light/warm/directional/north, +/obj/effect/decal/cleanable/oil/streak, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"tC" = ( +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"uT" = ( +/obj/structure/table/wood, +/obj/item/ammo_casing/shotgun/scatterlaser{ + pixel_y = 6; + pixel_x = 1 + }, +/obj/item/ammo_casing/shotgun/buckshot{ + pixel_y = 4; + pixel_x = 8 + }, +/turf/open/floor/carpet/red, +/area/ruin/syndielab) +"uX" = ( +/obj/structure/flora/bush/ferny{ + pixel_y = 2; + pixel_x = -2 + }, +/obj/machinery/air_sensor{ + chamber_id = "syndielab_biodome" + }, +/turf/open/floor/grass{ + initial_gas_mix = "o2=1000;n2=1100;TEMP=280" + }, +/area/ruin/syndielab) +"vr" = ( +/obj/structure/sign/poster/contraband/revolver/directional/east, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"vE" = ( +/obj/structure/safe, +/obj/item/book/granter/crafting_recipe/donk_secret_recipe, +/obj/item/stack/sheet/mineral/plasma/thirty, +/obj/item/storage/wallet/money{ + desc = "It can hold a few small and personal things." + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"vO" = ( +/obj/machinery/door/airlock/survival_pod{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/structure/fans/tiny, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"wh" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/trash/ready_donk{ + pixel_x = 6 + }, +/obj/structure/sign/poster/contraband/eat/directional/east, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"wj" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"wl" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"wJ" = ( +/obj/structure/rack, +/obj/item/storage/backpack/satchel, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/suit/hooded/explorer/syndicate{ + pixel_x = 8; + pixel_y = -2 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"xa" = ( +/obj/structure/extinguisher_cabinet/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"xg" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"xr" = ( +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security{ + desc = "It opens and closes. Menacingly!"; + name = "Syndicate Airlock" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"yW" = ( +/turf/open/floor/carpet/red, +/area/ruin/syndielab) +"AD" = ( +/obj/structure/bookcase, +/obj/item/book/manual/fish_catalog{ + pixel_x = -3; + pixel_y = -6 + }, +/obj/item/book/manual/nuclear{ + pixel_x = -5; + pixel_y = 1 + }, +/obj/item/book/manual/wiki/cytology{ + pixel_x = 6; + pixel_y = -2 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"AR" = ( +/turf/closed/wall/r_wall/syndicate/nodiagonal{ + desc = "An ominous looking wall. It has extra insulation to keep the heat in."; + name = "plastitanium wall" + }, +/area/ruin/syndielab) +"AX" = ( +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_y = -6; + pixel_x = 4 + }, +/turf/open/floor/carpet/red, +/area/ruin/syndielab) +"Co" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"CS" = ( +/obj/machinery/airalarm/directional/east, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Dd" = ( +/obj/item/storage/bag/trash/filled, +/obj/structure/closet/crate/bin, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"De" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/trash/semki{ + pixel_y = 12 + }, +/obj/item/soap/syndie, +/obj/structure/noticeboard/directional/east, +/obj/item/paper/fluff/junkmail_generic{ + name = "weird note" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"EY" = ( +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security/glass{ + desc = "It opens and closes. Menacingly!"; + name = "Syndicate Airlock" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Fz" = ( +/obj/structure/cable/layer1, +/obj/machinery/power/terminal{ + cable_layer = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"FJ" = ( +/obj/machinery/light/warm/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Gi" = ( +/obj/machinery/navbeacon{ + location = "syndielab_beacon4"; + codes_txt = "patrol;next_patrol=syndielab_beacon1" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"GL" = ( +/obj/structure/chair/office/tactical, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"GV" = ( +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security{ + desc = "It opens and closes. Menacingly!"; + name = "Syndicate Airlock" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Hq" = ( +/obj/item/seeds/lavaland/cactus{ + pixel_x = -8; + pixel_y = 4 + }, +/obj/item/seeds/lavaland/cactus{ + pixel_y = 6; + pixel_x = 8 + }, +/obj/item/seeds/lavaland/fireblossom{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/stack/ore/glass/basalt{ + amount = 50; + pixel_y = -3; + pixel_x = -3 + }, +/obj/structure/closet/crate/secure/cybersun/dawn, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"Hs" = ( +/obj/structure/rack, +/obj/item/storage/bag/trash, +/obj/item/pushbroom, +/obj/item/storage/bag/trash{ + pixel_x = 9; + pixel_y = -3 + }, +/obj/machinery/airalarm/directional/south, +/obj/structure/cable/layer1, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"HH" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/paper/guides/antag/hdd_extraction{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/book/manual/wiki/tcomms{ + pixel_x = 12; + pixel_y = 1 + }, +/obj/structure/sign/poster/contraband/interdyne_gene_clinics/directional/north, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"HS" = ( +/obj/structure/rack, +/obj/item/storage/toolbox/syndicate, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"IQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/mob/living/basic/bot/dedbot, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Jc" = ( +/obj/effect/overloader_trap{ + uses_remaining = 1; + shock_damage = 55; + shock_range = 2; + machine_overload_damage = 160 + }, +/obj/machinery/telecomms/hub, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"JF" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/structure/sign/poster/contraband/hacking_guide/directional/north, +/obj/item/assembly/signaler/cyborg{ + pixel_y = 5; + pixel_x = 6 + }, +/obj/item/assembly/voice{ + pixel_x = -5; + pixel_y = 3 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"Ka" = ( +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security/glass{ + desc = "It opens and closes. Menacingly!"; + name = "Syndicate Airlock" + }, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"KV" = ( +/obj/machinery/computer/atmos_control/noreconnect{ + atmos_chambers = list("syndielab_biodome"="Biodome Atmos"); + dir = 4; + name = "gas tank monitor"; + desc = "This computer connects to and controls the sensors and equipment in a nearby pressurised gas reservoir."; + icon_keyboard = "syndie_key" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Lt" = ( +/obj/item/paper/fluff/operative, +/obj/structure/noticeboard/directional/north, +/obj/structure/cable/layer1, +/obj/item/ammo_casing/shotgun/buckshot/spent{ + pixel_x = 8; + pixel_y = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"MW" = ( +/turf/template_noop, +/area/template_noop) +"NM" = ( +/obj/structure/sign/poster/contraband/donk_co/directional/east, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Qj" = ( +/obj/structure/flora/bush/grassy{ + pixel_x = 15; + pixel_y = 3 + }, +/obj/structure/flora/bush, +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/oxygen_output{ + dir = 1; + chamber_id = "syndielab_biodome" + }, +/turf/open/floor/grass{ + initial_gas_mix = "o2=1000;n2=1100;TEMP=280" + }, +/area/ruin/syndielab) +"QO" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/computer_disk/syndicate/camera_app{ + pixel_y = 4; + pixel_x = -5 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/crowbar/hammer{ + pixel_x = 3; + pixel_y = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"Sq" = ( +/obj/structure/rack, +/obj/item/pinata/donk{ + pixel_y = 10 + }, +/obj/item/storage/box/party_poppers{ + pixel_y = 1; + pixel_x = 7 + }, +/obj/item/storage/box/firecrackers{ + pixel_x = -8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Te" = ( +/obj/machinery/navbeacon{ + location = "syndielab_beacon3"; + codes_txt = "patrol;next_patrol=syndielab_beacon4" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Tl" = ( +/obj/item/stack/tile/carpet/donk/thirty{ + pixel_x = 6; + pixel_y = -5 + }, +/obj/item/toy/plush/donkpocket{ + pixel_x = 12; + pixel_y = 3 + }, +/obj/item/stack/tile/carpet/donk/thirty{ + pixel_x = -6; + pixel_y = -5 + }, +/obj/item/toy/plush/donkpocket{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/stack/package_wrap, +/obj/structure/closet/crate/preopen, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"Ts" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/structure/sign/poster/contraband/c20r/directional/north, +/obj/item/anomaly_releaser{ + pixel_y = 6 + }, +/obj/item/anomaly_releaser, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"TB" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"UF" = ( +/obj/machinery/door/airlock/survival_pod/glass{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/structure/fans/tiny, +/obj/machinery/atmospherics/pipe/smart/manifold4w/dark/hidden, +/obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"UM" = ( +/obj/item/ammo_box/c9mm, +/obj/item/ammo_box/magazine/m9mm, +/obj/structure/closet/crate/secure/gorlex_weapons{ + req_one_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/syndielab) +"Vf" = ( +/obj/effect/decal/cleanable/molten_object, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/item/stack/ore/plasma{ + pixel_x = 7; + pixel_y = 10 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Vu" = ( +/obj/structure/aquarium/donkfish, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"VO" = ( +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Wn" = ( +/obj/machinery/computer/terminal{ + dir = 4; + upperinfo = "ERROR - NO FINGERPRINT MATCH ON FILE!"; + tguitheme = "syndicate"; + desc = "An state-of-the-art lab terminal. The Cybersun Industries logo is imprinted just below the screen."; + content = list("*Solid Matter Analyzer and Research Terminal*"); + name = "lab terminal"; + icon_screen = "tcboss"; + icon_keyboard = "syndie_key" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Wo" = ( +/obj/structure/table/wood, +/obj/item/ammo_casing/shotgun/fletchette{ + pixel_y = 6 + }, +/obj/item/ammo_casing/shotgun/fletchette{ + pixel_x = 8; + pixel_y = 6 + }, +/obj/item/gun/ballistic/shotgun/musket, +/turf/open/floor/carpet/red, +/area/ruin/syndielab) +"WO" = ( +/obj/item/trash/boritos/red{ + pixel_y = -9; + pixel_x = -5 + }, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) +"Xe" = ( +/obj/structure/closet/crate/cardboard, +/obj/item/paint/red{ + pixel_y = 2; + pixel_x = -6 + }, +/obj/item/paint_palette{ + pixel_y = 6; + pixel_x = 8 + }, +/obj/item/mod/paint, +/obj/structure/sign/poster/contraband/energy_swords/directional/south, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Xm" = ( +/obj/structure/closet/crate/secure/trashcart, +/obj/item/relic, +/obj/item/storage/bag/trash/filled{ + pixel_y = 1; + pixel_x = 6 + }, +/obj/item/storage/bag/trash/filled{ + pixel_x = -6; + pixel_y = 1 + }, +/obj/item/storage/bag/trash/filled{ + pixel_y = -1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Xt" = ( +/turf/closed/mineral/snowmountain/icemoon, +/area/icemoon/underground/explored) +"YH" = ( +/obj/item/storage/medkit, +/obj/structure/sign/poster/contraband/free_key/directional/south, +/obj/structure/rack, +/obj/item/stack/medical/suture, +/obj/item/clothing/neck/stethoscope, +/obj/item/reagent_containers/hypospray/medipen/atropine, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Ze" = ( +/obj/machinery/porta_turret/syndicate/energy/cybersun, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"Zx" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/power/smes/magical/cybersun{ + cable_layer = 1; + input_level = 180000; + output_level = 200000; + dir = 1 + }, +/obj/structure/cable/layer1, +/turf/open/floor/mineral/plastitanium, +/area/ruin/syndielab) +"ZW" = ( +/obj/structure/chair/sofa/corp/right, +/mob/living/basic/trooper/syndicate/ranged/shotgun, +/obj/machinery/light/warm/directional/north, +/obj/structure/cable/layer1, +/turf/open/floor/iron/dark/textured, +/area/ruin/syndielab) + +(1,1,1) = {" +MW +MW +MW +MW +Xt +Xt +bx +MW +MW +Xt +MW +MW +MW +MW +MW +MW +"} +(2,1,1) = {" +MW +MW +MW +MW +Xt +AR +AR +vO +AR +Xt +Xt +Xt +Xt +MW +MW +MW +"} +(3,1,1) = {" +MW +MW +Xt +Xt +Xt +AR +cg +xg +AR +AR +cP +AR +Xt +Xt +Xt +MW +"} +(4,1,1) = {" +MW +AR +AR +AR +AR +AR +AR +UF +AR +na +mi +AR +AR +AR +Xt +Xt +"} +(5,1,1) = {" +Xt +AR +aa +Wn +bC +EY +el +el +AR +iQ +iy +vE +Xe +AR +AR +Xt +"} +(6,1,1) = {" +Xt +AR +Ts +sj +FJ +AR +qy +el +AR +AD +ry +ey +VO +Tl +AR +Xt +"} +(7,1,1) = {" +Xt +AR +bn +Vf +xa +AR +Ze +Gi +cu +el +ey +wl +sa +Hq +AR +Xt +"} +(8,1,1) = {" +Xt +AR +AR +AR +EY +AR +qC +qC +AR +tb +HS +ey +sp +UM +AR +Xt +"} +(9,1,1) = {" +Xt +AR +pK +KV +el +nT +Qj +ex +qC +el +Sq +cM +Hs +AR +AR +Xt +"} +(10,1,1) = {" +Xt +AR +JF +sj +el +qC +uX +ci +qC +el +oY +Fz +Zx +AR +Xt +Xt +"} +(11,1,1) = {" +Xt +AR +Jc +oA +FJ +AR +qC +qC +AR +GV +AR +qC +qC +AR +Xt +MW +"} +(12,1,1) = {" +Xt +AR +HH +GL +hl +IQ +rH +rH +xr +Te +hu +TB +lW +AR +Xt +MW +"} +(13,1,1) = {" +Xt +AR +QO +hn +el +Xm +rO +aP +AR +Lt +AX +yW +YH +AR +Xt +MW +"} +(14,1,1) = {" +Xt +AR +AR +AR +EY +qC +qC +qC +AR +ZW +uT +yW +Vu +AR +Xt +MW +"} +(15,1,1) = {" +Xt +Xt +AR +gE +el +wj +dD +Co +AR +cd +Wo +yW +Dd +AR +Xt +MW +"} +(16,1,1) = {" +MW +Xt +AR +sV +NM +tC +tC +tC +Ka +WO +vr +CS +wJ +AR +Xt +MW +"} +(17,1,1) = {" +MW +Xt +AR +AR +AR +nD +wh +De +AR +AR +AR +AR +AR +AR +MW +MW +"} +(18,1,1) = {" +MW +MW +Xt +Xt +AR +AR +AR +AR +AR +Xt +Xt +Xt +Xt +Xt +Xt +MW +"} +(19,1,1) = {" +MW +MW +MW +Xt +Xt +Xt +Xt +Xt +Xt +Xt +MW +MW +MW +MW +MW +MW +"} diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm index cf7817d97b0..7490203ccea 100644 --- a/code/datums/ruins/icemoon.dm +++ b/code/datums/ruins/icemoon.dm @@ -172,6 +172,12 @@ description = "Radio signals are being detected and the source is this completely innocent pile of snow." suffix = "icemoon_underground_comms_agent.dmm" +/datum/map_template/ruin/icemoon/underground/syndie_lab + name = "Ice-Ruin Syndicate Lab" + id = "syndie_lab" + description = "A small laboratory and living space for Syndicate agents." + suffix = "icemoon_underground_syndielab.dmm" + //TODO: Bottom-Level ONLY Spawns after Refactoring Related Code /datum/map_template/ruin/icemoon/underground/plasma_facility name = "Ice-Ruin Abandoned Plasma Facility" diff --git a/code/game/area/areas/ruins/icemoon.dm b/code/game/area/areas/ruins/icemoon.dm index d0049e7007c..061bd8f06d2 100644 --- a/code/game/area/areas/ruins/icemoon.dm +++ b/code/game/area/areas/ruins/icemoon.dm @@ -75,3 +75,7 @@ /area/ruin/powered/hermit name = "\improper Hermit's Cabin" +/area/ruin/syndielab + name = "\improper Syndicate Lab" + ambience_index = AMBIENCE_DANGER + sound_environment = SOUND_ENVIRONMENT_CAVE diff --git a/config/iceruinblacklist.txt b/config/iceruinblacklist.txt index 10960a7b215..87c0296d6fa 100644 --- a/config/iceruinblacklist.txt +++ b/config/iceruinblacklist.txt @@ -33,6 +33,7 @@ _maps/RandomRuins/IceRuins/icemoon_underground_mining_site.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_puzzle.dmm +#_maps/RandomRuins/IceRuins/icemoon_underground_syndielab.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_wrath.dmm ##NOVA From 4e64c00eda5180f364183248f6d6d331b7efc6d0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:58:27 +0000 Subject: [PATCH 031/142] Automatic changelog for PR #86545 [ci skip] --- html/changelogs/AutoChangeLog-pr-86545.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86545.yml diff --git a/html/changelogs/AutoChangeLog-pr-86545.yml b/html/changelogs/AutoChangeLog-pr-86545.yml new file mode 100644 index 00000000000..a31dde644f2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86545.yml @@ -0,0 +1,4 @@ +author: "DaCoolBoss" +delete-after: True +changes: + - rscadd: "Adds the Syndicate Lab to the Icemoon ruin pool." \ No newline at end of file From aa5ac574e6afaf9f67c83c3247d7ff20432e716a Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Sun, 15 Sep 2024 06:38:58 -0400 Subject: [PATCH 032/142] Fixes being able to shout chuunibyou phrases while mute (#86650) ## About The Pull Request Fixes https://github.com/NovaSector/NovaSector/issues/4391 It was an easy fix so why not. This override was in place specifically to allow mimes to use the spell but did not take into consideration the mute trait. Mimes use `TRAIT_MIMING` not `TRAIT_MUTE`, so this should not have any effect on the original intent. ## Why It's Good For The Game Fixes an oversight. ## Changelog :cl: fix: fixes being able to use chuunibyou shouts while mute /:cl: --- code/datums/components/chuunibyou.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/components/chuunibyou.dm b/code/datums/components/chuunibyou.dm index 4e06f0fd474..5724b93488f 100644 --- a/code/datums/components/chuunibyou.dm +++ b/code/datums/components/chuunibyou.dm @@ -64,7 +64,7 @@ /datum/component/chuunibyou/proc/on_try_speech(datum/source, message, ignore_spam, forced) SIGNAL_HANDLER - if(casting_spell) + if(casting_spell && !HAS_TRAIT(src, TRAIT_MUTE)) return COMPONENT_IGNORE_CAN_SPEAK ///signal sent when the parent casts a spell that has a projectile From 0641dc0cd3ba6fc1492f579e18710d5a10ab6185 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 10:42:25 +0000 Subject: [PATCH 033/142] Automatic changelog for PR #86650 [ci skip] --- html/changelogs/AutoChangeLog-pr-86650.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86650.yml diff --git a/html/changelogs/AutoChangeLog-pr-86650.yml b/html/changelogs/AutoChangeLog-pr-86650.yml new file mode 100644 index 00000000000..c74ef214324 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86650.yml @@ -0,0 +1,4 @@ +author: "vinylspiders" +delete-after: True +changes: + - bugfix: "fixes being able to use chuunibyou shouts while mute" \ No newline at end of file From 6634d1729a2035304119ed8a18bdd0a77dd8b1c9 Mon Sep 17 00:00:00 2001 From: Jerry <55355646+Jewelry-x@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:42:36 +0300 Subject: [PATCH 034/142] Fix typo for the description of the heretic's "Lionhunter's Rifle". (#86653) ## About The Pull Request Fixes typos in the heretic's "Lionhunter's Rifle". ## Why It's Good For The Game Improves readability and user experience. ## Changelog :cl: spellcheck: fixed typos on heretic's "Lionhunter's Rifle" /:cl: --- code/modules/antagonists/heretic/knowledge/side_blade_rust.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm index 3a0f17ed483..2bae6ed5402 100644 --- a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm +++ b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm @@ -47,7 +47,7 @@ desc = "Allows you to transmute any ballistic weapon, such as a pipegun, with hide \ from any animal, a plank of wood, and a camera to create the Lionhunter's rifle. \ The Lionhunter's Rifle is a long ranged ballistic weapon with three shots. \ - These shots function as normal, albeit weak high caliber mutitions when fired from \ + These shots function as normal, albeit weak high-caliber munitions when fired from \ close range or at inanimate objects. You can aim the rifle at distant foes, \ causing the shot to deal massively increased damage and hone in on them." gain_text = "I met an old man in an antique shop who wielded a very unusual weapon. \ From b98b8e6d9c0f6d3709e7a521372d77e2e7a50c92 Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Sun, 15 Sep 2024 06:43:38 -0400 Subject: [PATCH 035/142] Tiny fix for phonebooth ruin (#86649) ## About The Pull Request This is just so UpdatePaths doesn't annoyingly keep adding space after the varedits, because it likes to do that when you have a semicolon on a single varedit. ## Changelog Nothing whatsoever player-facing --- _maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm index 532c90f6084..4cbf3478bc2 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm @@ -13,7 +13,7 @@ /area/ruin/powered/lavaland_phone_booth) "k" = ( /obj/machinery/vending/snack/green{ - all_products_free = 0; + all_products_free = 0 }, /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/plating/lavaland_atmos, @@ -66,7 +66,7 @@ /area/ruin/powered/lavaland_phone_booth) "W" = ( /obj/machinery/vending/cigarette{ - all_products_free = 0; + all_products_free = 0 }, /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/plating/lavaland_atmos, From 730a567fd53536a57089fe0b1d0278b3fd413134 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 10:46:25 +0000 Subject: [PATCH 036/142] Automatic changelog for PR #86653 [ci skip] --- html/changelogs/AutoChangeLog-pr-86653.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86653.yml diff --git a/html/changelogs/AutoChangeLog-pr-86653.yml b/html/changelogs/AutoChangeLog-pr-86653.yml new file mode 100644 index 00000000000..8ddb534ab95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86653.yml @@ -0,0 +1,4 @@ +author: "Jewelry-x" +delete-after: True +changes: + - spellcheck: "fixed typos on heretic's \"Lionhunter's Rifle\"" \ No newline at end of file From f959d0df65aa494082f15b892dddd8e68361bb6c Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:13:47 +0200 Subject: [PATCH 037/142] Fish (ya know, from fishing) is now edible (#86110) ## About The Pull Request Fish (the item that you catch with a fishing rod) now has an edible component attached to it, making it possible to eat them if you really have to, at the cost of eventually killing and deleting the fish, however, you normally shouldn't. Along with the seafood and meat foodtypes flags, it possess the gore and raw foodtypes too, making them pretty awful to eat unless you're a (non-vegan) lizard, felinid, or wearing the strange bandana*, which can only be found in the cqc kit case. Furthermore, it carry diseases like the ones from food left on the floors for too long, so a strong stomach is required to safely eat it even if you actually like it, dummy... UNLESS you fry or grill it, thus killing the diseases (as well as the fish) and removing both the gore and raw food types, then it becomes an actually ok meal... UNLESS you're dumb enough to eat a pufferfish, a donkfish or a slimefish. That is more or less the general rule. A few fish stray for it. For example, lavaloops are never raw (still gorey). The skeleton fish are never edibles, and holodeck fish is, well, holographic and thus disappears if you try to eat it. *the strange bandana is a reference to MSG, and this is a reference to the MGS3 fish eating animation. This is WIP btw, I'll have to test it and add some then polish it. ## Why It's Good For The Game Whole unprocessed fish should be technically edible, even if not safe to eat nine times out of ten. Also I kinda need this if I want to add a tasty fishing spot to the kitchen deepfriers. ## Changelog :cl: add: Whole, unprocessed fish is now edible. However it's pretty much reccomended to grill or fry it for over 30 spess seconds before attempting to eat it. fix: germ-covered, dirty food no longer tries to infect you through contact. /:cl: # Conflicts: # code/__DEFINES/food.dm --- code/__DEFINES/dcs/signals/signals_fish.dm | 2 + code/__DEFINES/fish.dm | 7 + code/__DEFINES/food.dm | 11 +- code/__DEFINES/traits/declarations.dm | 8 + code/_globalvars/traits/_traits.dm | 5 + code/_globalvars/traits/admin_tooling.dm | 2 + code/datums/components/food/edible.dm | 25 +- code/datums/components/infective.dm | 128 ++++++---- .../advance/floor_diseases/carpellosis.dm | 2 +- code/datums/elements/consumable_mob.dm | 2 +- code/datums/elements/food/fried_item.dm | 10 +- code/datums/elements/food/grilled_item.dm | 4 +- code/datums/mood_events/food_events.dm | 5 + .../quirks/neutral_quirks/vegetarian.dm | 15 +- code/game/atom/_atom.dm | 4 +- code/game/objects/items/cigarettes.dm | 3 +- code/game/objects/items/food/meatdish.dm | 14 +- .../objects/items/storage/boxes/food_boxes.dm | 2 +- code/game/objects/items/storage/toolbox.dm | 1 + code/modules/fishing/fish/_fish.dm | 234 +++++++++++++++++- code/modules/fishing/fish/fish_traits.dm | 63 +++-- code/modules/fishing/fish/types/air_space.dm | 6 + code/modules/fishing/fish/types/anadromous.dm | 5 + code/modules/fishing/fish/types/freshwater.dm | 15 ++ .../modules/fishing/fish/types/holographic.dm | 4 +- code/modules/fishing/fish/types/mining.dm | 15 ++ code/modules/fishing/fish/types/ruins.dm | 17 ++ code/modules/fishing/fish/types/saltwater.dm | 11 +- code/modules/fishing/fish/types/station.dm | 24 +- code/modules/fishing/fish/types/syndicate.dm | 12 + code/modules/fishing/fish/types/tiziran.dm | 17 ++ code/modules/fishing/fishing_rod.dm | 3 + .../food_and_drinks/machinery/deep_fryer.dm | 2 +- .../food_and_drinks/recipes/soup_mixtures.dm | 2 +- code/modules/hydroponics/grown/onion.dm | 2 +- code/modules/hydroponics/hydroponics.dm | 9 +- code/modules/mob/living/taste.dm | 23 +- .../reagents/chemistry/holder/holder.dm | 30 ++- .../chemistry/reagents/food_reagents.dm | 4 +- .../chemistry/reagents/toxin_reagents.dm | 13 + .../reagents/chemistry/recipes/others.dm | 15 +- .../chemistry/recipes/slime_extracts.dm | 2 +- .../surgery/organs/internal/tongue/_tongue.dm | 2 +- code/modules/unit_tests/fish_unit_tests.dm | 67 ++++- strings/fishing_tips.txt | 10 +- 45 files changed, 694 insertions(+), 163 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index b82f4b4657e..92c65e3b25e 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -22,6 +22,8 @@ #define COMSIG_FISH_LIFE "fish_life" ///From /datum/fish_trait/eat_fish: (predator) #define COMSIG_FISH_EATEN_BY_OTHER_FISH "fish_eaten_by_other_fish" +///From /obj/item/fish/generate_reagents_to_add, which returns a holder when the fish is eaten or composted for example: (list/reagents) +#define COMSIG_GENERATE_REAGENTS_TO_ADD "generate_reagents_to_add" ///From /obj/item/fish/feed: (fed_reagents, fed_reagent_type) #define COMSIG_FISH_FED "fish_on_fed" ///from /obj/item/fish/pet_fish diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index be92fed0466..7f8e8462a98 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -141,6 +141,10 @@ #define FISH_WEIGHT_SLOWDOWN_EXPONENT 0.54 ///Used to calculate the force of the fish by comparing (1 + log(weight/this_define)) and the w_class of the item. #define FISH_WEIGHT_FORCE_DIVISOR 250 +///The multiplier used in the FISH_WEIGHT_BITE_DIVISOR define +#define FISH_WEIGHT_GRIND_TO_BITE_MULT 0.4 +///Used to calculate how many bites a fish can take and therefore the amount of reagents it has. +#define FISH_WEIGHT_BITE_DIVISOR (FISH_GRIND_RESULTS_WEIGHT_DIVISOR * FISH_WEIGHT_GRIND_TO_BITE_MULT) ///The breeding timeout for newly instantiated fish is multiplied by this. #define NEW_FISH_BREEDING_TIMEOUT_MULT 2 @@ -190,6 +194,9 @@ /// The height of the minigame slider. Not in pixels, but minigame units. #define FISHING_MINIGAME_AREA 1000 +///The fish needs to be cooked for at least this long so that it can be safely eaten +#define FISH_SAFE_COOKING_DURATION 30 SECONDS + ///Defines for fish properties from the collect_fish_properties proc #define FISH_PROPERTIES_FAV_BAIT "fav_bait" #define FISH_PROPERTIES_BAD_BAIT "bad_bait" diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 56f0e9d7a92..fc538a5d5da 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -175,13 +175,22 @@ GLOBAL_LIST_INIT(food_buffs, list( #define FOOD_IN_CONTAINER (1<<0) /// Finger food can be eaten while walking / running around #define FOOD_FINGER_FOOD (1<<1) +/// Examining this edible won't show infos on food types, bites and remote tasting etc. +#define FOOD_NO_EXAMINE (1<<2) +/// This food item doesn't track bitecounts, use responsibly. +#define FOOD_NO_BITECOUNT (1<<3) DEFINE_BITFIELD(food_flags, list( "FOOD_FINGER_FOOD" = FOOD_FINGER_FOOD, "FOOD_IN_CONTAINER" = FOOD_IN_CONTAINER, + "FOOD_NO_EXAMINE" = FOOD_NO_EXAMINE, + "FOOD_NO_BITECOUNT" = FOOD_NO_BITECOUNT, )) -#define STOP_SERVING_BREAKFAST (35 MINUTES) // NOVA EDIT - ORIGINAL: 15 MINUTES +///Define for return value of the after_eat callback that will call OnConsume if it hasn't already. +#define FOOD_AFTER_EAT_CONSUME_ANYWAY 2 + +#define STOP_SERVING_BREAKFAST (35 MINUTES) // NOVA EDIT CHANGE - ORIGINAL: #define STOP_SERVING_BREAKFAST (15 MINUTES) #define FOOD_MEAT_HUMAN 50 #define FOOD_MEAT_MUTANT 100 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index c745fada831..b9f733fb5bd 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -221,6 +221,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NO_STAGGER "no_stagger" /// Getting hit by thrown movables won't push you away #define TRAIT_NO_THROW_HITPUSH "no_throw_hitpush" +/// This mob likes to eat fish. Raw, uncut fish. +#define TRAIT_FISH_EATER "fish_eater" ///Added to mob or mind, changes the icons of the fish shown in the minigame UI depending on the possible reward. #define TRAIT_REVEAL_FISH "reveal_fish" ///This trait gets you a list of fishes that can be caught when examining a fishing spot. @@ -742,6 +744,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_T_RAY_VISIBLE "t-ray-visible" /// If this item's been fried #define TRAIT_FOOD_FRIED "food_fried" +/// If this item's been bbq grilled +#define TRAIT_FOOD_BBQ_GRILLED "food_bbq_grilled" /// This is a silver slime created item #define TRAIT_FOOD_SILVER "food_silver" /// If this item's been made by a chef instead of being map-spawned or admin-spawned or such @@ -803,6 +807,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_HAUNTED "haunted" /// An item that, if it has contents, will ignore its contents when scanning for contraband. #define TRAIT_CONTRABAND_BLOCKER "contraband_blocker" +/// For edible items that cannot be composted inside hydro trays +#define TRAIT_UNCOMPOSTABLE "uncompostable" //quirk traits #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" @@ -839,6 +845,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_THROWINGARM "throwing_arm" #define TRAIT_SETTLER "settler" #define TRAIT_STRONG_STOMACH "strong_stomach" +#define TRAIT_VEGETARIAN "trait_vegetarian" /// This mob always lands on their feet when they fall, for better or for worse. #define TRAIT_CATLIKE_GRACE "catlike_grace" @@ -963,6 +970,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_FISH_AMPHIBIOUS "fish_amphibious" ///Trait needed for the lubefish evolution #define TRAIT_FISH_FED_LUBE "fish_fed_lube" +#define TRAIT_FISH_WELL_COOKED "fish_well_cooked" #define TRAIT_FISH_NO_HUNGER "fish_no_hunger" ///It comes from a fish case. Relevant for bounties so far. #define TRAIT_FISH_FROM_CASE "fish_from_case" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index fd046d22d99..2a3b1097844 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -243,6 +243,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FEARLESS" = TRAIT_FEARLESS, "TRAIT_FENCE_CLIMBER" = TRAIT_FENCE_CLIMBER, "TRAIT_FINGERPRINT_PASSTHROUGH" = TRAIT_FINGERPRINT_PASSTHROUGH, + "TRAIT_FISH_EATER" = TRAIT_FISH_EATER, "TRAIT_FIST_MINING" = TRAIT_FIST_MINING, "TRAIT_FIXED_MUTANT_COLORS" = TRAIT_FIXED_MUTANT_COLORS, "TRAIT_FLESH_DESIRE" = TRAIT_FLESH_DESIRE, @@ -529,6 +530,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_USER_SCOPED" = TRAIT_USER_SCOPED, "TRAIT_USES_SKINTONES" = TRAIT_USES_SKINTONES, "TRAIT_VATGROWN" = TRAIT_VATGROWN, + "TRAIT_VEGETARIAN" = TRAIT_VEGETARIAN, "TRAIT_VENTCRAWLER_ALWAYS" = TRAIT_VENTCRAWLER_ALWAYS, "TRAIT_VENTCRAWLER_NUDE" = TRAIT_VENTCRAWLER_NUDE, "TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE, @@ -563,6 +565,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CUSTOM_TAP_SOUND" = TRAIT_CUSTOM_TAP_SOUND, "TRAIT_DANGEROUS_OBJECT" = TRAIT_DANGEROUS_OBJECT, "TRAIT_FISHING_BAIT" = TRAIT_FISHING_BAIT, + "TRAIT_FOOD_BBQ_GRILLED" = TRAIT_FOOD_BBQ_GRILLED, "TRAIT_GERM_SENSITIVE" = TRAIT_GERM_SENSITIVE, "TRAIT_GOOD_QUALITY_BAIT" = TRAIT_GOOD_QUALITY_BAIT, "TRAIT_GREAT_QUALITY_BAIT" = TRAIT_GREAT_QUALITY_BAIT, @@ -583,6 +586,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_T_RAY_VISIBLE" = TRAIT_T_RAY_VISIBLE, "TRAIT_TRANSFORM_ACTIVE" = TRAIT_TRANSFORM_ACTIVE, "TRAIT_UNCATCHABLE" = TRAIT_UNCATCHABLE, + "TRAIT_UNCOMPOSTABLE" = TRAIT_UNCOMPOSTABLE, "TRAIT_UNIQUE_AQUARIUM_CONTENT" = TRAIT_UNIQUE_AQUARIUM_CONTENT, "TRAIT_WIELDED" = TRAIT_WIELDED, ), @@ -625,6 +629,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FISH_STINGER" = TRAIT_FISH_STINGER, "TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE, "TRAIT_RESIST_EMULSIFY" = TRAIT_RESIST_EMULSIFY, + "TRAIT_FISH_WELL_COOKED" = TRAIT_FISH_WELL_COOKED, "TRAIT_YUCKY_FISH" = TRAIT_YUCKY_FISH, ), /obj/item/fishing_rod = list( diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 919099f1a68..67a7417b5e7 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -101,6 +101,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_FAT" = TRAIT_FAT, "TRAIT_FEARLESS" = TRAIT_FEARLESS, "TRAIT_FENCE_CLIMBER" = TRAIT_FENCE_CLIMBER, + "TRAIT_FISH_EATER" = TRAIT_FISH_EATER, "TRAIT_FIST_MINING" = TRAIT_FIST_MINING, "TRAIT_FIXED_MUTANT_COLORS" = TRAIT_FIXED_MUTANT_COLORS, "TRAIT_FLESH_DESIRE" = TRAIT_FLESH_DESIRE, @@ -299,6 +300,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_UNSTABLE" = TRAIT_UNSTABLE, "TRAIT_USED_DNA_VAULT" = TRAIT_USED_DNA_VAULT, "TRAIT_USES_SKINTONES" = TRAIT_USES_SKINTONES, + "TRAIT_VEGETARIAN" = TRAIT_VEGETARIAN, "TRAIT_VENTCRAWLER_ALWAYS" = TRAIT_VENTCRAWLER_ALWAYS, "TRAIT_VENTCRAWLER_NUDE" = TRAIT_VENTCRAWLER_NUDE, "TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE, diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index c034300f982..9e2964273fd 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -40,8 +40,6 @@ Behavior that's still missing from this component that original food items had t var/volume = 50 ///The flavortext for taste (haha get it flavor text) var/list/tastes - ///Whether to tell the examiner that this is edible or not. - var/show_examine = TRUE /datum/component/edible/Initialize( list/initial_reagents, @@ -57,7 +55,6 @@ Behavior that's still missing from this component that original food items had t datum/callback/on_consume, datum/callback/check_liked, reagent_purity = 0.5, - show_examine = TRUE, ) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -73,7 +70,6 @@ Behavior that's still missing from this component that original food items had t src.on_consume = on_consume src.tastes = string_assoc_list(tastes) src.check_liked = check_liked - src.show_examine = show_examine setup_initial_reagents(initial_reagents, reagent_purity) @@ -81,9 +77,9 @@ Behavior that's still missing from this component that original food items had t RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(examine)) RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, PROC_REF(UseByAnimal)) RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, PROC_REF(OnCraft)) - RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(OnProcessed)) - RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added)) RegisterSignal(parent, COMSIG_OOZE_EAT_ATOM, PROC_REF(on_ooze_eat)) + RegisterSignal(parent, COMSIG_FOOD_INGREDIENT_ADDED, PROC_REF(edible_ingredient_added)) + RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, PROC_REF(OnProcessed)) if(isturf(parent)) RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) @@ -216,7 +212,7 @@ Behavior that's still missing from this component that original food items had t SIGNAL_HANDLER var/atom/owner = parent - if(!show_examine) + if(food_flags & FOOD_NO_EXAMINE) return if(foodtypes) var/list/types = bitfield_to_list(foodtypes, FOOD_FLAGS) @@ -316,7 +312,6 @@ Behavior that's still missing from this component that original food items had t SIGNAL_HANDLER var/atom/this_food = parent - for(var/obj/item/food/crafted_part in parts_list) if(!crafted_part.reagents) continue @@ -325,7 +320,7 @@ Behavior that's still missing from this component that original food items had t this_food.reagents.maximum_volume = ROUND_UP(this_food.reagents.maximum_volume) // Just because I like whole numbers for this. - BLACKBOX_LOG_FOOD_MADE(this_food.type) + BLACKBOX_LOG_FOOD_MADE(parent.type) ///Makes sure the thing hasn't been destroyed or fully eaten to prevent eating phantom edibles /datum/component/edible/proc/IsFoodGone(atom/owner, mob/living/feeder) @@ -462,7 +457,7 @@ Behavior that's still missing from this component that original food items had t var/atom/owner = parent - if(!owner?.reagents) + if(!owner.reagents) stack_trace("[eater] failed to bite [owner], because [owner] had no reagents.") return FALSE if(eater.satiety > -200) @@ -479,7 +474,8 @@ Behavior that's still missing from this component that original food items had t if(bitecount == 0) apply_buff(eater) - var/fraction = min(bite_consumption / owner.reagents.total_volume, 1) + var/fraction = 0.3 + fraction = min(bite_consumption / owner.reagents.total_volume, 1) owner.reagents.trans_to(eater, bite_consumption, transferred_by = feeder, methods = INGEST) bitecount++ @@ -489,8 +485,7 @@ Behavior that's still missing from this component that original food items had t On_Consume(eater, feeder) //Invoke our after eat callback if it is valid - if(after_eat) - after_eat.Invoke(eater, feeder, bitecount) + after_eat?.Invoke(eater, feeder, bitecount) //Invoke the eater's stomach's after_eat callback if valid if(iscarbon(eater)) @@ -531,7 +526,7 @@ Behavior that's still missing from this component that original food items had t if(recipe_complexity <= 0) return var/obj/item/food/food = parent - if(!isnull(food.crafted_food_buff)) + if(istype(food) && !isnull(food.crafted_food_buff)) buff = food.crafted_food_buff else buff = pick_weight(GLOB.food_buffs[min(recipe_complexity, FOOD_COMPLEXITY_5)]) @@ -666,7 +661,7 @@ Behavior that's still missing from this component that original food items had t /datum/component/edible/proc/UseByAnimal(datum/source, mob/living/basic/pet/dog/doggy) SIGNAL_HANDLER - if(!isdog(doggy)) + if(!isdog(doggy) || (food_flags & FOOD_NO_BITECOUNT)) //this entirely relies on bitecounts alas return var/atom/food = parent diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm index bc7cc2e6af3..5163ca69dac 100644 --- a/code/datums/components/infective.dm +++ b/code/datums/components/infective.dm @@ -8,43 +8,78 @@ var/weak_infection_chance = 10 -/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in, weak = FALSE) - if(islist(_diseases)) - diseases = _diseases - else - diseases = list(_diseases) +/datum/component/infective/Initialize(list/datum/disease/diseases, expire_in, weak = FALSE, weak_infection_chance = 10) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + if(!islist(diseases)) + diseases = islist(diseases) + + ///Make sure the diseases list is populated with instances of diseases so that it doesn't have to be for each AddComponent call. + for(var/datum/disease/disease as anything in diseases) + if(!disease) //empty entry, remove. + diseases -= disease + if(ispath(disease, /datum/disease)) + var/datum/disease/instance = new disease + diseases -= disease + diseases += instance + else if(!istype(disease)) + stack_trace("found [isdatum(disease) ? "an instance of [disease.type]" : disease] inside the diseases list argument for [type]") + diseases -= disease + + src.diseases = diseases + if(expire_in) expire_time = world.time + expire_in QDEL_IN(src, expire_in) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - is_weak = weak + src.weak_infection_chance = weak_infection_chance + +/datum/component/infective/Destroy() + QDEL_NULL(diseases) + return ..() +/datum/component/infective/RegisterWithParent() if(is_weak && isitem(parent)) RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat)) RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat)) - else - var/static/list/disease_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(try_infect_crossed), - ) - AddComponent(/datum/component/connect_loc_behalf, parent, disease_connections) - - RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean)) - RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, PROC_REF(try_infect_buckle)) - RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(try_infect_collide)) - RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(try_infect_impact_zone)) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(try_infect_attack_zone)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(try_infect_attack)) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(try_infect_equipped)) - RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat)) - RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat)) - if(istype(parent, /obj/item/reagent_containers/cup)) - RegisterSignal(parent, COMSIG_GLASS_DRANK, PROC_REF(try_infect_drink)) - if(isorgan(parent)) - RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion)) + return + var/static/list/disease_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(try_infect_crossed), + ) + AddComponent(/datum/component/connect_loc_behalf, parent, disease_connections) + + RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(clean)) + RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, PROC_REF(try_infect_buckle)) + RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(try_infect_collide)) + RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(try_infect_impact_zone)) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, PROC_REF(try_infect_attack_zone)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(try_infect_attack)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(try_infect_equipped)) + RegisterSignal(parent, COMSIG_FOOD_EATEN, PROC_REF(try_infect_eat)) + RegisterSignal(parent, COMSIG_PILL_CONSUMED, PROC_REF(try_infect_eat)) + if(istype(parent, /obj/item/reagent_containers/cup)) + RegisterSignal(parent, COMSIG_GLASS_DRANK, PROC_REF(try_infect_drink)) + if(isorgan(parent)) + RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_insertion)) + +/datum/component/infective/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list( + COMSIG_FOOD_EATEN, + COMSIG_PILL_CONSUMED, + COMSIG_COMPONENT_CLEAN_ACT, + COMSIG_MOVABLE_BUMP, + COMSIG_MOVABLE_IMPACT_ZONE, + COMSIG_ITEM_ATTACK_ZONE, + COMSIG_ITEM_ATTACK, + COMSIG_ITEM_EQUIPPED, + COMSIG_GLASS_DRANK, + COMSIG_ORGAN_IMPLANTED, + )) + qdel(GetComponent(/datum/component/connect_loc_behalf)) /datum/component/infective/proc/on_organ_insertion(obj/item/organ/target, mob/living/carbon/receiver) SIGNAL_HANDLER @@ -62,16 +97,16 @@ eater.add_mood_event("disgust", /datum/mood_event/disgust/dirty_food) - if(is_weak && !prob(weak_infection_chance)) - return - - for(var/datum/disease/disease in diseases) + for(var/datum/disease/disease as anything in diseases) + if(is_weak && !prob(weak_infection_chance)) + continue if(!disease.has_required_infectious_organ(eater, ORGAN_SLOT_STOMACH)) continue eater.ForceContractDisease(disease) - try_infect(feeder, BODY_ZONE_L_ARM) + if(!is_weak) + try_infect(feeder, BODY_ZONE_L_ARM) /datum/component/infective/proc/try_infect_drink(datum/source, mob/living/drinker, mob/living/feeder) SIGNAL_HANDLER @@ -79,11 +114,14 @@ if(HAS_TRAIT(drinker, TRAIT_STRONG_STOMACH)) return - var/appendage_zone = feeder.held_items.Find(source) - appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM - try_infect(feeder, appendage_zone) + if(!is_weak) + var/appendage_zone = feeder.held_items.Find(source) + appendage_zone = appendage_zone == 0 ? BODY_ZONE_CHEST : (appendage_zone % 2 ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM) + try_infect(feeder, appendage_zone) - for(var/datum/disease/disease in diseases) + for(var/datum/disease/disease as anything in diseases) + if(is_weak && !prob(weak_infection_chance)) + continue if(!disease.has_required_infectious_organ(drinker, ORGAN_SLOT_STOMACH)) continue @@ -163,19 +201,3 @@ /datum/component/infective/proc/try_infect(mob/living/L, target_zone) for(var/V in diseases) L.ContactContractDisease(V, target_zone) - -/datum/component/infective/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, list( - COMSIG_FOOD_EATEN, - COMSIG_PILL_CONSUMED, - COMSIG_COMPONENT_CLEAN_ACT, - COMSIG_MOVABLE_BUMP, - COMSIG_MOVABLE_IMPACT_ZONE, - COMSIG_ITEM_ATTACK_ZONE, - COMSIG_ITEM_ATTACK, - COMSIG_ITEM_EQUIPPED, - COMSIG_GLASS_DRANK, - COMSIG_ORGAN_IMPLANTED, - )) - qdel(GetComponent(/datum/component/connect_loc_behalf)) diff --git a/code/datums/diseases/advance/floor_diseases/carpellosis.dm b/code/datums/diseases/advance/floor_diseases/carpellosis.dm index a0482215494..cdeb6051537 100644 --- a/code/datums/diseases/advance/floor_diseases/carpellosis.dm +++ b/code/datums/diseases/advance/floor_diseases/carpellosis.dm @@ -41,7 +41,7 @@ switch(stage) if(2) - if(SPT_PROB(1, seconds_per_tick) && affected_mob.stat == CONSCIOUS) + if(SPT_PROB(1, seconds_per_tick) && affected_mob.stat == CONSCIOUS && affected_mob.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)) to_chat(affected_mob, span_warning("You want to wag your tail...")) affected_mob.emote("wag") if(3) diff --git a/code/datums/elements/consumable_mob.dm b/code/datums/elements/consumable_mob.dm index 1a7c67a4312..fafdb8cbcab 100644 --- a/code/datums/elements/consumable_mob.dm +++ b/code/datums/elements/consumable_mob.dm @@ -23,7 +23,7 @@ /datum/element/consumable_mob/proc/on_consume(atom/movable/source, mob/living/consumer) SIGNAL_HANDLER - if(!consumer.combat_mode || !consumer.reagents) + if(!consumer.combat_mode || !consumer.reagents || HAS_TRAIT(consumer, TRAIT_PACIFISM)) return for(var/reagent_type in reagents_list) if(isnull(reagents_list[reagent_type])) diff --git a/code/datums/elements/food/fried_item.dm b/code/datums/elements/food/fried_item.dm index 2afab84d1cb..bc21e51f24c 100644 --- a/code/datums/elements/food/fried_item.dm +++ b/code/datums/elements/food/fried_item.dm @@ -17,28 +17,27 @@ var/atom/this_food = target switch(fry_time) - if(0 to 15) + if(0 to 15 SECONDS) this_food.add_atom_colour(fried_colors[1], FIXED_COLOUR_PRIORITY) this_food.name = "lightly-fried [this_food.name]" this_food.desc += " It's been lightly fried in a deep fryer." - if(15 to 50) + if(15 SECONDS to 50 SECONDS) this_food.add_atom_colour(fried_colors[2], FIXED_COLOUR_PRIORITY) this_food.name = "fried [this_food.name]" this_food.desc += " It's been fried, increasing its tastiness value by [rand(1, 75)]%." - if(50 to 85) + if(50 SECONDS to 85 SECONDS) this_food.add_atom_colour(fried_colors[3], FIXED_COLOUR_PRIORITY) this_food.name = "deep-fried [this_food.name]" this_food.desc += " Deep-fried to perfection." - if(85 to INFINITY) + if(85 SECONDS to INFINITY) this_food.add_atom_colour(fried_colors[4], FIXED_COLOUR_PRIORITY) this_food.name = "\proper the physical manifestation of the very concept of fried foods" this_food.desc = "A heavily-fried... something. Who can tell anymore?" ADD_TRAIT(this_food, TRAIT_FOOD_FRIED, ELEMENT_TRAIT(type)) - SEND_SIGNAL(this_food, COMSIG_ITEM_FRIED, fry_time) // Already edible items will inherent these parameters // Otherwise, we will become edible. this_food.AddComponent( \ @@ -49,6 +48,7 @@ foodtypes = FRIED, \ volume = this_food.reagents?.maximum_volume, \ ) + SEND_SIGNAL(this_food, COMSIG_ITEM_FRIED, fry_time) /datum/element/fried_item/Detach(atom/source, ...) for(var/color in fried_colors) diff --git a/code/datums/elements/food/grilled_item.dm b/code/datums/elements/food/grilled_item.dm index 74e772eb73c..6899f47faa4 100644 --- a/code/datums/elements/food/grilled_item.dm +++ b/code/datums/elements/food/grilled_item.dm @@ -28,10 +28,12 @@ if(grill_time > 30 SECONDS && isnull(this_food.GetComponent(/datum/component/edible))) this_food.AddComponent(/datum/component/edible, foodtypes = FRIED) - SEND_SIGNAL(this_food, COMSIG_ITEM_BARBEQUE_GRILLED) + SEND_SIGNAL(this_food, COMSIG_ITEM_BARBEQUE_GRILLED, grill_time) + ADD_TRAIT(this_food, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type)) /datum/element/grilled_item/Detach(atom/source, ...) source.name = initial(source.name) source.desc = initial(source.desc) qdel(source.GetComponent(/datum/component/edible)) // Don't care if it was initially edible + REMOVE_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED, ELEMENT_TRAIT(type)) return ..() diff --git a/code/datums/mood_events/food_events.dm b/code/datums/mood_events/food_events.dm index 7d33e7e57ce..e64d975902e 100644 --- a/code/datums/mood_events/food_events.dm +++ b/code/datums/mood_events/food_events.dm @@ -49,3 +49,8 @@ /datum/mood_event/food/top quality = FOOD_QUALITY_TOP + +/datum/mood_event/pacifist_eating_fish_item + description = "I shouldn't be eating living creatures..." + mood_change = -1 //The disgusting food moodlet already has a pretty big negative value, this is just for context. + timeout = 4 MINUTES diff --git a/code/datums/quirks/neutral_quirks/vegetarian.dm b/code/datums/quirks/neutral_quirks/vegetarian.dm index 0ade72acafe..0568e2f1e22 100644 --- a/code/datums/quirks/neutral_quirks/vegetarian.dm +++ b/code/datums/quirks/neutral_quirks/vegetarian.dm @@ -7,17 +7,4 @@ lose_text = span_notice("You feel like eating meat isn't that bad.") medical_record_text = "Patient reports a vegetarian diet." mail_goodies = list(/obj/effect/spawner/random/food_or_drink/salad) - -/datum/quirk/vegetarian/add(client/client_source) - var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE) - if(!tongue) - return - tongue.liked_foodtypes &= ~MEAT - tongue.disliked_foodtypes |= MEAT - -/datum/quirk/vegetarian/remove() - var/obj/item/organ/internal/tongue/tongue = quirk_holder.get_organ_slot(ORGAN_SLOT_TONGUE) - if(!tongue) - return - tongue.liked_foodtypes = initial(tongue.liked_foodtypes) - tongue.disliked_foodtypes = initial(tongue.disliked_foodtypes) + mob_trait = TRAIT_VEGETARIAN diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 4ab67c23253..57d5db329af 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -690,10 +690,10 @@ created_atoms.Add(created_atom) to_chat(user, span_notice("You manage to create [amount_to_create] [initial(atom_to_create.gender) == PLURAL ? "[initial(atom_to_create.name)]" : "[initial(atom_to_create.name)][plural_s(initial(atom_to_create.name))]"] from [src].")) SEND_SIGNAL(src, COMSIG_ATOM_PROCESSED, user, process_item, created_atoms) - UsedforProcessing(user, process_item, chosen_option) + UsedforProcessing(user, process_item, chosen_option, created_atoms) return -/atom/proc/UsedforProcessing(mob/living/user, obj/item/used_item, list/chosen_option) +/atom/proc/UsedforProcessing(mob/living/user, obj/item/used_item, list/chosen_option, list/created_atoms) qdel(src) return diff --git a/code/game/objects/items/cigarettes.dm b/code/game/objects/items/cigarettes.dm index 7484765b625..d55bd12bd50 100644 --- a/code/game/objects/items/cigarettes.dm +++ b/code/game/objects/items/cigarettes.dm @@ -203,7 +203,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM // "It is called a cigarette" AddComponent(/datum/component/edible,\ initial_reagents = list_reagents,\ - food_flags = null,\ + food_flags = FOOD_NO_EXAMINE,\ foodtypes = JUNKFOOD,\ volume = 50,\ eat_time = 0 SECONDS,\ @@ -213,7 +213,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM junkiness = 0,\ reagent_purity = null,\ on_consume = CALLBACK(src, PROC_REF(on_consume)),\ - show_examine = FALSE, \ ) /obj/item/cigarette/Destroy() diff --git a/code/game/objects/items/food/meatdish.dm b/code/game/objects/items/food/meatdish.dm index 5ad5cea20fa..a619be72062 100644 --- a/code/game/objects/items/food/meatdish.dm +++ b/code/game/objects/items/food/meatdish.dm @@ -57,7 +57,7 @@ food_reagents = list( /datum/reagent/consumable/nutriment/protein = 4, /datum/reagent/consumable/nutriment/vitamin = 3, - /datum/reagent/consumable/nutriment/fat/oil = 2, + /datum/reagent/consumable/nutriment/fat = 2, ) bite_consumption = 4.5 crafting_complexity = FOOD_COMPLEXITY_1 @@ -99,14 +99,20 @@ /obj/item/food/fishmeat/gunner_jellyfish name = "filleted gunner jellyfish" - desc = "A gunner jellyfish with the stingers removed. Mildly hallucinogenic." + desc = "A gunner jellyfish with the stingers removed. Mildly hallucinogenic when raw." icon = 'icons/obj/food/lizard.dmi' icon_state = "jellyfish_fillet" food_reagents = list( - /datum/reagent/consumable/nutriment/protein = 4, - /datum/reagent/toxin/mindbreaker = 2, + /datum/reagent/consumable/nutriment/protein = 4, //The halluginogen comes from the fish trait. ) +///Premade gunner jellyfish fillets from supply orders. Contains the halluginogen that'd be normally from the fish trait. +/obj/item/food/fishmeat/gunner_jellyfish/supply + +/obj/item/food/fishmeat/gunner_jellyfish/supply/Initialize(mapload) + food_reagents[/datum/reagent/toxin/mindbreaker/fish] = 2 + return ..() + /obj/item/food/fishmeat/armorfish name = "cleaned armorfish" desc = "An armorfish with its guts and shell removed, ready for use in cooking." diff --git a/code/game/objects/items/storage/boxes/food_boxes.dm b/code/game/objects/items/storage/boxes/food_boxes.dm index 86d59123c72..bac558ce3be 100644 --- a/code/game/objects/items/storage/boxes/food_boxes.dm +++ b/code/game/objects/items/storage/boxes/food_boxes.dm @@ -301,7 +301,7 @@ new /obj/item/food/fishmeat/armorfish(src) new /obj/item/food/fishmeat/carp(src) new /obj/item/food/fishmeat/moonfish(src) - new /obj/item/food/fishmeat/gunner_jellyfish(src) + new /obj/item/food/fishmeat/gunner_jellyfish/supply(src) /obj/item/storage/box/ingredients/salads theme_name = "salads" diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 6b6810c7aa3..a40da40358e 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -412,6 +412,7 @@ desc = "A bandana. It seems to have a little carp embroidered on the inside, as well as the kanji '魚'." icon_state = "snake_eater" inhand_icon_state = null + clothing_traits = list(TRAIT_FISH_EATER) /obj/item/clothing/head/costume/knight name = "fake medieval helmet" diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 7c964d3e50f..12a2ad2d448 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -20,8 +20,6 @@ drop_sound = 'sound/creatures/fish/fish_drop1.ogg' pickup_sound = SFX_FISH_PICKUP sound_vary = TRUE - ///The grind results of the fish. They scale with the weight of the fish. - grind_results = list(/datum/reagent/blood = 5, /datum/reagent/consumable/liquidgibs = 5) obj_flags = UNIQUE_RENAME item_flags = IMMUTABLE_SLOW|SLOWS_WHILE_IN_HAND @@ -150,6 +148,14 @@ ///have we recently pet this fish var/recently_petted = FALSE + /** + * If you wonder why this isn't being tracked by the edible component instead: + * We reset the this value when revived, and slowly chip it away as we heal. + * Of course, it would be daunting to get this to be handled by the edible component + * given its complexity. + */ + var/bites_amount = 0 + /obj/item/fish/Initialize(mapload, apply_qualities = TRUE) . = ..() //It's important that we register the signals before the component is attached. @@ -163,6 +169,7 @@ RegisterSignal(src, COMSIG_ATOM_TEMPORARY_ANIMATION_START, PROC_REF(on_temp_animation)) check_environment() if(status != FISH_DEAD) + ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, REF(src)) //Composting a food that is not real food wouldn't work anyway. START_PROCESSING(SSobj, src) //stops new fish from being able to reproduce right away. @@ -175,6 +182,174 @@ register_evolutions() +///Main proc that makes the fish edible. +/obj/item/fish/proc/make_edible() + var/foodtypes = get_food_types() + if(foodtypes & RAW) + AddComponent(/datum/component/infective, GLOB.floor_diseases.Copy(), weak = TRUE, weak_infection_chance = PERFORM_ALL_TESTS(edible_fish) ? 100 : 15) + else + AddComponent(/datum/component/germ_sensitive) + var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR + create_reagents(INFINITY) //We'll set this to the total volume of the reagents right after generate_fish_reagents() is over + generate_fish_reagents(bites_to_finish) + reagents.maximum_volume = round(reagents.total_volume * 1.25) //make some meager space for condiments. + AddComponent(/datum/component/edible, \ + food_flags = FOOD_NO_EXAMINE|FOOD_NO_BITECOUNT, \ + foodtypes = foodtypes, \ + volume = reagents.total_volume, \ + eat_time = 1.5 SECONDS, \ + bite_consumption = reagents.total_volume / bites_to_finish, \ + after_eat = CALLBACK(src, PROC_REF(after_eat)), \ + check_liked = CALLBACK(src, PROC_REF(check_liked)), \ + reagent_purity = 1, \ + ) + RegisterSignals(src, list(COMSIG_ITEM_FRIED, COMSIG_ITEM_BARBEQUE_GRILLED), PROC_REF(on_fish_cooked)) + +///A proc that returns the food types the edible component has when initialized. +/obj/item/fish/proc/get_food_types() + return SEAFOOD|MEAT|RAW|GORE + +///Kill the fish, remove the raw and gore food types, and the infectiveness too if not under-cooked. +/obj/item/fish/proc/on_fish_cooked(datum/source, cooking_time) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + adjust_health(0) + + //Remove the blood from the reagents holder and reward the player with some extra nutriment added to the fish. + var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE) + var/datum/reagent/blood/blood = reagents.has_reagent(/datum/reagent/blood) + var/old_blood_volume = blood?.volume + reagents.del_reagent(/datum/reagent/blood) + + ///Make space for the additional nutriment + var/volume_mult = 1 + if(bites_amount) + var/initial_bites_left = weight / FISH_WEIGHT_BITE_DIVISOR + var/bites_left = initial_bites_left - bites_amount + volume_mult = initial_bites_left / bites_left + adjust_reagents_capacity((protein?.volume - old_blood_volume) * volume_mult) + + ///Add the extra nutriment + if(protein) + reagents.multiply_single_reagent(/datum/reagent/consumable/nutriment/protein, 2) + + var/datum/component/edible/edible = GetComponent(/datum/component/edible) + edible.foodtypes &= ~(RAW|GORE) + if(cooking_time >= FISH_SAFE_COOKING_DURATION) + well_cooked() + + ///override the signals so they don't mess with blood and proteins again. + RegisterSignals(src, list(COMSIG_ITEM_FRIED, COMSIG_ITEM_BARBEQUE_GRILLED), PROC_REF(on_fish_cooked_again), TRUE) + +///Just kill the fish, again, and perhaps remove the infective comp. +/obj/item/fish/proc/on_fish_cooked_again(datum/source, cooking_time) + SIGNAL_HANDLER + adjust_health(0) + if(cooking_time >= FISH_SAFE_COOKING_DURATION) + well_cooked() + +///The fish is well cooked. Change how the fish tastes, remove the infective comp and add the relative trait. +/obj/item/fish/proc/well_cooked() + qdel(GetComponent(/datum/component/infective)) + AddComponent(/datum/component/germ_sensitive) + ADD_TRAIT(src, TRAIT_FISH_WELL_COOKED, INNATE_TRAIT) + var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE) + if(protein) + protein.data = get_fish_taste_cooked() + +///Checks if the fish is liked or not when eaten by a human. +/obj/item/fish/proc/check_liked(mob/living/eater) + if(HAS_TRAIT(eater, TRAIT_PACIFISM) && (status == FISH_ALIVE ||HAS_MIND_TRAIT(eater, TRAIT_NAIVE))) + eater.add_mood_event("eating_fish", /datum/mood_event/pacifist_eating_fish_item) + return FOOD_TOXIC + if(HAS_TRAIT(eater, TRAIT_AGEUSIA)) + return + if(HAS_TRAIT(eater, TRAIT_FISH_EATER) && !HAS_TRAIT(eater, TRAIT_VEGETARIAN)) + return FOOD_LIKED + +/** + * Fish is not a reagent holder yet it's edible, so it doen't behave like most other snacks + * which means it has its own way of handling being bitten, which is defined here. + */ +/obj/item/fish/proc/after_eat(mob/living/eater, mob/living/feeder) + SHOULD_CALL_PARENT(TRUE) + if(!reagents.total_volume) + return + bites_amount++ + var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR + adjust_health(health - (initial(health) / bites_to_finish) * 3) + 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) + throw_at(target_turf) + +///A proc that returns a static reagent holder with a set reagents that you'd get when eating this fish. +/obj/item/fish/proc/generate_fish_reagents(multiplier = 1) + SHOULD_NOT_OVERRIDE(TRUE) + var/list/reagents_to_add = get_base_edible_reagents_to_add() + SEND_SIGNAL(src, COMSIG_GENERATE_REAGENTS_TO_ADD, reagents_to_add) + if(multiplier != 1) + for(var/reagent in reagents_to_add) + reagents_to_add[reagent] *= multiplier + reagents.add_reagent_list(reagents_to_add, added_purity = 1) + var/datum/reagent/consumable/nutriment/protein/protein = reagents.has_reagent(/datum/reagent/consumable/nutriment/protein, check_subtypes = TRUE) + if(protein) + protein.data = HAS_TRAIT(src, TRAIT_FISH_WELL_COOKED) ? get_fish_taste_cooked() : get_fish_taste() + +/obj/item/fish/proc/get_fish_taste() + return list("raw fish" = 2.5, "scales" = 1) + +/obj/item/fish/proc/get_fish_taste_cooked() + return list("cooked fish" = 2) + +///The proc that adds in the main reagents this fish has when eaten (without accounting for traits) +/obj/item/fish/proc/get_base_edible_reagents_to_add() + var/return_list = list( + /datum/reagent/consumable/nutriment/protein = 2, + /datum/reagent/blood = 1, + ) + //It has been at the very least under-cooked. + if(HAS_TRAIT(src, TRAIT_FOOD_FRIED) || HAS_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED)) + return_list[/datum/reagent/consumable/nutriment/protein] *= 2 + return_list -= /datum/reagent/blood + if(required_fluid_type == AQUARIUM_FLUID_SALTWATER) + return_list[/datum/reagent/consumable/salt] = 0.4 + return return_list + +///adjusts the maximum volume of the fish reagents holder and update the amount of food to bite +/obj/item/fish/proc/adjust_reagents_capacity(amount_to_add) + if(!reagents) + return + reagents.maximum_volume += amount_to_add + var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR + ///updates how many units of reagent one bite takes if edible. + if(IS_EDIBLE(src)) + AddComponent(/datum/component/edible, bite_consumption = reagents.maximum_volume / bites_to_finish) + +///Grinding a fish replaces some the protein it has with blood and gibs. You ain't getting a clean smoothie out of it. +/obj/item/fish/on_grind() + . = ..() + if(!reagents) + return + reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/consumable/liquidgibs, 0.4, include_source_subtypes = TRUE) + reagents.convert_reagent(/datum/reagent/consumable/nutriment/protein, /datum/reagent/blood, 0.2, include_source_subtypes = TRUE) + +///When processed, the reagents inside this fish will be passed to the created atoms. +/obj/item/fish/UsedforProcessing(mob/living/user, obj/item/used_item, list/chosen_option, list/created_atoms) + var/created_len = length(created_atoms) + for(var/atom/movable/created as anything in created_atoms) + if(!created.reagents) + continue + for(var/datum/reagent/reagent as anything in reagents.reagent_list) + var/transfer_vol = reagent.volume / created_len + var/datum/reagent/result_reagent = created.reagents.has_reagent(reagent.type) + if(!result_reagent) + created.reagents.add_reagent(reagent.type, transfer_vol, reagents.copy_data(reagent), reagents.chem_temp, reagent.purity, reagent.ph, no_react = TRUE) + continue + var/multiplier = transfer_vol / result_reagent.volume + created.reagents.multiply_single_reagent(reagent.type, multiplier) + return ..() + /obj/item/fish/update_icon_state() if(status == FISH_DEAD && icon_state_dead) icon_state = icon_state_dead @@ -214,6 +389,8 @@ . += span_notice("It weighs [weight] g.") if(HAS_TRAIT(src, TRAIT_FISHING_BAIT)) . += span_smallnoticeital("It can be used as a fishing bait.") + if(bites_amount) + . += span_warning("It's been bitten by someone.") ///Randomizes weight and size. /obj/item/fish/proc/randomize_size_and_weight(base_size = average_size, base_weight = average_weight, deviation = weight_size_deviation) @@ -272,11 +449,32 @@ num_fillets = amount AddElement(/datum/element/processable, TOOL_KNIFE, fillet_type, num_fillets, 0.5 SECONDS * num_fillets, screentip_verb = "Cut") + var/make_edible = TRUE if(weight) for(var/reagent_type in grind_results) grind_results[reagent_type] /= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1) + if(reagents) //This fish has reagents. Adjust the maximum volume of the reagent holder and do some math to adjut the reagents too. + var/new_weight_ratio = new_weight / weight + var/volume_diff = reagents.maximum_volume * new_weight_ratio - reagents.maximum_volume + if(new_weight_ratio > weight) + adjust_reagents_capacity(volume_diff) + ///As always, we want to maintain proportions here, so we need to get the ratio of bites left and initial bites left. + var/weight_diff = new_weight - weight + var/multiplier = weight_diff / FISH_WEIGHT_BITE_DIVISOR + var/initial_bites_left = weight / FISH_WEIGHT_BITE_DIVISOR + var/bites_left = initial_bites_left - bites_amount + var/amount_to_gen = bites_left / initial_bites_left * multiplier + generate_fish_reagents(amount_to_gen) + else + reagents.multiply_reagents(new_weight_ratio) + adjust_reagents_capacity(volume_diff) + make_edible = FALSE + weight = new_weight + if(make_edible) + make_edible() + if(weight >= FISH_WEIGHT_SLOWDOWN) slowdown = round(((weight/FISH_WEIGHT_SLOWDOWN_DIVISOR)**FISH_WEIGHT_SLOWDOWN_EXPONENT)-1.3, 0.1) drag_slowdown = round(slowdown * 0.5, 1) @@ -492,12 +690,15 @@ if(FISH_ALIVE) status = FISH_ALIVE health = initial(health) // since the fishe has been revived + regenerate_bites(bites_amount) last_feeding = world.time //reset hunger check_environment() START_PROCESSING(SSobj, src) + ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT) if(FISH_DEAD) status = FISH_DEAD STOP_PROCESSING(SSobj, src) + REMOVE_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT) stop_flopping() if(!silent) var/message = span_notice(replacetext(death_text, "%SRC", "[src]")) @@ -652,10 +853,28 @@ health_change_per_second += 0.5 //Slowly healing adjust_health(health + health_change_per_second * seconds_per_tick) -/obj/item/fish/proc/adjust_health(amt) - health = clamp(amt, 0, initial(health)) +/obj/item/fish/proc/adjust_health(amount) + if(status == FISH_DEAD || amount == health) + return + var/pre_health = health + var/initial_health = initial(health) + health = clamp(amount, 0, initial_health) if(health <= 0) set_status(FISH_DEAD) + return + if(amount < pre_health || !bites_amount) + return + var/health_to_pre_health_diff = amount - pre_health + var/init_health_to_pre_diff = initial_health - pre_health + var/bites_to_recover = bites_amount * (health_to_pre_health_diff / init_health_to_pre_diff) + regenerate_bites(bites_to_recover) + +/obj/item/fish/proc/regenerate_bites(amount) + amount = min(amount, bites_amount) + if(amount <= 0) + return + bites_amount -= amount + generate_fish_reagents(amount) /obj/item/fish/proc/ready_to_reproduce(being_targeted = FALSE) var/obj/structure/aquarium/aquarium = loc @@ -845,6 +1064,7 @@ if(HAS_TRAIT(src, TRAIT_FISH_FROM_CASE)) //Avoid printing money by simply ordering fish and sending it back. calculated_price *= 0.05 return round(calculated_price) + /obj/item/fish/proc/get_happiness_value() var/happiness_value = 0 if(recently_petted) @@ -858,7 +1078,11 @@ happiness_value++ if(ISINRANGE(aquarium.fluid_temp, required_temperature_min, required_temperature_max)) happiness_value++ - return happiness_value + if(bites_amount) // ouch + happiness_value -= 2 + if(health < initial(health) * 0.6) + happiness_value -= 1 + return clamp(happiness_value, FISH_SAD, FISH_VERY_HAPPY) /obj/item/fish/proc/pet_fish(mob/living/user) if(recently_petted) diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index c289e1d8907..8c96df6e4ac 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -37,7 +37,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) var/list/fish_whitelist /// Depending on the value, fish with trait will be reported as more or less difficult in the catalog. var/added_difficulty = 0 - /// Reagents added to the fish when gained + /// Reagents to add to the fish whenever the COMSIG_GENERATE_REAGENTS_TO_ADD signal is sent. Their values will be multiplied later. var/list/reagents_to_add /// Difficulty modifier from this mod, needs to return a list with two values @@ -57,10 +57,8 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /// Applies some special qualities to the fish that has been spawned /datum/fish_trait/proc/apply_to_fish(obj/item/fish/fish) SHOULD_CALL_PARENT(TRUE) - if(reagents_to_add) - for(var/reagent in reagents_to_add) - add_to_reagents(fish, reagent, reagents_to_add[reagent]) - RegisterSignal(fish, COMSIG_ATOM_PROCESSED, PROC_REF(process_reagents)) + if(length(reagents_to_add)) + RegisterSignal(fish, COMSIG_GENERATE_REAGENTS_TO_ADD, PROC_REF(add_reagents)) /// Applies some special qualities to basic mobs generated by fish (i.e. chasm chrab --> young lobstrosity --> lobstrosity). /datum/fish_trait/proc/apply_to_mob(mob/living/basic/mob) @@ -79,25 +77,15 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) SEND_SIGNAL(prey, COMSIG_FISH_EATEN_BY_OTHER_FISH, predator) qdel(prey) -/// Proc that inserts a reagent to the grind_results list of the fish. You'll still have to set the processed comsig proc yourself. -/datum/fish_trait/proc/add_to_reagents(obj/item/fish/fish, reagent_type, amount) - LAZYINITLIST(fish.grind_results) - fish.grind_results.Insert(1, reagent_type) - fish.grind_results[reagent_type] = amount -/// Proc that handles adding reagents from the trait to the fillets from butchered fish. -/datum/fish_trait/proc/process_reagents(obj/item/fish/source, mob/living/user, obj/item/process_item, list/results) +/** + * Signal sent when we need to generate an abstract holder containing + * reagents to be transfered, usually as a result of the fish being eaten by someone + */ +/datum/fish_trait/proc/add_reagents(obj/item/fish/fish, list/reagents) SIGNAL_HANDLER - var/results_with_reagents = 0 - for(var/atom/result as anything in results) - if(result.reagents) - results_with_reagents++ - if(!results_with_reagents) - return for(var/reagent in reagents_to_add) - var/amount = round(source.grind_results[reagent] / results_with_reagents, 0.1) - for(var/atom/result as anything in results) - result.reagents?.add_reagent(reagent, amount) + reagents[reagent] += reagents_to_add[reagent] /// Proc that adds or changes the venomous when the fish size and/or weight are updated /datum/fish_trait/proc/add_venom(obj/item/fish/source, venom_path, new_weight, mult = 0.25) @@ -413,7 +401,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/yucky name = "Yucky" catalog_description = "This fish tastes so repulsive, other fishes won't try to eat it." - reagents_to_add = list(/datum/reagent/yuck = 3) + reagents_to_add = list(/datum/reagent/yuck = 1.2) /datum/fish_trait/yucky/apply_to_fish(obj/item/fish/fish) . = ..() @@ -423,7 +411,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) name = "Toxic" catalog_description = "This fish contains toxins. Feeding it to predatory fishes or people is not recommended." diff_traits_inheritability = 25 - reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 2.5) + reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 1) /datum/fish_trait/toxic/apply_to_fish(obj/item/fish/fish) . = ..() @@ -512,6 +500,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) spontaneous_manifest_types = list(/obj/item/fish/clownfish/lube = 100) catalog_description = "This fish exudes a viscous, slippery lubrificant. It's recommended not to step on it." added_difficulty = 5 + reagents_to_add = list(/datum/reagent/lube = 1.2) /datum/fish_trait/lubed/apply_to_fish(obj/item/fish/fish) . = ..() @@ -597,11 +586,30 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) inheritability = 60 diff_traits_inheritability = 30 catalog_description = "This fish is electroreceptive, and will generate electric fields. Can be harnessed inside a bioelectric generator." + reagents_to_add = list(/datum/reagent/consumable/liquidelectricity = 1.5) /datum/fish_trait/electrogenesis/apply_to_fish(obj/item/fish/fish) . = ..() ADD_TRAIT(fish, TRAIT_FISH_ELECTROGENESIS, FISH_TRAIT_DATUM) RegisterSignal(fish, COMSIG_FISH_FORCE_UPDATED, PROC_REF(on_force_updated)) + RegisterSignals(fish, list(COMSIG_ITEM_FRIED, TRAIT_FOOD_BBQ_GRILLED), PROC_REF(on_fish_cooked)) + +/datum/fish_trait/electrogenesis/proc/on_fish_cooked(obj/item/fish/fish, cooked_time) + SIGNAL_HANDLER + if(cooked_time >= FISH_SAFE_COOKING_DURATION) + fish.reagents.del_reagent(/datum/reagent/consumable/liquidelectricity) + else + fish.reagents.multiply_single_reagent(/datum/reagent/consumable/liquidelectricity, 0.66) + +/datum/fish_trait/electrogenesis/add_reagents(obj/item/fish/fish, list/reagents) + . = ..() + if(HAS_TRAIT(fish, TRAIT_FISH_WELL_COOKED)) // Cooking it well removes all liquid electricity + reagents -= /datum/reagent/consumable/liquidelectricity + else + reagents -= /datum/reagent/blood + //Otherwise, undercooking it will remove 2/3 of it. + if(!HAS_TRAIT(fish, TRAIT_FOOD_FRIED) && !HAS_TRAIT(fish, TRAIT_FOOD_BBQ_GRILLED)) + reagents[/datum/reagent/consumable/liquidelectricity] -= 1 /datum/fish_trait/electrogenesis/proc/on_force_updated(obj/item/fish/fish, weight_rank, bonus_or_malus) SIGNAL_HANDLER @@ -670,6 +678,15 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) return change_venom_on_death(source, /datum/reagent/toxin/venom, 0.7, 0.3) +/datum/fish_trait/hallucinogenic + name = "Hallucinogenic" + catalog_description = "This fish is coated with hallucinogenic neurotoxin. We advise cooking it before consumption." + reagents_to_add = list(/datum/reagent/toxin/mindbreaker/fish = 1) + +/datum/fish_trait/hallucinogenic/add_reagents(obj/item/fish/fish, list/reagents) + if(!HAS_TRAIT(src, TRAIT_FOOD_FRIED) && !HAS_TRAIT(src, TRAIT_FOOD_BBQ_GRILLED)) + return ..() + /datum/fish_trait/ink name = "Ink Production" catalog_description = "This fish possess a sac that produces ink." diff --git a/code/modules/fishing/fish/types/air_space.dm b/code/modules/fishing/fish/types/air_space.dm index f3b985edfa7..dda3794ff4e 100644 --- a/code/modules/fishing/fish/types/air_space.dm +++ b/code/modules/fishing/fish/types/air_space.dm @@ -40,6 +40,12 @@ ), ) +/obj/item/fish/sand_crab/get_fish_taste() + return list("raw crab" = 2) + +/obj/item/fish/sand_crab/get_fish_taste_cooked() + return list("cooked crab" = 2) + /obj/item/fish/bumpy name = "bump-fish" desc = "An misshapen fish-thing all covered in stubby little tendrils" diff --git a/code/modules/fishing/fish/types/anadromous.dm b/code/modules/fishing/fish/types/anadromous.dm index ecdbda1fde7..4edbce5d0c3 100644 --- a/code/modules/fishing/fish/types/anadromous.dm +++ b/code/modules/fishing/fish/types/anadromous.dm @@ -11,6 +11,11 @@ fillet_type = /obj/item/food/fishmeat/salmon beauty = FISH_BEAUTY_GOOD +/obj/item/fish/sockeye_salmon/get_base_edible_reagents_to_add() + var/return_list = ..() + return_list[/datum/reagent/consumable/nutriment/fat] = 1 + return return_list + /obj/item/fish/arctic_char name = "arctic char" desc = "A cold-water anadromous fish widespread around the Northern Hemisphere of Earth, yet it has somehow found a way here." diff --git a/code/modules/fishing/fish/types/freshwater.dm b/code/modules/fishing/fish/types/freshwater.dm index 4da73c94dd9..b5891e19fb9 100644 --- a/code/modules/fishing/fish/types/freshwater.dm +++ b/code/modules/fishing/fish/types/freshwater.dm @@ -31,6 +31,9 @@ compatible_types = list(/obj/item/fish/goldfish, /obj/item/fish/goldfish/three_eyes) fish_traits = list(/datum/fish_trait/recessive) +/obj/item/fish/goldfish/gill/get_fish_taste() + return list("raw fish" = 2.5, "objection" = 1) + /obj/item/fish/goldfish/three_eyes name = "three-eyed goldfish" desc = "A goldfish with an extra half a pair of eyes. You wonder what it's been feeding on lately..." @@ -50,6 +53,9 @@ ), ) +/obj/item/fish/goldfish/three_eyes/get_fish_taste() + return list("raw fish" = 2.5, "chemical waste" = 0.5) + /obj/item/fish/goldfish/three_eyes/gill name = "McGill" desc = "A great rubber duck tool for Lawyers who can't get a grasp over their case. It looks kinda different today..." @@ -59,6 +65,9 @@ stable_population = 1 random_case_rarity = FISH_RARITY_NOPE +/obj/item/fish/goldfish/three_eyes/gill/get_fish_taste() + return list("raw fish" = 2.5, "objection" = 1) + /obj/item/fish/angelfish name = "angelfish" desc = "Young Angelfish often live in groups, while adults prefer solitary life. They become territorial and aggressive toward other fish when they reach adulthood." @@ -142,6 +151,9 @@ electrogenesis_power = 6.7 MEGA JOULES beauty = FISH_BEAUTY_GOOD +/obj/item/fish/zipzap/get_fish_taste() + return list("raw fish" = 2, "anxiety" = 1) + /obj/item/fish/tadpole name = "tadpole" desc = "The larval spawn of an amphibian. A very minuscle, round creature with a long tail it uses to swim around." @@ -167,6 +179,9 @@ RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks)) RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth)) +/obj/item/fish/tadpole/make_edible() + return + /obj/item/fish/tadpole/set_status(new_status, silent = FALSE) . = ..() if(status == FISH_DEAD) diff --git a/code/modules/fishing/fish/types/holographic.dm b/code/modules/fishing/fish/types/holographic.dm index dfcdbeedb6b..159334002bc 100644 --- a/code/modules/fishing/fish/types/holographic.dm +++ b/code/modules/fishing/fish/types/holographic.dm @@ -13,7 +13,6 @@ average_size = /obj/item/fish/goldfish::average_size average_weight = /obj/item/fish/goldfish::average_weight required_fluid_type = AQUARIUM_FLUID_ANADROMOUS - grind_results = null fillet_type = null death_text = "%SRC gently disappears." fish_traits = list(/datum/fish_trait/no_mating) //just to be sure, these shouldn't reproduce @@ -28,6 +27,9 @@ return holo_area.linked.add_to_spawned(src) +/obj/item/fish/holo/make_edible(weight_val) + return + /obj/item/fish/holo/set_status(new_status, silent = FALSE) . = ..() if(status == FISH_DEAD) diff --git a/code/modules/fishing/fish/types/mining.dm b/code/modules/fishing/fish/types/mining.dm index 7614f259e59..f70e557fdc8 100644 --- a/code/modules/fishing/fish/types/mining.dm +++ b/code/modules/fishing/fish/types/mining.dm @@ -37,6 +37,12 @@ RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks)) RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth)) +/obj/item/fish/chasm_crab/get_fish_taste() + return list("raw crab" = 2) + +/obj/item/fish/chasm_crab/get_fish_taste_cooked() + return list("cooked crab" = 2) + ///A chasm crab growth speed is determined by its initial weight and size, ergo bigger crabs for faster lobstrosities /obj/item/fish/chasm_crab/update_size_and_weight(new_size = average_size, new_weight = average_weight) . = ..() @@ -125,6 +131,9 @@ evolution_types = list(/datum/fish_evolution/mastodon) beauty = FISH_BEAUTY_UGLY +/obj/item/fish/boned/make_edible(weight_val) + return //it's all bones and no meat. + /obj/item/fish/lavaloop name = "lavaloop fish" desc = "Due to its curvature, it can be used as make-shift boomerang." @@ -164,6 +173,12 @@ effect_on_success = /obj/effect/temp_visual/guardian/phase,\ ) +/obj/item/fish/lavaloop/get_fish_taste() + return list("chewy fish" = 2) + +/obj/item/fish/lavaloop/get_food_types() + return SEAFOOD|MEAT|GORE //Well-cooked in lava + /obj/item/fish/lavaloop/proc/explode_on_user(mob/living/user) var/obj/item/bodypart/arm/active_arm = user.get_active_hand() active_arm?.dismember() diff --git a/code/modules/fishing/fish/types/ruins.dm b/code/modules/fishing/fish/types/ruins.dm index da9e8388c0c..a01cd062354 100644 --- a/code/modules/fishing/fish/types/ruins.dm +++ b/code/modules/fishing/fish/types/ruins.dm @@ -26,6 +26,9 @@ fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/amphibious, /datum/fish_trait/revival, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/aggressive) beauty = FISH_BEAUTY_BAD +/obj/item/fish/mastodon/make_edible(weight_val) + return //it's all bones and gibs. + ///From the cursed spring /obj/item/fish/soul name = "soulfish" @@ -50,6 +53,15 @@ required_temperature_max = MIN_AQUARIUM_TEMP+38 random_case_rarity = FISH_RARITY_NOPE +/obj/item/fish/soul/get_food_types() + return MEAT|RAW|GORE //Not-so-quite-seafood + +/obj/item/fish/soul/get_fish_taste() + return list("meat" = 2, "soulfulness" = 1) + +/obj/item/fish/soul/get_fish_taste_cooked() + return list("cooked meat" = 2) + ///From the cursed spring /obj/item/fish/skin_crab name = "skin crab" @@ -71,3 +83,8 @@ fillet_type = /obj/item/food/meat/slab/rawcrab random_case_rarity = FISH_RARITY_NOPE +/obj/item/fish/skin_crab/get_fish_taste() + return list("raw crab" = 2) + +/obj/item/fish/skin_crab/get_fish_taste_cooked() + return list("cooked crab" = 2) diff --git a/code/modules/fishing/fish/types/saltwater.dm b/code/modules/fishing/fish/types/saltwater.dm index 0271c7f3008..afb14436fad 100644 --- a/code/modules/fishing/fish/types/saltwater.dm +++ b/code/modules/fishing/fish/types/saltwater.dm @@ -14,6 +14,9 @@ required_temperature_min = MIN_AQUARIUM_TEMP+22 required_temperature_max = MIN_AQUARIUM_TEMP+30 +/obj/item/fish/clownfish/get_fish_taste() + return list("raw fish" = 2, "something funny" = 1) + /obj/item/fish/clownfish/lube name = "lubefish" desc = "A clownfish exposed to cherry-flavored lube for far too long. First discovered the days following a cargo incident around the seas of Europa, when thousands of thousands of thousands..." @@ -227,9 +230,15 @@ required_temperature_max = MIN_AQUARIUM_TEMP+26 fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/carnivore, /datum/fish_trait/predator, /datum/fish_trait/ink, /datum/fish_trait/camouflage, /datum/fish_trait/wary) +/obj/item/fish/squid/get_fish_taste() + return list("raw mollusk" = 2) + +/obj/item/fish/squid/get_fish_taste_cooked() + return list("cooked mollusk" = 2, "tenderness" = 0.5) + /obj/item/fish/monkfish name = "monkfish" - desc = "A member of the Lophiid family of anglerfish. It goes by several different names, however none of them will make it look any prettier, nor any less delicious." + desc = "A member of the Lophiid family of anglerfish. It goes by several different names, however none of them will make it look any prettier, nor be any less delicious." icon_state = "monkfish" required_fluid_type = AQUARIUM_FLUID_SALTWATER sprite_height = 7 diff --git a/code/modules/fishing/fish/types/station.dm b/code/modules/fishing/fish/types/station.dm index 8dd459452ab..0fa8032d979 100644 --- a/code/modules/fishing/fish/types/station.dm +++ b/code/modules/fishing/fish/types/station.dm @@ -20,6 +20,20 @@ ) beauty = FISH_BEAUTY_DISGUSTING +/obj/item/fish/ratfish/get_fish_taste() + return list("vermin" = 2, "maintenance" = 1) + +/obj/item/fish/ratfish/get_fish_taste_cooked() + return list("cooked vermin" = 2, "burned fur" = 0.5) + +/obj/item/fish/ratfish/get_food_types() + return MEAT|RAW|GORE //Not-so-quite-seafood + +/obj/item/fish/ratfish/get_base_edible_reagents_to_add() + var/list/return_list = ..() + return_list[/datum/reagent/rat_spit] = 1 + return return_list + /obj/item/fish/ratfish/Initialize(mapload, apply_qualities = TRUE) . = ..() //stable pop reflects the config for how many mice migrate. powerful... @@ -43,6 +57,9 @@ evolution_types = list(/datum/fish_evolution/purple_sludgefish) beauty = FISH_BEAUTY_NULL +/obj/item/fish/sludgefish/get_fish_taste() + return list("raw fish" = 2, "eau de toilet" = 1) + /obj/item/fish/sludgefish/purple name = "purple sludgefish" desc = "A misshapen, fragile, loosely fish-like living goop. This one has developed sexual reproduction mechanisms, and a purple tint to boot." @@ -63,7 +80,6 @@ stable_population = 4 health = 150 fillet_type = /obj/item/slime_extract/grey - grind_results = list(/datum/reagent/toxin/slimejelly = 10) fish_traits = list(/datum/fish_trait/toxin_immunity, /datum/fish_trait/crossbreeder) favorite_bait = list( list( @@ -78,3 +94,9 @@ ) required_temperature_min = MIN_AQUARIUM_TEMP+20 beauty = FISH_BEAUTY_GREAT + +/obj/item/fish/slimefish/get_food_types() + return SEAFOOD|TOXIC + +/obj/item/fish/slimefish/get_base_edible_reagents_to_add() + return list(/datum/reagent/toxin/slimejelly = 5) diff --git a/code/modules/fishing/fish/types/syndicate.dm b/code/modules/fishing/fish/types/syndicate.dm index 7710423f4c1..c1c6eea06e4 100644 --- a/code/modules/fishing/fish/types/syndicate.dm +++ b/code/modules/fishing/fish/types/syndicate.dm @@ -13,6 +13,9 @@ required_temperature_max = MIN_AQUARIUM_TEMP+40 beauty = FISH_BEAUTY_BAD +/obj/item/fish/emulsijack/get_fish_taste() + return list("raw fish" = 2, "acid" = 1) //no scales + /obj/item/fish/donkfish name = "donk co. company patent donkfish" desc = "A lab-grown donkfish. Its invention was an accident for the most part, as it was intended to be consumed in donk pockets. Unfortunately, it tastes horrible, so it has now become a pseudo-mascot." @@ -94,6 +97,9 @@ . = ..() AddElement(/datum/element/update_icon_updates_onmob) +/obj/item/fish/chainsawfish/get_fish_taste() + return list("raw fish" = 2.5, "anger" = 1) + /obj/item/fish/chainsawfish/update_icon_state() if(status == FISH_DEAD) inhand_icon_state = "chainsawfish_dead" @@ -202,6 +208,12 @@ /obj/item/fish, ) +/obj/item/fish/pike/armored/get_fish_taste() + return list("raw fish" = 2.5, "metal" = 1) + +/obj/item/fish/pike/armored/get_fish_taste() + return list("cooked fish" = 2.5, "metal" = 1) + /obj/item/fish/swordfish/get_force_rank() switch(w_class) if(WEIGHT_CLASS_TINY) diff --git a/code/modules/fishing/fish/types/tiziran.dm b/code/modules/fishing/fish/types/tiziran.dm index a39e82ce6c4..b6fd43709f2 100644 --- a/code/modules/fishing/fish/types/tiziran.dm +++ b/code/modules/fishing/fish/types/tiziran.dm @@ -24,10 +24,21 @@ required_fluid_type = AQUARIUM_FLUID_SALTWATER stable_population = 4 fillet_type = /obj/item/food/fishmeat/gunner_jellyfish + fish_traits = list(/datum/fish_trait/hallucinogenic) required_temperature_min = MIN_AQUARIUM_TEMP+24 required_temperature_max = MIN_AQUARIUM_TEMP+32 beauty = FISH_BEAUTY_GOOD +/obj/item/fish/gunner_jellyfish/Initialize(mapload, apply_qualities = TRUE) + . = ..() + AddElement(/datum/element/quality_food_ingredient, FOOD_COMPLEXITY_2) + +/obj/item/fish/gunner_jellyfish/get_fish_taste() + return list("cold jelly" = 2) + +/obj/item/fish/gunner_jellyfish/get_fish_taste_cooked() + return list("crunchy tenderness" = 2) + /obj/item/fish/needlefish name = "needlefish" desc = "A tiny, transparent fish which resides in large schools in the oceans of Tizira. A common food for other, larger fish." @@ -67,3 +78,9 @@ /obj/item/fish/armorfish/Initialize(mapload, apply_qualities = TRUE) . = ..() add_traits(list(TRAIT_FISHING_BAIT, TRAIT_GOOD_QUALITY_BAIT), INNATE_TRAIT) + +/obj/item/fish/chasm_crab/get_fish_taste() + return list("raw prawn" = 2) + +/obj/item/fish/chasm_crab/get_fish_taste_cooked() + return list("cooked prawn" = 2) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 122378e99e6..9b088778d57 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -704,4 +704,7 @@ override_origin_pixel_x = lefthand ? lefthand_n_px : righthand_n_px override_origin_pixel_y = lefthand ? lefthand_n_py : righthand_n_py + override_origin_pixel_x += origin.pixel_x + override_origin_pixel_y += origin.pixel_y + #undef FISHING_ROD_REEL_CAST_RANGE diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm index 3425c3b4a8f..056aa4263c0 100644 --- a/code/modules/food_and_drinks/machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm @@ -154,7 +154,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list( reagents.trans_to(frying, oil_use * seconds_per_tick, multiplier = fry_speed * 3) //Fried foods gain more of the reagent thanks to space magic grease_level += prob(grease_increase_chance) * grease_Increase_amount - cook_time += fry_speed * seconds_per_tick + cook_time += fry_speed * seconds_per_tick SECONDS if(cook_time >= DEEPFRYER_COOKTIME && !frying_fried) frying_fried = TRUE //frying... frying... fried playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE) diff --git a/code/modules/food_and_drinks/recipes/soup_mixtures.dm b/code/modules/food_and_drinks/recipes/soup_mixtures.dm index 4f3cba68dd3..88cb4d27e41 100644 --- a/code/modules/food_and_drinks/recipes/soup_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/soup_mixtures.dm @@ -245,7 +245,7 @@ // Everything else will just get fried if(isnull(ingredient.reagents) && !is_type_in_list(ingredient, required_ingredients)) - ingredient.AddElement(/datum/element/fried_item, 30) + ingredient.AddElement(/datum/element/fried_item, 30 SECONDS) continue // Things that had reagents or ingredients in the soup will get deleted diff --git a/code/modules/hydroponics/grown/onion.dm b/code/modules/hydroponics/grown/onion.dm index 0d33c3e1f39..4287bf9eb3e 100644 --- a/code/modules/hydroponics/grown/onion.dm +++ b/code/modules/hydroponics/grown/onion.dm @@ -48,7 +48,7 @@ /obj/item/food/grown/onion/red/make_processable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/onion_slice/red, 2, 15, screentip_verb = "Cut") -/obj/item/food/grown/onion/UsedforProcessing(mob/living/user, obj/item/I, list/chosen_option) +/obj/item/food/grown/onion/UsedforProcessing(mob/living/user, obj/item/I, list/chosen_option, list/created_atoms) var/datum/effect_system/fluid_spread/smoke/chem/cry_about_it = new //Since the onion is destroyed when it's sliced, var/splat_location = get_turf(src) //we need to set up the smoke beforehand cry_about_it.attach(splat_location) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 8856667ae53..e23b1cac5de 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -139,8 +139,8 @@ context[SCREENTIP_CONTEXT_LMB] = "Lock mutation" return CONTEXTUAL_SCREENTIP_SET - // Edibles and pills can be composted. - if(IS_EDIBLE(held_item) || istype(held_item, /obj/item/reagent_containers/pill)) + // Edibles can be composted (most of the times). + if(IS_EDIBLE(held_item) && HAS_TRAIT(held_item, TRAIT_UNCOMPOSTABLE)) context[SCREENTIP_CONTEXT_LMB] = "Compost" return CONTEXTUAL_SCREENTIP_SET @@ -855,7 +855,10 @@ var/visi_msg = "" var/transfer_amount - if(IS_EDIBLE(reagent_source) || istype(reagent_source, /obj/item/reagent_containers/pill)) + if(IS_EDIBLE(reagent_source)) + if(HAS_TRAIT(reagent_source, TRAIT_UNCOMPOSTABLE)) + to_chat(user, "[reagent_source] cannot be composted in its current state") + return visi_msg="[user] composts [reagent_source], spreading it through [target]" transfer_amount = reagent_source.reagents.total_volume SEND_SIGNAL(reagent_source, COMSIG_ITEM_ON_COMPOSTED, user) diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm index 72adcbb43df..28dbbc078c5 100644 --- a/code/modules/mob/living/taste.dm +++ b/code/modules/mob/living/taste.dm @@ -52,27 +52,31 @@ return NONE /mob/living/carbon/get_liked_foodtypes() - var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) - // No tongue, no tastin' - if(!tongue?.sense_of_taste || HAS_TRAIT(src, TRAIT_AGEUSIA)) + if(HAS_TRAIT(src, TRAIT_AGEUSIA)) return NONE // Handled in here since the brain trauma can't modify taste directly (/datum/brain_trauma/severe/flesh_desire) if(HAS_TRAIT(src, TRAIT_FLESH_DESIRE)) return GORE | MEAT - return tongue.liked_foodtypes + var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) + . = tongue.liked_foodtypes + if(HAS_TRAIT(src, TRAIT_VEGETARIAN)) + . &= ~MEAT /** * Gets food flags that this mob dislikes **/ /mob/living/proc/get_disliked_foodtypes() + if(HAS_TRAIT(src, TRAIT_VEGETARIAN)) + return MEAT return NONE /mob/living/carbon/get_disliked_foodtypes() - var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) - // No tongue, no tastin' - if(!tongue?.sense_of_taste || HAS_TRAIT(src, TRAIT_AGEUSIA)) + if(HAS_TRAIT(src, TRAIT_AGEUSIA)) return NONE - return tongue.disliked_foodtypes + var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) + . = tongue.disliked_foodtypes + if(HAS_TRAIT(src, TRAIT_VEGETARIAN)) + . |= MEAT /** * Gets food flags that this mob hates @@ -83,9 +87,8 @@ /mob/living/carbon/get_toxic_foodtypes() var/obj/item/organ/internal/tongue/tongue = get_organ_slot(ORGAN_SLOT_TONGUE) - // No tongue, no tastin' if(!tongue) - return TOXIC + return ..() if(HAS_TRAIT(src, TRAIT_FLESH_DESIRE)) return VEGETABLES | DAIRY | FRUIT | FRIED return tongue.toxic_foodtypes diff --git a/code/modules/reagents/chemistry/holder/holder.dm b/code/modules/reagents/chemistry/holder/holder.dm index f084a7eaa39..593bc6d4710 100644 --- a/code/modules/reagents/chemistry/holder/holder.dm +++ b/code/modules/reagents/chemistry/holder/holder.dm @@ -204,11 +204,12 @@ * * * [list_reagents][list] - list to add. Format it like this: list(/datum/reagent/toxin = 10, "beer" = 15) * * [data][list] - additional data to add + * * [added_purity][number] - an override to the default purity for each reagent to add. */ -/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data = null) +/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data = null, added_purity = null) for(var/r_id in list_reagents) var/amt = list_reagents[r_id] - add_reagent(r_id, amt, data) + add_reagent(r_id, amt, data, added_purity = added_purity) /** * Removes a specific reagent. can supress reactions if needed @@ -589,10 +590,11 @@ */ /datum/reagents/proc/multiply_reagents(multiplier = 1) var/list/cached_reagents = reagent_list - if(!total_volume) + if(!total_volume || multiplier == 1) return var/change = (multiplier - 1) //Get the % change for(var/datum/reagent/reagent as anything in cached_reagents) + _multiply_reagent(reagent, change) if(change > 0) add_reagent(reagent.type, reagent.volume * change, added_purity = reagent.purity, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT) else @@ -601,6 +603,28 @@ update_total() handle_reactions() +/** + * Multiplies a single inside this holder by a specific amount + * Arguments + * * reagent_path - The path of the reagent we want to multiply the volume of. + * * multiplier - the amount to multiply each reagent by + */ +/datum/reagents/proc/multiply_single_reagent(reagent_path, multiplier = 1) + var/datum/reagent/reagent = locate(reagent_path) in reagent_list + if(!reagent || multiplier == 1) + return + var/change = (multiplier - 1) //Get the % change + _multiply_reagent(reagent, change) + update_total() + handle_reactions() + +///Proc containing the operations called by both multiply_reagents() and multiply_single_reagent() +/datum/reagents/proc/_multiply_reagent(datum/reagent/reagent, change) + if(change > 0) + add_reagent(reagent.type, reagent.volume * change, added_purity = reagent.purity, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT) + else + remove_reagent(reagent.type, abs(reagent.volume * change)) //absolute value to prevent a double negative situation (removing -50% would be adding 50%) + /// Updates [/datum/reagents/var/total_volume] /datum/reagents/proc/update_total() var/list/cached_reagents = reagent_list diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index e475a9d2f48..2f59bd4d77b 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -170,8 +170,8 @@ return exposed_obj.visible_message(span_warning("[exposed_obj] rapidly fries as it's splashed with hot oil! Somehow.")) - exposed_obj.AddElement(/datum/element/fried_item, volume) - exposed_obj.reagents.add_reagent(src.type, reac_volume) + exposed_obj.AddElement(/datum/element/fried_item, volume SECONDS) + exposed_obj.reagents.add_reagent(src.type, reac_volume, reagtemp = holder.chem_temp) /datum/reagent/consumable/nutriment/fat/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 5e553fce962..95f73e552be 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -326,6 +326,19 @@ else affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) +/datum/reagent/toxin/mindbreaker/fish + name = "Jellyfish Hallucinogen" + description = "A hallucinogen structurally similar to the mindbreaker toxin, but with weaker molecular bonds, making it easily degradeable by heat." + +/datum/reagent/toxin/mindbreaker/fish/on_new(data) + . = ..() + if(holder?.my_atom) + RegisterSignals(holder.my_atom, list(COMSIG_ITEM_FRIED, TRAIT_FOOD_BBQ_GRILLED), PROC_REF(on_atom_cooked)) + +/datum/reagent/toxin/mindbreaker/fish/proc/on_atom_cooked(datum/source, cooking_time) + SIGNAL_HANDLER + holder.del_reagent(type) + /datum/reagent/toxin/plantbgone name = "Plant-B-Gone" description = "A harmful toxic mixture to kill plantlife. Do not ingest!" diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index b80919e6a23..7e619c50d19 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -41,7 +41,7 @@ required_other = TRUE /datum/chemical_reaction/sodiumchloride/pre_reaction_other_checks(datum/reagents/holder) - . = ..() + . = ..() if(holder.has_reagent(/datum/reagent/consumable/liquidelectricity) || holder.has_reagent(/datum/reagent/consumable/liquidelectricity/enriched)) return FALSE @@ -990,3 +990,16 @@ var/location = get_turf(holder.my_atom) for(var/i in 1 to created_volume) new /obj/item/stack/sheet/hauntium(location) + +/datum/chemical_reaction/fish_hallucinogen_degradation + results = list(/datum/reagent/consumable/nutriment/protein = 0.1) + required_reagents = list(/datum/reagent/toxin/mindbreaker/fish = 1) + required_temp = 363.15 // 90° + optimal_temp = 450 + rate_up_lim = 8 + temp_exponent_factor = 1.5 + optimal_ph_min = 2 + optimal_ph_max = 10 + thermic_constant = 80 + H_ion_release = 2 + reaction_tags = REACTION_TAG_EASY diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index 13eaffca3a8..21d076e949f 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -147,7 +147,7 @@ var/obj/item/food_item = new chosen(T) ADD_TRAIT(food_item, TRAIT_FOOD_SILVER, INNATE_TRAIT) if(prob(5))//Fry it! - food_item.AddElement(/datum/element/fried_item, rand(15, 60)) + food_item.AddElement(/datum/element/fried_item, rand(15, 60) SECONDS) if(prob(5))//Grill it! food_item.AddElement(/datum/element/grilled_item, rand(30 SECONDS, 100 SECONDS)) if(prob(50)) diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index 8f1bd532eb9..d0efba5111b 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -624,7 +624,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list()) say_mod = "meows" liked_foodtypes = SEAFOOD | ORANGES | BUGS | GORE disliked_foodtypes = GROSS | CLOTH | RAW - organ_traits = list(TRAIT_WOUND_LICKER) + organ_traits = list(TRAIT_WOUND_LICKER, TRAIT_FISH_EATER) /obj/item/organ/internal/tongue/jelly name = "jelly tongue" diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index e3ede57fc29..63bb5e30616 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -1,4 +1,5 @@ #define TRAIT_FISH_TESTING "made_you_read_this" +#define FISH_REAGENT_AMOUNT (10 * FISH_WEIGHT_GRIND_TO_BITE_MULT) ///Ensures that all fish have an aquarium icon state and that sprite_width and sprite_height have been set. /datum/unit_test/fish_aquarium_icons @@ -21,7 +22,10 @@ /datum/unit_test/fish_size_weight/Run() var/obj/item/fish/fish = allocate(/obj/item/fish/testdummy) - TEST_ASSERT_EQUAL(fish.grind_results[/datum/reagent], 20, "the test fish has [fish.grind_results[/datum/reagent]] units of reagent when it should have 20") + var/datum/reagent/reagent = fish.reagents?.has_reagent(/datum/reagent/fishdummy) + TEST_ASSERT(reagent, "the test fish doesn't have the test reagent.[fish.reagents ? "" : " It doesn't even have a reagent holder."]") + var/expected_units = FISH_REAGENT_AMOUNT * fish.weight / FISH_WEIGHT_BITE_DIVISOR + TEST_ASSERT_EQUAL(reagent.volume, expected_units, "the test fish has [reagent.volume] units of the test reagent when it should have [expected_units]") TEST_ASSERT_EQUAL(fish.w_class, WEIGHT_CLASS_BULKY, "the test fish has w_class of [fish.w_class] when it should have been [WEIGHT_CLASS_BULKY]") var/expected_num_fillets = round(FISH_SIZE_BULKY_MAX / FISH_FILLET_NUMBER_SIZE_DIVISOR * 2, 1) TEST_ASSERT_EQUAL(fish.num_fillets, expected_num_fillets, "the test fish has [fish.num_fillets] number of fillets when it should have [expected_num_fillets]") @@ -93,7 +97,7 @@ incompatible_traits = list(/datum/fish_trait/dummy/two) inheritability = 100 diff_traits_inheritability = 100 - reagents_to_add = list(/datum/reagent = 10) + reagents_to_add = list(/datum/reagent/fishdummy = FISH_REAGENT_AMOUNT) /datum/fish_trait/dummy/apply_to_fish(obj/item/fish/fish) . = ..() @@ -102,6 +106,10 @@ /datum/fish_trait/dummy/two incompatible_traits = list(/datum/fish_trait/dummy) +/datum/reagent/fishdummy + name = "fish test reagent" + description = "It smells fishy." + /obj/structure/aquarium/traits allow_breeding = TRUE var/obj/item/fish/testdummy/crossbreeder/crossbreeder @@ -283,12 +291,63 @@ /datum/fish_source/unit_test fish_table = list( /obj/item/wrench = 1, - /obj/item/screwdriver = INFINITY, + /obj/item/screwdriver = INFINITY, //infinite weight, so if fish counts doesn't work as intended, this'll be always picked. ) fish_counts = list( /obj/item/wrench = 1, - /obj/item/screwdriver = 0, + /obj/item/screwdriver = 0, //this should never be picked. ) +/datum/unit_test/edible_fish + +/datum/unit_test/edible_fish/Run() + var/obj/item/fish/fish = allocate(/obj/item/fish/testdummy/food) + var/datum/component/edible/edible = fish.GetComponent(/datum/component/edible) + TEST_ASSERT(edible, "Fish is not edible") + edible.eat_time = 0 + TEST_ASSERT(fish.GetComponent(/datum/component/infective), "Fish doesn't have the infective component") + var/bite_size = edible.bite_consumption + + var/mob/living/carbon/human/consistent/gourmet = allocate(/mob/living/carbon/human/consistent) + + var/food_quality = edible.get_perceived_food_quality(gourmet) + TEST_ASSERT(food_quality < 0, "Humans don't seem to dislike raw, unprocessed fish when they should") + ADD_TRAIT(gourmet, TRAIT_FISH_EATER, TRAIT_FISH_TESTING) + food_quality = edible.get_perceived_food_quality(gourmet) + TEST_ASSERT(food_quality >= LIKED_FOOD_QUALITY_CHANGE, "mobs with the TRAIT_FISH_EATER traits don't seem to like fish when they should") + REMOVE_TRAIT(gourmet, TRAIT_FISH_EATER, TRAIT_FISH_TESTING) + + fish.attack(gourmet, gourmet) + TEST_ASSERT(gourmet.has_reagent(/datum/reagent/consumable/nutriment/protein), "Human doesn't have ingested protein after eating fish") + TEST_ASSERT(gourmet.has_reagent(/datum/reagent/blood), "Human doesn't have ingested blood after eating fish") + TEST_ASSERT(gourmet.has_reagent(/datum/reagent/fishdummy), "Human doesn't have the reagent from /datum/fish_trait/dummy after eating fish") + + TEST_ASSERT_EQUAL(fish.status, FISH_DEAD, "The fish is not dead, despite having sustained enough damage that it should. health: [fish.health]") + + var/obj/item/organ/internal/stomach/belly = gourmet.get_organ_slot(ORGAN_SLOT_STOMACH) + belly.reagents.clear_reagents() + + fish.set_status(FISH_ALIVE) + TEST_ASSERT(!fish.bites_amount, "bites_amount wasn't reset after the fish revived") + + fish.update_size_and_weight(fish.size, FISH_WEIGHT_BITE_DIVISOR) + fish.AddElement(/datum/element/fried_item, FISH_SAFE_COOKING_DURATION) + TEST_ASSERT_EQUAL(fish.status, FISH_DEAD, "The fish didn't die after being cooked") + TEST_ASSERT(bite_size < edible.bite_consumption, "The bite_consumption value hasn't increased after being cooked (it removes blood but doubles protein). Value: [bite_size]") + TEST_ASSERT(!(edible.foodtypes & (RAW|GORE)), "Fish still has the GORE and/or RAW foodtypes flags after being cooked") + TEST_ASSERT(!fish.GetComponent(/datum/component/infective), "Fish still has the infective component after being cooked for long enough") + + + food_quality = edible.get_perceived_food_quality(gourmet) + TEST_ASSERT(food_quality >= 0, "Humans still dislike fish, even when it's cooked") + fish.attack(gourmet, gourmet) + TEST_ASSERT(!gourmet.has_reagent(/datum/reagent/blood), "Human has ingested blood from eating a fish when it shouldn't since the fish has been cooked") + + TEST_ASSERT(QDELETED(fish), "The fish is not being deleted, despite having sustained enough bites. Reagents volume left: [fish.reagents.total_volume]") + +/obj/item/fish/testdummy/food + average_weight = FISH_WEIGHT_BITE_DIVISOR * 2 //One bite, it's death; the other, it's gone. + +#undef FISH_REAGENT_AMOUNT #undef TRAIT_FISH_TESTING diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index eda70bb4252..31d18f10196 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -22,7 +22,7 @@ The fishing portal generator has different modules, all of which can be unlocked A fish's traits influence how you can catch them. Carnivore fish will ignore dough balls, and herbivore fish ignore anything that's not from botany. Telescopic fishing rods can be bought from cargo. Once grown from chrabs and tamed, lobstrosities can be heeded to fish on fishing spots for you. -Aquariums can be upgraded to bioelectricity generators can a specific kit. From there, you can add electric-generating fish like the anxious zip zap to generate power. +Aquariums can be upgraded to bioelectricity generators with a specific kit. From there, you can add electric-generating fish like the anxious zip zap to generate power for the station. Getting better at fishing will net you some small additional advantages, such as receiving more information when examining a fish or a fishing spot. The size and weight of a fish can influence the amount of reagents and fillets you can harvest from them, their force as a weapon and how easy it is to store them in containers. While most fish make for shoddy weapons, a few, like the swordfish and the chainsawfish, can be quite powerful. In general, the bigger they are, the more forceful they get. @@ -33,12 +33,14 @@ Some species of fish can be bred into new species under the right conditions. Most fish don't survive outside water, so get them somewhere safe like an aquarium or a fish case, or even a toilet or a moisture trap! No matter how you look at it, most people won't care about fishing. Don't let that stop you. They're just jealous. To fish on ice you have to puncture the ice layer with a pick or shovel first. -Depending on the kind of fish inside it and whether they're alive or dead, an aquarium can improve the beauty of the room or worsen it. +Depending on the kinds of fish inside it and whether they're alive or dead, an aquarium can improve the beauty of the room or worsen it. Almost all fish can be ground in an All-in-one-Grinder. Don't think too hard about how you're fitting a giant fish into a blender. Nanotrasen technology is weird like that. The sludgefish from the toilets can be used as a steady supply of cheap fish and fillets due to its self-reproducing behaviour. However it's quite fragile. In a jiffy, you can scoop tadpoles from ponds with your bare hands, place them inside aquariums and quickly raise them into frogs. The legendary fishing hat isn't just cosmetic. Space carps (as well as young lobstrosities and frogs) do truly fear those who wear it. Have you ever heard a lobster or crab talk? Well, neither have I, but they say they're quite the fishy punsters. -You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) for research. +You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) to research. +Fish is, of course, edible. Is it safe to eat raw? Well, if you've strong stomach, otherwise your best option is to cook it for a at least half a spessman minute if you don't want to catch nasty diseases. +After researching the Advanced Fishing Technology Node, you can print special fishing gloves that let you fish without having to carry around a fishing rod. There's one pair that even trains athletics on top of fishing.You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) for research. If you have enough credits, you can buy a set of fishing lures from cargo. Each lure allows you to catch different species of fish and won't get consumed, however they need to be spun at intervals to work. -This may sound silly, but squids and their ink sacs can be used as weapons to temporarily blind people. \ No newline at end of file +This may sound silly, but squids and their ink sacs can be used to temporarily blind foes. \ No newline at end of file From e806a0d6cc95f5fd08c4f2c6b9e570cf3f7c21d4 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:38:06 +0200 Subject: [PATCH 038/142] Water turfs are now properly named (#86641) ## About The Pull Request Because water turfs were unnamed on compile-time, they defaulted to the last section of their path. ## Why It's Good For The Game This will fix #86638 ## Changelog :cl: fix: Water turfs from the crashed site ruin on lavaland are no longer named "lavaland atmos". /:cl: --- code/game/turfs/open/water.dm | 1 + code/modules/mapfluff/ruins/icemoonruin_code/hotsprings.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index 5f71d43698f..853557a1fe9 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -1,4 +1,5 @@ /turf/open/water + name = "water" gender = PLURAL desc = "Shallow water." icon = 'icons/turf/floors.dmi' diff --git a/code/modules/mapfluff/ruins/icemoonruin_code/hotsprings.dm b/code/modules/mapfluff/ruins/icemoonruin_code/hotsprings.dm index 362bf364b7a..4ea4dbff415 100644 --- a/code/modules/mapfluff/ruins/icemoonruin_code/hotsprings.dm +++ b/code/modules/mapfluff/ruins/icemoonruin_code/hotsprings.dm @@ -11,6 +11,7 @@ */ /turf/open/water/cursed_spring + name = "cursed spring" baseturfs = /turf/open/water/cursed_spring planetary_atmos = TRUE initial_gas_mix = ICEMOON_DEFAULT_ATMOS From a6063915bfa043643cbfc8c797583f4f7564a632 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:51:05 +0200 Subject: [PATCH 039/142] Fixes the offsets of the chimp shotgun (#86632) ## About The Pull Request Gee... ## Why It's Good For The Game ## Changelog :cl: fix: Fixed the offsets of the chimp shotgun when held. /:cl: --- code/modules/projectiles/guns/ballistic/shotgun.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 1c885902908..990b7ea3ee6 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -350,6 +350,8 @@ inhand_icon_state = "shotgun" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' + inhand_x_dimension = 32 + inhand_y_dimension = 32 force = 8 obj_flags = CONDUCTS_ELECTRICITY slot_flags = NONE From fca81bf646e8f6658ab1a5459ff4bb18bad94b1c Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:55:27 +0200 Subject: [PATCH 040/142] Fishing in a virtual domain doesn't deplete limited loot anymore (also the treasure chest is no longer anchored) (#86625) ## About The Pull Request I've recently realized that bitrunning fishing spots can steal the limited loot from outside the virtual reality, which sucks. Also Livrah asked me why the treasure chest is anchored, to which I said it's actually an oversight. ## Why It's Good For The Game Fixing stuff. ## Changelog :cl: fix: Bitrunning fishing spots no longer deplete limited loot from outside the virtual reality. fix: The treasure chest from the beach is no longer anchored to the floor. /:cl: --- code/__DEFINES/_flags.dm | 2 ++ code/_globalvars/bitfields.dm | 1 + code/game/area/areas/centcom.dm | 1 + code/game/objects/structures/mystery_box.dm | 1 + code/modules/bitrunning/areas.dm | 14 +++++++------- code/modules/fishing/sources/_fish_source.dm | 3 ++- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index 687f5365f6d..9b3b239034b 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -140,6 +140,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define BINARY_JAMMING (1<<17) /// This area prevents Bag of Holding rifts from being opened. #define NO_BOH (1<<18) +/// This area prevents fishing from removing unique/limited loot from sources that're also used outside of it. +#define UNLIMITED_FISHING (1<<19) /* These defines are used specifically with the atom/pass_flags bitmask diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 0694d1c947c..3fcc9e1cedc 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -65,6 +65,7 @@ DEFINE_BITFIELD(area_flags, list( "VALID_TERRITORY" = VALID_TERRITORY, "XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE, "NO_BOH" = NO_BOH, + "UNLIMITED_FISHING" = UNLIMITED_FISHING, )) DEFINE_BITFIELD(turf_flags, list( diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index ee79b5b8cc7..4049e9600db 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -129,6 +129,7 @@ /area/centcom/tdome/arena name = "Thunderdome Arena" icon_state = "thunder" + area_flags = parent_type::area_flags | UNLIMITED_FISHING //for possible testing purposes /area/centcom/tdome/tdome1 name = "Thunderdome (Team 1)" diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm index 4195be91dae..cb56cfe8ef1 100644 --- a/code/game/objects/structures/mystery_box.dm +++ b/code/game/objects/structures/mystery_box.dm @@ -281,6 +281,7 @@ GLOBAL_LIST_INIT(mystery_fishing, list( max_integrity = 100 damage_deflection = 30 grant_extra_mag = FALSE + anchored = FALSE /obj/structure/mystery_box/handle_deconstruct(disassembled) new /obj/item/stack/sheet/mineral/wood(drop_location(), 2) diff --git a/code/modules/bitrunning/areas.dm b/code/modules/bitrunning/areas.dm index 4fcf0a0496e..0656f9d65b3 100644 --- a/code/modules/bitrunning/areas.dm +++ b/code/modules/bitrunning/areas.dm @@ -14,7 +14,7 @@ name = "Virtual Domain Ruins" icon_state = "bit_ruin" icon = 'icons/area/areas_station.dmi' - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA | UNLIMITED_FISHING has_gravity = STANDARD_GRAVITY requires_power = FALSE @@ -26,7 +26,7 @@ /area/virtual_domain/safehouse name = "Virtual Domain Safehouse" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | VIRTUAL_SAFE_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | VIRTUAL_SAFE_AREA | UNLIMITED_FISHING icon_state = "bit_safe" requires_power = FALSE sound_environment = SOUND_ENVIRONMENT_ROOM @@ -36,30 +36,30 @@ /area/lavaland/surface/outdoors/virtual_domain name = "Virtual Domain Lava Ruins" icon_state = "bit_ruin" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA | UNLIMITED_FISHING /area/icemoon/underground/explored/virtual_domain name = "Virtual Domain Ice Ruins" icon_state = "bit_ice" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA | UNLIMITED_FISHING /area/ruin/space/virtual_domain name = "Virtual Domain Unexplored Location" icon = 'icons/area/areas_station.dmi' icon_state = "bit_ruin" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA | UNLIMITED_FISHING /area/space/virtual_domain name = "Virtual Domain Space" icon = 'icons/area/areas_station.dmi' icon_state = "bit_space" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | HIDDEN_AREA | UNLIMITED_FISHING ///Areas that virtual entities should not be in /area/virtual_domain/protected_space name = "Virtual Domain Safe Zone" - area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | VIRTUAL_SAFE_AREA + area_flags = UNIQUE_AREA | NOTELEPORT | EVENT_PROTECTED | VIRTUAL_SAFE_AREA | UNLIMITED_FISHING icon_state = "bit_safe" /area/virtual_domain/protected_space/fullbright diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 92c76b9b0b7..e347cdc17b4 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -259,7 +259,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) /datum/fish_source/proc/simple_dispense_reward(reward_path, atom/spawn_location, turf/fishing_spot) if(isnull(reward_path)) return null - if(!isnull(fish_counts[reward_path])) // This is limited count result + var/area/area = get_area(fishing_spot) + if(!(area.area_flags & UNLIMITED_FISHING) && !isnull(fish_counts[reward_path])) // This is limited count result //Somehow, we're trying to spawn an expended reward. if(fish_counts[reward_path] <= 0) return null From dd8224d1da96f3a5347c62e69ba2843bb7536e9e Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:56:08 +0200 Subject: [PATCH 041/142] Fixes a line in fish sources code. (#86633) ## About The Pull Request We ned to set the `leveling_exponent` here, not the `weight_leveling_exponents` static variable itself. ## Why It's Good For The Game Fixing fishing with baits. I should improve the unit tests later... ## Changelog :cl: fix: Fishing with baits works again. /:cl: --- code/modules/fishing/sources/_fish_source.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index e347cdc17b4..e3b3922b332 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -320,7 +320,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) for(var/trait in weight_result_multiplier) if(HAS_TRAIT(bait, trait)) result_multiplier = weight_result_multiplier[trait] - weight_leveling_exponents = weight_leveling_exponents[trait] + leveling_exponent = weight_leveling_exponents[trait] break From d79aea1ff4c1c9defc3c635c1b5aaf1d2bef9575 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:57:32 +0200 Subject: [PATCH 042/142] Fixes aquarium props not showing up in the aquarium. (#86618) ## About The Pull Request RegisterSignals apparently doesn't throw warnings when the signals arg is not a list and just silently fails. ## Why It's Good For The Game Fixing stuff. ## Changelog :cl: fix: Fixed aquarium props not showing up inside the aquarium. /:cl: --- code/modules/fishing/aquarium/aquarium_kit.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/fishing/aquarium/aquarium_kit.dm b/code/modules/fishing/aquarium/aquarium_kit.dm index 03fe2c5aef5..11fd841009d 100644 --- a/code/modules/fishing/aquarium/aquarium_kit.dm +++ b/code/modules/fishing/aquarium/aquarium_kit.dm @@ -123,7 +123,7 @@ /obj/item/aquarium_prop/Initialize(mapload) . = ..() //It's important that we register the signals before the component is attached. - RegisterSignals(src, COMSIG_AQUARIUM_CONTENT_GENERATE_APPEARANCE, PROC_REF(generate_aquarium_appearance)) + RegisterSignal(src, COMSIG_AQUARIUM_CONTENT_GENERATE_APPEARANCE, PROC_REF(generate_aquarium_appearance)) AddComponent(/datum/component/aquarium_content, beauty = beauty) ADD_TRAIT(src, TRAIT_UNIQUE_AQUARIUM_CONTENT, INNATE_TRAIT) From ae2cc45ce2d6ab1b7351c178597724ecf3daa237 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:59:20 +0200 Subject: [PATCH 043/142] Adds a screentip to items with the disarm attack element. (#86598) ## About The Pull Request Added a screentip to the element that shields and pillows use for shoving mobs. ## Why It's Good For The Game It helps. ## Changelog :cl: qol: Add a screentip to shields and pillows' right-click function (shoving people). /:cl: --- code/datums/elements/disarm_attack.dm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/code/datums/elements/disarm_attack.dm b/code/datums/elements/disarm_attack.dm index a788cd9f35e..8b4b0b3ff8a 100644 --- a/code/datums/elements/disarm_attack.dm +++ b/code/datums/elements/disarm_attack.dm @@ -6,13 +6,23 @@ if(!isitem(target)) return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_ITEM_ATTACK_SECONDARY, PROC_REF(secondary_attack)) - RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(examine)) + var/obj/item/item = target + RegisterSignal(item, COMSIG_ITEM_ATTACK_SECONDARY, PROC_REF(secondary_attack)) + RegisterSignal(item, COMSIG_ATOM_EXAMINE, PROC_REF(examine)) + item.item_flags |= ITEM_HAS_CONTEXTUAL_SCREENTIPS + RegisterSignal(item, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, PROC_REF(add_item_context)) /datum/element/disarm_attack/Detach(datum/source) - UnregisterSignal(source, list(COMSIG_ATOM_EXAMINE, COMSIG_ITEM_ATTACK_SECONDARY)) + UnregisterSignal(source, list(COMSIG_ATOM_EXAMINE, COMSIG_ITEM_ATTACK_SECONDARY, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET)) return ..() +/datum/element/disarm_attack/proc/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) + SIGNAL_HANDLER + if(!isliving(target) || !can_disarm_attack(source, target, user, FALSE)) + return NONE + context[SCREENTIP_CONTEXT_RMB] = "Shove" + return CONTEXTUAL_SCREENTIP_SET + /datum/element/disarm_attack/proc/secondary_attack(obj/item/source, mob/living/victim, mob/living/user, params) SIGNAL_HANDLER if(!user.can_disarm(victim) || !can_disarm_attack(source, victim, user)) From ea96fcd22031f8ba917dd2787276ae9a61666021 Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Sun, 15 Sep 2024 08:45:52 -0400 Subject: [PATCH 044/142] Fixes crafted donuts never, ever getting their sprinkles (#86652) ## About The Pull Request Fixes https://github.com/NovaSector/NovaSector/issues/4380 Sprinkles are supposed to be added as a reagent during `Initialize()`, but whenever you craft a food item the `reagents` get cleared, and then reagents from the ingredients get transferred into the resulting food item. Since sprinkles do not come from any particular ingredient (they are hand-waved to be made from the 1unit of sugar) they just never get re-added by anything. Basically it comes down to a race condition of donut spawned by crafting->1unit sprinkles gets added->crafting tries to do its clearing reagents + transferring reagents thing, losing the sprinkles in the process. The solution I came up with is to just...readd them in `on_craft_completion()`. ## Why It's Good For The Game I want my mother*****ing sprinkles!!

Works ![dreamseeker_T1AfkW6M8t](https://github.com/user-attachments/assets/c2e3b997-e71a-4cb0-935a-3b0625de0f53)
## Changelog :cl: fix: fixed crafted donuts not getting any sprinkles, ever /:cl: --- .../food_and_drinks/recipes/tablecraft/recipes_pastry.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index c965526bcb1..8798f7cd880 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -13,6 +13,14 @@ result = /obj/item/food/donut/plain category = CAT_PASTRY +// It is so stupid that we have to do this but because food crafting clears all reagents that got added during init, +// here we are adding it again (but only for crafting, maploaded and spawned donuts work fine). +// Until the issues with crafted items' reagents are resolved this will have to do +/datum/crafting_recipe/food/donut/on_craft_completion(mob/user, atom/result) + . = ..() + var/obj/item/food/donut/donut_result = result + if(donut_result.is_decorated) + donut_result.reagents.add_reagent(/datum/reagent/consumable/sprinkles, 1) /datum/crafting_recipe/food/donut/chaos name = "Chaos donut" From eaf46e488cbbe7ebf9e668246a6bb6ca733c6be2 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:09:21 +0000 Subject: [PATCH 045/142] Automatic changelog for PR #86110 [ci skip] --- html/changelogs/AutoChangeLog-pr-86110.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86110.yml diff --git a/html/changelogs/AutoChangeLog-pr-86110.yml b/html/changelogs/AutoChangeLog-pr-86110.yml new file mode 100644 index 00000000000..1dd3b6bd2ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86110.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Whole, unprocessed fish is now edible. However it's pretty much reccomended to grill or fry it for over 30 spess seconds before attempting to eat it." + - bugfix: "germ-covered, dirty food no longer tries to infect you through contact." \ No newline at end of file From 014c797f71170a709db14371a5f80d7452f170a4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:11:49 +0000 Subject: [PATCH 046/142] Automatic changelog for PR #86641 [ci skip] --- html/changelogs/AutoChangeLog-pr-86641.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86641.yml diff --git a/html/changelogs/AutoChangeLog-pr-86641.yml b/html/changelogs/AutoChangeLog-pr-86641.yml new file mode 100644 index 00000000000..8f5e6437409 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86641.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Water turfs from the crashed site ruin on lavaland are no longer named \"lavaland atmos\"." \ No newline at end of file From f45b06e32fe089d792315975badcf8aa91ce655f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:12:10 +0000 Subject: [PATCH 047/142] Automatic changelog for PR #86632 [ci skip] --- html/changelogs/AutoChangeLog-pr-86632.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86632.yml diff --git a/html/changelogs/AutoChangeLog-pr-86632.yml b/html/changelogs/AutoChangeLog-pr-86632.yml new file mode 100644 index 00000000000..88689592dbc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86632.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed the offsets of the chimp shotgun when held." \ No newline at end of file From 8c264b9947c7be7ef08e052720d558c9263eb409 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:12:49 +0000 Subject: [PATCH 048/142] Automatic changelog for PR #86625 [ci skip] --- html/changelogs/AutoChangeLog-pr-86625.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86625.yml diff --git a/html/changelogs/AutoChangeLog-pr-86625.yml b/html/changelogs/AutoChangeLog-pr-86625.yml new file mode 100644 index 00000000000..192b9b7ff45 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86625.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Bitrunning fishing spots no longer deplete limited loot from outside the virtual reality." + - bugfix: "The treasure chest from the beach is no longer anchored to the floor." \ No newline at end of file From 8540fce0f0e817cce8c65698a853855a43c52bff Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:12:53 +0000 Subject: [PATCH 049/142] Automatic changelog for PR #86633 [ci skip] --- html/changelogs/AutoChangeLog-pr-86633.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86633.yml diff --git a/html/changelogs/AutoChangeLog-pr-86633.yml b/html/changelogs/AutoChangeLog-pr-86633.yml new file mode 100644 index 00000000000..b5258cb1ca1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86633.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fishing with baits works again." \ No newline at end of file From d4713ff322ab1b9473b8405ce393f67dc3e26c06 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:14:13 +0000 Subject: [PATCH 050/142] Automatic changelog for PR #86618 [ci skip] --- html/changelogs/AutoChangeLog-pr-86618.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86618.yml diff --git a/html/changelogs/AutoChangeLog-pr-86618.yml b/html/changelogs/AutoChangeLog-pr-86618.yml new file mode 100644 index 00000000000..239cbfeb594 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86618.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed aquarium props not showing up inside the aquarium." \ No newline at end of file From 042e7b692e403c14d7be73d7963657419c1284ae Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:14:31 +0000 Subject: [PATCH 051/142] Automatic changelog for PR #86598 [ci skip] --- html/changelogs/AutoChangeLog-pr-86598.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86598.yml diff --git a/html/changelogs/AutoChangeLog-pr-86598.yml b/html/changelogs/AutoChangeLog-pr-86598.yml new file mode 100644 index 00000000000..863761ee841 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86598.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - qol: "Add a screentip to shields and pillows' right-click function (shoving people)." \ No newline at end of file From 573a778beb0bd9e386de3e183dd68b801b71f5d6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:15:28 +0000 Subject: [PATCH 052/142] Automatic changelog for PR #86652 [ci skip] --- html/changelogs/AutoChangeLog-pr-86652.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86652.yml diff --git a/html/changelogs/AutoChangeLog-pr-86652.yml b/html/changelogs/AutoChangeLog-pr-86652.yml new file mode 100644 index 00000000000..023432ee70d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86652.yml @@ -0,0 +1,4 @@ +author: "vinylspiders" +delete-after: True +changes: + - bugfix: "fixed crafted donuts not getting any sprinkles, ever" \ No newline at end of file From 1b4abb588dd20687e47bab64ec49a74499806973 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:40:19 +0200 Subject: [PATCH 053/142] Upgrades GODMODE from a flag to a trait. (#86596) GODMODE has a lot of sources that toggle it. From admin-stuff to status effects, components, actions and mobs which are supposed to be invincible. It's better off as a trait than a flag, so we can manage these sources. See above. :cl: admin: godmode is now a datum trait instead of a bitflag. This means the process for toggling it is a little different now. /:cl: --- code/__DEFINES/combat.dm | 3 -- code/__DEFINES/traits/declarations.dm | 2 + code/_globalvars/traits/_traits.dm | 1 + code/_globalvars/traits/admin_tooling.dm | 1 + code/datums/actions/mobs/lava_swoop.dm | 6 +-- .../basic_targeting_strategy.dm | 3 +- code/datums/components/area_based_godmode.dm | 8 ++-- code/datums/components/singularity.dm | 2 +- code/datums/components/soulstoned.dm | 6 +-- code/datums/components/supermatter_crystal.dm | 20 +++++----- code/datums/elements/embed.dm | 2 +- code/datums/shuttles/emergency.dm | 2 +- .../weather/weather_types/radiation_storm.dm | 18 ++++----- code/datums/wounds/_wound_static_data.dm | 2 +- .../anomalies/anomalies_bioscrambler.dm | 2 +- code/game/objects/items/spear.dm | 6 +-- code/game/objects/items/theft_tools.dm | 6 +-- .../objects/structures/petrified_statue.dm | 37 +++++++++---------- code/modules/admin/verbs/admingame.dm | 18 +++++---- .../heretic/status_effects/buffs.dm | 4 +- code/modules/mafia/controller.dm | 17 ++++++--- code/modules/mining/lavaland/tendril_loot.dm | 6 +-- code/modules/mob/camera/camera.dm | 2 +- .../modules/mob/living/basic/basic_defense.dm | 2 +- .../mob/living/basic/drone/interaction.dm | 2 +- .../mob/living/basic/health_adjustment.dm | 4 +- .../lavaland/bileworm/bileworm_actions.dm | 8 ++-- .../mob/living/basic/pets/parrot/poly.dm | 3 +- .../basic/ruin_defender/living_floor.dm | 3 +- .../living/basic/space_fauna/bear/_bear.dm | 3 +- .../space_fauna/wumborian_fugu/inflation.dm | 6 +-- code/modules/mob/living/blood.dm | 2 +- code/modules/mob/living/brain/life.dm | 2 +- .../mob/living/carbon/alien/larva/life.dm | 2 +- code/modules/mob/living/carbon/alien/life.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 4 +- .../modules/mob/living/carbon/damage_procs.dm | 16 ++++---- code/modules/mob/living/carbon/human/dummy.dm | 5 ++- code/modules/mob/living/carbon/life.dm | 2 +- code/modules/mob/living/damage_procs.dm | 20 +++++----- code/modules/mob/living/living.dm | 4 +- code/modules/mob/living/living_defense.dm | 2 +- code/modules/mob/living/silicon/ai/life.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../mob/living/simple_animal/damage_procs.dm | 4 +- .../living/simple_animal/hostile/hostile.dm | 4 +- .../hostile/megafauna/colossus.dm | 6 +-- .../mob/living/simple_animal/simple_animal.dm | 6 +-- code/modules/mob/living/status_procs.dm | 10 ++--- code/modules/pai/pai.dm | 2 +- code/modules/power/tesla/energy_ball.dm | 4 +- .../crossbreeding/_status_effects.dm | 10 ++--- code/modules/shuttle/special.dm | 7 ++-- .../spells/spell_types/self/rod_form.dm | 6 +-- code/modules/surgery/bodyparts/_bodyparts.dm | 2 +- .../surgery/bodyparts/dismemberment.dm | 4 +- code/modules/surgery/bodyparts/wounds.dm | 4 +- .../organs/internal/_internal_organ.dm | 2 +- .../surgery/organs/internal/ears/_ears.dm | 4 +- .../surgery/organs/internal/lungs/_lungs.dm | 2 +- code/modules/unit_tests/mob_damage.dm | 8 ++-- code/modules/unit_tests/strange_reagent.dm | 2 +- .../death_consequences_trauma.dm | 2 +- .../modules/horrorform/code/horror_form.dm | 2 +- .../horrorform/code/true_changeling.dm | 4 +- 65 files changed, 175 insertions(+), 192 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 60cd3a7b018..439d803fb94 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -76,15 +76,12 @@ #define CANUNCONSCIOUS (1<<2) /// If set, this mob can be grabbed or pushed when bumped into #define CANPUSH (1<<3) -/// Mob godmode. Prevents most statuses and damage from being taken, but is more often than not a crapshoot. Use with caution. -#define GODMODE (1<<4) DEFINE_BITFIELD(status_flags, list( "CAN STUN" = CANSTUN, "CAN KNOCKDOWN" = CANKNOCKDOWN, "CAN UNCONSCIOUS" = CANUNCONSCIOUS, "CAN PUSH" = CANPUSH, - "GOD MODE" = GODMODE, )) //Health Defines diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index b9f733fb5bd..2794ffd3653 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -26,6 +26,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_RESTRAINED "restrained" /// Apply this to make a mob not dense, and remove it when you want it to no longer make them undense, other sources of undesity will still apply. Always define a unique source when adding a new instance of this! #define TRAIT_UNDENSE "undense" +/// Makes the mob immune to damage and several other ailments. +#define TRAIT_GODMODE "godmode" /// Expands our FOV by 30 degrees if restricted #define TRAIT_EXPANDED_FOV "expanded_fov" /// Doesn't miss attacks diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 2a3b1097844..760fb3912ad 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -263,6 +263,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GARLIC_BREATH" = TRAIT_GARLIC_BREATH, "TRAIT_GENELESS" = TRAIT_GENELESS, "TRAIT_GIANT" = TRAIT_GIANT, + "TRAIT_GODMODE" = TRAIT_GODMODE, "TRAIT_GONE_FISHING" = TRAIT_GONE_FISHING, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 67a7417b5e7..14f86941756 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -118,6 +118,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_GARLIC_BREATH" = TRAIT_GARLIC_BREATH, "TRAIT_GENELESS" = TRAIT_GENELESS, "TRAIT_GIANT" = TRAIT_GIANT, + "TRAIT_GODMODE" = TRAIT_GODMODE, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm index aa512b2d28e..2b07734b4a8 100644 --- a/code/datums/actions/mobs/lava_swoop.dm +++ b/code/datums/actions/mobs/lava_swoop.dm @@ -39,7 +39,7 @@ return // stop swooped target movement swooping = TRUE - ADD_TRAIT(owner, TRAIT_UNDENSE, SWOOPING_TRAIT) + owner.add_traits(list(TRAIT_GODMODE, TRAIT_UNDENSE), SWOOPING_TRAIT) owner.visible_message(span_boldwarning("[owner] swoops up high!")) var/negative @@ -66,7 +66,6 @@ animate(owner, alpha = 255, transform = oldtransform, time = 0, flags = ANIMATION_END_NOW) //reset immediately return animate(owner, alpha = 100, transform = matrix()*0.7, time = 7) - owner.status_flags |= GODMODE SEND_SIGNAL(owner, COMSIG_SWOOP_INVULNERABILITY_STARTED) owner.mouse_opacity = MOUSE_OPACITY_TRANSPARENT @@ -112,12 +111,11 @@ for(var/mob/observer in range(7, owner)) shake_camera(observer, 15, 1) - REMOVE_TRAIT(owner, TRAIT_UNDENSE, SWOOPING_TRAIT) + owner.remove_traits(list(TRAIT_GODMODE, TRAIT_UNDENSE), SWOOPING_TRAIT) SLEEP_CHECK_DEATH(1, owner) swooping = FALSE if(!lava_success) SEND_SIGNAL(owner, COMSIG_LAVA_ARENA_FAILED) - owner.status_flags &= ~GODMODE /datum/action/cooldown/mob_cooldown/lava_swoop/proc/lava_pools(atom/target, amount = 30, delay = 0.8) if(!target) diff --git a/code/datums/ai/basic_mobs/targeting_strategies/basic_targeting_strategy.dm b/code/datums/ai/basic_mobs/targeting_strategies/basic_targeting_strategy.dm index 709acb8d5e8..d552b69c142 100644 --- a/code/datums/ai/basic_mobs/targeting_strategies/basic_targeting_strategy.dm +++ b/code/datums/ai/basic_mobs/targeting_strategies/basic_targeting_strategy.dm @@ -25,8 +25,7 @@ if(ismob(the_target)) //Target is in godmode, ignore it. if(living_mob.loc == the_target) return FALSE // We've either been eaten or are shapeshifted, let's assume the latter because we're still alive - var/mob/M = the_target - if(M.status_flags & GODMODE) + if(HAS_TRAIT(the_target, TRAIT_GODMODE)) return FALSE if (vision_range && get_dist(living_mob, the_target) > vision_range) diff --git a/code/datums/components/area_based_godmode.dm b/code/datums/components/area_based_godmode.dm index 4f03ae57794..b9447efbafb 100644 --- a/code/datums/components/area_based_godmode.dm +++ b/code/datums/components/area_based_godmode.dm @@ -34,8 +34,6 @@ var/mob/mob_target = parent if(!istype(mob_target)) return COMPONENT_INCOMPATIBLE - if(initial(mob_target.status_flags) & GODMODE) - return COMPONENT_INCOMPATIBLE sources_to_area_type = list() src.gain_message = gain_message @@ -102,11 +100,11 @@ /datum/component/area_based_godmode/proc/check_area(mob/source) SIGNAL_HANDLER - var/has_godmode = source.status_flags & GODMODE + var/has_godmode = HAS_TRAIT(source, TRAIT_GODMODE) if(!check_in_valid_area(source)) if(has_godmode) to_chat(source, lose_message) - source.status_flags ^= GODMODE + REMOVE_TRAIT(source, TRAIT_GODMODE, REF(src)) check_area_cached_state = FALSE return @@ -115,7 +113,7 @@ return to_chat(source, gain_message) - source.status_flags ^= GODMODE + ADD_TRAIT(source, TRAIT_GODMODE, REF(src)) #undef MAP_AREA_TYPE #undef MAP_ALLOW_AREA_SUBTYPES diff --git a/code/datums/components/singularity.dm b/code/datums/components/singularity.dm index 14aaedff717..0cd64d829a2 100644 --- a/code/datums/components/singularity.dm +++ b/code/datums/components/singularity.dm @@ -373,7 +373,7 @@ for(var/mob/living/target as anything in GLOB.mob_living_list) if(target.z != atom_parent.z) continue - if(target.status_effects & GODMODE) + if(HAS_TRAIT(target, TRAIT_GODMODE)) continue var/distance_from_target = get_dist(target, atom_parent) if(distance_from_target < closest_distance) diff --git a/code/datums/components/soulstoned.dm b/code/datums/components/soulstoned.dm index bb22030c210..d4e9e0eaf02 100644 --- a/code/datums/components/soulstoned.dm +++ b/code/datums/components/soulstoned.dm @@ -11,8 +11,7 @@ stoned.forceMove(container) stoned.fully_heal() - stoned.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), SOULSTONE_TRAIT) - stoned.status_flags |= GODMODE + stoned.add_traits(list(TRAIT_GODMODE, TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), SOULSTONE_TRAIT) RegisterSignal(stoned, COMSIG_MOVABLE_MOVED, PROC_REF(free_prisoner)) @@ -25,5 +24,4 @@ /datum/component/soulstoned/UnregisterFromParent() var/mob/living/stoned = parent - stoned.status_flags &= ~GODMODE - stoned.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), SOULSTONE_TRAIT) + stoned.remove_traits(list(TRAIT_GODMODE, TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), SOULSTONE_TRAIT) diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm index 81a29b56c6d..53a0797c2e1 100644 --- a/code/datums/components/supermatter_crystal.dm +++ b/code/datums/components/supermatter_crystal.dm @@ -71,7 +71,7 @@ SIGNAL_HANDLER if(isliving(user)) var/mob/living/living_mob = user - if(living_mob.incorporeal_move || living_mob.status_flags & GODMODE) + if(living_mob.incorporeal_move || HAS_TRAIT(living_mob, TRAIT_GODMODE)) return if(isalien(user)) dust_mob(source, user, cause = "alien attack") @@ -80,7 +80,7 @@ /datum/component/supermatter_crystal/proc/animal_hit(datum/source, mob/living/simple_animal/user, list/modifiers) SIGNAL_HANDLER - if(user.incorporeal_move || user.status_flags & GODMODE) + if(user.incorporeal_move || HAS_TRAIT(user, TRAIT_GODMODE)) return var/atom/atom_source = source var/murder @@ -101,7 +101,7 @@ SIGNAL_HANDLER if(isliving(user)) var/mob/living/living_mob = user - if(living_mob.incorporeal_move || living_mob.status_flags & GODMODE) + if(living_mob.incorporeal_move || HAS_TRAIT(living_mob, TRAIT_GODMODE)) return var/atom/atom_source = source if(iscyborg(user) && atom_source.Adjacent(user)) @@ -115,7 +115,7 @@ /datum/component/supermatter_crystal/proc/hand_hit(datum/source, mob/living/user, list/modifiers) SIGNAL_HANDLER - if(user.incorporeal_move || user.status_flags & GODMODE) + if(user.incorporeal_move || HAS_TRAIT(user, TRAIT_GODMODE)) return if(user.zone_selected != BODY_ZONE_PRECISE_MOUTH) dust_mob(source, user, cause = "hand") @@ -202,7 +202,7 @@ return if(atom_source.Adjacent(user)) //if the item is stuck to the person, kill the person too instead of eating just the item. - if(user.incorporeal_move || user.status_flags & GODMODE) + if(user.incorporeal_move || HAS_TRAIT(user, TRAIT_GODMODE)) return var/vis_msg = span_danger("[user] reaches out and touches [atom_source] with [item], inducing a resonance... [item] starts to glow briefly before the light continues up to [user]'s body. [user.p_They()] burst[user.p_s()] into flames before flashing into dust!") var/mob_msg = span_userdanger("You reach out and touch [atom_source] with [item]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"") @@ -219,7 +219,7 @@ SIGNAL_HANDLER if(isliving(hit_object)) var/mob/living/hit_mob = hit_object - if(hit_mob.incorporeal_move || hit_mob.status_flags & GODMODE) + if(hit_mob.incorporeal_move || HAS_TRAIT(hit_mob, TRAIT_GODMODE)) return var/atom/atom_source = source var/obj/machinery/power/supermatter_crystal/our_supermatter = parent // Why is this a component? @@ -272,7 +272,7 @@ span_hear("You hear a loud crack as you are washed with a wave of heat.")) /datum/component/supermatter_crystal/proc/dust_mob(datum/source, mob/living/nom, vis_msg, mob_msg, cause) - if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too + if(nom.incorporeal_move || HAS_TRAIT(nom, TRAIT_GODMODE)) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too return var/atom/atom_source = source if(!vis_msg) @@ -290,10 +290,8 @@ /datum/component/supermatter_crystal/proc/consume(atom/source, atom/movable/consumed_object) if(consumed_object.flags_1 & SUPERMATTER_IGNORES_1) return - if(isliving(consumed_object)) - var/mob/living/consumed_mob = consumed_object - if(consumed_mob.status_flags & GODMODE) - return + if(HAS_TRAIT(consumed_object, TRAIT_GODMODE)) + return var/atom/atom_source = source SEND_SIGNAL(consumed_object, COMSIG_SUPERMATTER_CONSUMED, atom_source) diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 4a8bda37c3a..5217738dff6 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -46,7 +46,7 @@ if(blocked || !istype(victim) || HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) return FALSE - if(victim.status_flags & GODMODE) + if(HAS_TRAIT(victim, TRAIT_GODMODE)) return FALSE var/flying_speed = throwingdatum?.speed || weapon.throw_speed diff --git a/code/datums/shuttles/emergency.dm b/code/datums/shuttles/emergency.dm index 925dfc74d3d..63c617ff39a 100644 --- a/code/datums/shuttles/emergency.dm +++ b/code/datums/shuttles/emergency.dm @@ -91,7 +91,7 @@ suffix = "bar" name = "The Emergency Escape Bar" description = "Features include sentient bar staff (a Bardrone and a Barmaid), bathroom, a quality lounge for the heads, and a large gathering table." - admin_notes = "Bardrone and Barmaid are GODMODE, will be automatically sentienced by the fun balloon at 60 seconds before arrival. \ + admin_notes = "Bardrone and Barmaid have TRAIT_GODMODE (basically invincibility), will be automatically sentienced by the fun balloon at 60 seconds before arrival. \ Has medical facilities." credit_cost = CARGO_CRATE_VALUE * 10 occupancy_limit = "30" diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index d33d832b1fc..7b41d16755f 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -34,28 +34,28 @@ status_alarm(TRUE) -/datum/weather/rad_storm/weather_act(mob/living/L) +/datum/weather/rad_storm/weather_act(mob/living/living) if(!prob(mutate_chance)) return - if(!ishuman(L)) + if(!ishuman(living) || HAS_TRAIT(living, TRAIT_GODMODE)) return - var/mob/living/carbon/human/H = L - if(!H.can_mutate() || H.status_flags & GODMODE) + var/mob/living/carbon/human/human = living + if(!human.can_mutate()) return - if(HAS_TRAIT(H, TRAIT_RADIMMUNE)) + if(HAS_TRAIT(human, TRAIT_RADIMMUNE)) return - if (SSradiation.wearing_rad_protected_clothing(H)) + if (SSradiation.wearing_rad_protected_clothing(human)) return - H.random_mutate_unique_identity() - H.random_mutate_unique_features() + human.random_mutate_unique_identity() + human.random_mutate_unique_features() if(prob(50)) - do_mutate(L) + do_mutate(human) /datum/weather/rad_storm/end() if(..()) diff --git a/code/datums/wounds/_wound_static_data.dm b/code/datums/wounds/_wound_static_data.dm index f8b03d1856b..adc0923ee4f 100644 --- a/code/datums/wounds/_wound_static_data.dm +++ b/code/datums/wounds/_wound_static_data.dm @@ -95,7 +95,7 @@ if (random_roll && !can_be_randomly_generated) return FALSE - if (HAS_TRAIT(limb.owner, TRAIT_NEVER_WOUNDED) || (limb.owner.status_flags & GODMODE)) + if (HAS_TRAIT(limb.owner, TRAIT_NEVER_WOUNDED) || HAS_TRAIT(limb.owner, TRAIT_GODMODE)) return FALSE if (!wounding_types_valid(suggested_wounding_types)) diff --git a/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm b/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm index efa197de84b..d9796616023 100644 --- a/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm +++ b/code/game/objects/effects/anomalies/anomalies_bioscrambler.dm @@ -62,7 +62,7 @@ for(var/mob/living/carbon/target in GLOB.player_list) if (target.z != z) continue - if (target.status_flags & GODMODE) + if (HAS_TRAIT(target, TRAIT_GODMODE)) continue if (target.stat >= UNCONSCIOUS) continue // Don't just haunt a corpse diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index 76796356388..0b369b7a6d8 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -177,10 +177,8 @@ return if(target.resistance_flags & INDESTRUCTIBLE) //due to the lich incident of 2021, embedding grenades inside of indestructible structures is forbidden return - if(ismob(target)) - var/mob/mob_target = target - if(mob_target.status_flags & GODMODE) //no embedding grenade phylacteries inside of ghost poly either - return + if(HAS_TRAIT(target, TRAIT_GODMODE)) + return if(iseffect(target)) //and no accidentally wasting your moment of glory on graffiti return user.say("[war_cry]", forced="spear warcry") diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index e13251fe8e5..d51130a4d21 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -187,7 +187,7 @@ if(!isliving(hit_atom)) return ..() var/mob/living/victim = hit_atom - if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + if(victim.incorporeal_move || HAS_TRAIT(victim, TRAIT_GODMODE)) //try to keep this in sync with supermatter's consume fail conditions return ..() var/mob/thrower = throwingdatum?.get_thrower() if(thrower) @@ -208,7 +208,7 @@ /obj/item/nuke_core/supermatter_sliver/pickup(mob/living/user) ..() - if(!isliving(user) || user.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + if(!isliving(user) || HAS_TRAIT(user, TRAIT_GODMODE)) //try to keep this in sync with supermatter's consume fail conditions return FALSE user.visible_message(span_danger("[user] reaches out and tries to pick up [src]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!"),\ span_userdanger("You reach for [src] with your hands. That was dumb."),\ @@ -311,7 +311,7 @@ if(!isliving(AM)) return var/mob/living/victim = AM - if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions + if(victim.incorporeal_move || HAS_TRAIT(victim, TRAIT_GODMODE)) //try to keep this in sync with supermatter's consume fail conditions return victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) victim.dust() diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index 5383436d4db..d7fdfab74e2 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -13,24 +13,24 @@ /obj/structure/statue/petrified/relaymove() return -/obj/structure/statue/petrified/Initialize(mapload, mob/living/L, statue_timer, save_brain) +/obj/structure/statue/petrified/Initialize(mapload, mob/living/living, statue_timer, save_brain) . = ..() if(statue_timer) timer = statue_timer if(save_brain) brain = save_brain - if(L) - petrified_mob = L - if(L.buckled) - L.buckled.unbuckle_mob(L,force=1) - L.visible_message(span_warning("[L]'s skin rapidly turns to marble!"), span_userdanger("Your body freezes up! Can't... move... can't... think...")) - L.forceMove(src) - ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE) - L.faction |= FACTION_MIMIC //Stops mimics from instaqdeling people in statues - L.status_flags |= GODMODE - atom_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues - max_integrity = atom_integrity - START_PROCESSING(SSobj, src) + if(!living) + return + petrified_mob = living + if(living.buckled) + living.buckled.unbuckle_mob(living, force = TRUE) + living.visible_message(span_warning("[living]'s skin rapidly turns to marble!"), span_userdanger("Your body freezes up! Can't... move... can't... think...")) + living.forceMove(src) + living.add_traits(list(TRAIT_GODMODE, TRAIT_MUTE, TRAIT_NOBLOOD), STATUE_MUTE) + living.faction |= FACTION_MIMIC //Stops mimics from instaqdeling people in statues + atom_integrity = living.health + 100 //stoning damaged mobs will result in easier to shatter statues + max_integrity = atom_integrity + START_PROCESSING(SSobj, src) /obj/structure/statue/petrified/process(seconds_per_tick) if(!petrified_mob) @@ -47,6 +47,9 @@ /obj/structure/statue/petrified/Exited(atom/movable/gone, direction) . = ..() if(gone == petrified_mob) + petrified_mob.remove_traits(list(TRAIT_GODMODE, TRAIT_MUTE, TRAIT_NOBLOOD), STATUE_MUTE) + petrified_mob.take_overall_damage((petrified_mob.health - atom_integrity + 100)) //any new damage the statue incurred is transferred to the mob + petrified_mob.faction -= FACTION_MIMIC petrified_mob = null /obj/structure/statue/petrified/Destroy() @@ -64,13 +67,7 @@ for(var/obj/O in src) O.forceMove(loc) - if(petrified_mob) - petrified_mob.status_flags &= ~GODMODE - REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE) - REMOVE_TRAIT(petrified_mob, TRAIT_NOBLOOD, MAGIC_TRAIT) - petrified_mob.take_overall_damage((petrified_mob.health - atom_integrity + 100)) //any new damage the statue incurred is transferred to the mob - petrified_mob.faction -= FACTION_MIMIC - petrified_mob.forceMove(loc) + petrified_mob?.forceMove(loc) return ..() /obj/structure/statue/petrified/atom_deconstruct(disassembled = TRUE) diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index fdd00318ad3..76d814e8ee0 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -168,20 +168,24 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo user << browse(body, "window=adminplayeropts-[REF(player)];size=550x515") BLACKBOX_LOG_ADMIN_VERB("Player Panel") -/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list) +/client/proc/cmd_admin_godmode(mob/mob in GLOB.mob_list) set category = "Admin.Game" set name = "Godmode" if(!check_rights(R_ADMIN)) return - M.status_flags ^= GODMODE - to_chat(usr, span_adminnotice("Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"), confidential = TRUE) + var/had_trait = HAS_TRAIT_FROM(mob, TRAIT_GODMODE, ADMIN_TRAIT) + if(had_trait) + REMOVE_TRAIT(mob, TRAIT_GODMODE, ADMIN_TRAIT) + else + ADD_TRAIT(mob, TRAIT_GODMODE, ADMIN_TRAIT) + to_chat(usr, span_adminnotice("Toggled [had_trait ? "OFF" : "ON"]"), confidential = TRUE) - log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") - var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]" + log_admin("[key_name(usr)] has toggled [key_name(mob)]'s nodamage to [had_trait ? "Off" : "On"]") + var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(mob)]'s nodamage to [had_trait ? "Off" : "On"]" message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[M.status_flags & GODMODE ? "Enabled" : "Disabled"]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + admin_ticket_log(mob, msg) + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[had_trait ? "Disabled" : "Enabled"]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! /* If a guy was gibbed and you want to revive him, this is a good way to do so. diff --git a/code/modules/antagonists/heretic/status_effects/buffs.dm b/code/modules/antagonists/heretic/status_effects/buffs.dm index 1668ea5a11e..e4f5990040b 100644 --- a/code/modules/antagonists/heretic/status_effects/buffs.dm +++ b/code/modules/antagonists/heretic/status_effects/buffs.dm @@ -251,11 +251,10 @@ status_type = STATUS_EFFECT_REFRESH duration = -1 alert_type = null - var/static/list/caretaking_traits = list(TRAIT_HANDS_BLOCKED, TRAIT_IGNORESLOWDOWN, TRAIT_SECLUDED_LOCATION) + var/static/list/caretaking_traits = list(TRAIT_GODMODE, TRAIT_HANDS_BLOCKED, TRAIT_IGNORESLOWDOWN, TRAIT_SECLUDED_LOCATION) /datum/status_effect/caretaker_refuge/on_apply() owner.add_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id)) - owner.status_flags |= GODMODE animate(owner, alpha = 45,time = 0.5 SECONDS) owner.density = FALSE RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING), PROC_REF(on_focus_lost)) @@ -266,7 +265,6 @@ /datum/status_effect/caretaker_refuge/on_remove() owner.remove_traits(caretaking_traits, TRAIT_STATUS_EFFECT(id)) - owner.status_flags &= ~GODMODE owner.alpha = initial(owner.alpha) owner.density = initial(owner.density) UnregisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_ALLOW_HERETIC_CASTING)) diff --git a/code/modules/mafia/controller.dm b/code/modules/mafia/controller.dm index f6b46c3430d..d4edbb37f41 100644 --- a/code/modules/mafia/controller.dm +++ b/code/modules/mafia/controller.dm @@ -602,13 +602,18 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment()) outfit_to_distribute = player_outfit for(var/datum/mafia_role/role as anything in all_roles) - var/mob/living/carbon/human/H = new(get_turf(role.assigned_landmark)) - H.add_traits(list(TRAIT_NOFIRE, TRAIT_NOBREATH, TRAIT_CANNOT_CRYSTALIZE, TRAIT_PERMANENTLY_MORTAL), MAFIA_TRAIT) - H.equipOutfit(outfit_to_distribute) - H.status_flags |= GODMODE - RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes)) + var/mob/living/carbon/human/human = new(get_turf(role.assigned_landmark)) + human.add_traits(list( + TRAIT_NOFIRE, + TRAIT_NOBREATH, + TRAIT_CANNOT_CRYSTALIZE, + TRAIT_PERMANENTLY_MORTAL, + TRAIT_GODMODE, + ), MAFIA_TRAIT) + human.equipOutfit(outfit_to_distribute) + RegisterSignal(human, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes)) var/obj/item/modular_computer/modpc = role.player_pda - role.register_body(H) + role.register_body(human) if(modpc) player_role_lookup[modpc] = role else diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index 24131d776a2..a75043e7b55 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -425,8 +425,7 @@ if(!user) return - user.status_flags &= ~GODMODE - REMOVE_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src)) + user.remove_traits(list(TRAIT_GODMODE, TRAIT_NO_TRANSFORM), REF(src)) user.forceMove(get_turf(src)) user.visible_message(span_danger("[user] pops back into reality!")) @@ -437,8 +436,7 @@ setDir(user.dir) user.forceMove(src) - ADD_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src)) - user.status_flags |= GODMODE + user.add_traits(list(TRAIT_GODMODE, TRAIT_NO_TRANSFORM), REF(src)) user_ref = WEAKREF(user) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index b4ddc8cd9c8..2dc5db8fc02 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -4,7 +4,6 @@ density = FALSE move_force = INFINITY move_resist = INFINITY - status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT invisibility = INVISIBILITY_ABSTRACT // No one can see us sight = SEE_SELF @@ -15,6 +14,7 @@ /mob/camera/Initialize(mapload) . = ..() + ADD_TRAIT(src, TRAIT_GODMODE, INNATE_TRAIT) SSpoints_of_interest.make_point_of_interest(src) if(!move_on_shuttle) ADD_TRAIT(src, TRAIT_BLOCK_SHUTTLE_MOVEMENT, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index 646cabe339d..9a7ddef3ce0 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -159,7 +159,7 @@ ..() /mob/living/basic/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= 0) diff --git a/code/modules/mob/living/basic/drone/interaction.dm b/code/modules/mob/living/basic/drone/interaction.dm index 0b0247c1c45..58b7cd88ef2 100644 --- a/code/modules/mob/living/basic/drone/interaction.dm +++ b/code/modules/mob/living/basic/drone/interaction.dm @@ -32,7 +32,7 @@ return ..() /mob/living/basic/drone/mob_try_pickup(mob/living/user, instant=FALSE) - if(stat == DEAD || status_flags & GODMODE) + if(stat == DEAD || HAS_TRAIT(src, TRAIT_GODMODE)) return return ..() diff --git a/code/modules/mob/living/basic/health_adjustment.dm b/code/modules/mob/living/basic/health_adjustment.dm index bae9d7b9e57..ca98f98eb8e 100644 --- a/code/modules/mob/living/basic/health_adjustment.dm +++ b/code/modules/mob/living/basic/health_adjustment.dm @@ -4,12 +4,12 @@ * Arguments: * * amount The amount that will be used to adjust the mob's health * * updating_health If the mob's health should be immediately updated to the new value - * * forced If we should force update the adjustment of the mob's health no matter the restrictions, like GODMODE + * * forced If we should force update the adjustment of the mob's health no matter the restrictions, like TRAIT_GODMODE * returns the net change in bruteloss after applying the damage amount */ /mob/living/basic/proc/adjust_health(amount, updating_health = TRUE, forced = FALSE) . = FALSE - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return 0 . = bruteloss // bruteloss value before applying damage bruteloss = round(clamp(bruteloss + amount, 0, maxHealth * 2), DAMAGE_PRECISION) diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm index f023215d7dd..ca07c1a043e 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm @@ -19,14 +19,14 @@ return playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE) new /obj/effect/temp_visual/mook_dust(get_turf(burrower)) - burrower.status_flags |= GODMODE + ADD_TRAIT(burrower, TRAIT_GODMODE, REF(src)) burrower.SetInvisibility(INVISIBILITY_MAXIMUM, id=type) burrower.forceMove(unburrow_turf) //not that it's gonna die with godmode but still SLEEP_CHECK_DEATH(rand(0.7 SECONDS, 1.2 SECONDS), burrower) playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE) new /obj/effect/temp_visual/mook_dust(unburrow_turf) - burrower.status_flags &= ~GODMODE + REMOVE_TRAIT(burrower, TRAIT_GODMODE, REF(src)) burrower.RemoveInvisibility(type) /datum/action/cooldown/mob_cooldown/resurface/proc/get_unburrow_turf(mob/living/burrower, atom/target) @@ -108,14 +108,14 @@ return //this will give up on devouring the target which is fine by me playsound(devourer, 'sound/effects/break_stone.ogg', 50, TRUE) new /obj/effect/temp_visual/mook_dust(get_turf(devourer)) - devourer.status_flags |= GODMODE + ADD_TRAIT(devourer, TRAIT_GODMODE, REF(src)) devourer.SetInvisibility(INVISIBILITY_MAXIMUM, id=type) devourer.forceMove(devour_turf) //not that it's gonna die with godmode but still SLEEP_CHECK_DEATH(rand(0.7 SECONDS, 1.2 SECONDS), devourer) playsound(devourer, 'sound/effects/break_stone.ogg', 50, TRUE) new /obj/effect/temp_visual/mook_dust(devour_turf) - devourer.status_flags &= ~GODMODE + REMOVE_TRAIT(devourer, TRAIT_GODMODE, REF(src)) devourer.RemoveInvisibility(type) if(!(target in devour_turf)) to_chat(devourer, span_warning("Someone stole your dinner!")) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index cba3dd6e588..737ea2079b0 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -191,7 +191,6 @@ name = "The Ghost of Poly" desc = "Doomed to squawk the Earth." color = "#FFFFFF77" - status_flags = GODMODE sentience_type = SENTIENCE_BOSS //This is so players can't mindswap into ghost poly to become a literal god incorporeal_move = INCORPOREAL_MOVE_BASIC butcher_results = list(/obj/item/ectoplasm = 1) @@ -202,7 +201,7 @@ /mob/living/basic/parrot/poly/ghost/Initialize(mapload) // block anything and everything that could possibly happen with writing memory for ghosts memory_saved = TRUE - ADD_TRAIT(src, TRAIT_DONT_WRITE_MEMORY, INNATE_TRAIT) + add_traits(list(TRAIT_GODMODE, TRAIT_DONT_WRITE_MEMORY), INNATE_TRAIT) RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) return ..() diff --git a/code/modules/mob/living/basic/ruin_defender/living_floor.dm b/code/modules/mob/living/basic/ruin_defender/living_floor.dm index 105838f0c55..c84e602659b 100644 --- a/code/modules/mob/living/basic/ruin_defender/living_floor.dm +++ b/code/modules/mob/living/basic/ruin_defender/living_floor.dm @@ -26,7 +26,6 @@ icon_living = "floor" mob_size = MOB_SIZE_HUGE mob_biotypes = MOB_SPECIAL - status_flags = GODMODE //nothing but crowbars may kill us death_message = "" unsuitable_atmos_damage = 0 minimum_survivable_temperature = 0 @@ -52,7 +51,7 @@ /mob/living/basic/living_floor/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_IMMOBILIZED, INNATE_TRAIT) + add_traits(list(TRAIT_GODMODE, TRAIT_IMMOBILIZED), INNATE_TRAIT) //nothing but crowbars may kill us var/static/list/connections = list(COMSIG_ATOM_ENTERED = PROC_REF(look_aggro), COMSIG_ATOM_EXITED = PROC_REF(look_deaggro)) AddComponent(/datum/component/connect_range, tracked = src, connections = connections, range = 1, works_in_containers = FALSE) diff --git a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm index f4a1267e9db..9080e040f51 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm @@ -94,12 +94,11 @@ /mob/living/basic/bear/snow/ancient name = "ancient polar bear" desc = "A grizzled old polar bear, its hide thick enough to make it impervious to almost all weapons." - status_flags = CANPUSH | GODMODE gold_core_spawnable = NO_SPAWN /mob/living/basic/bear/snow/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_SNOWSTORM_IMMUNE, INNATE_TRAIT) + add_traits(list(TRAIT_GODMODE, TRAIT_SNOWSTORM_IMMUNE), INNATE_TRAIT) /mob/living/basic/bear/russian name = "combat bear" diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm index bba6e0eb460..a25b3c52ad8 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm @@ -58,13 +58,12 @@ return FALSE RegisterSignal(fugu, COMSIG_MOB_STATCHANGE, PROC_REF(check_death)) fugu.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/inflated) - ADD_TRAIT(fugu, TRAIT_FUGU_GLANDED, TRAIT_STATUS_EFFECT(id)) + fugu.add_traits(list(TRAIT_FUGU_GLANDED, TRAIT_GODMODE), TRAIT_STATUS_EFFECT(id)) fugu.AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE) fugu.mob_size = MOB_SIZE_LARGE fugu.icon_state = "Fugu1" fugu.melee_damage_lower = 15 fugu.melee_damage_upper = 20 - fugu.status_flags |= GODMODE fugu.obj_damage = 60 fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) fugu.ai_controller.CancelActions() @@ -76,12 +75,11 @@ return // Check again in case you changed mob after application but somehow kept the status effect UnregisterSignal(fugu, COMSIG_MOB_STATCHANGE) fugu.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/inflated) - REMOVE_TRAIT(fugu, TRAIT_FUGU_GLANDED, TRAIT_STATUS_EFFECT(id)) + fugu.remove_traits(list(TRAIT_FUGU_GLANDED, TRAIT_GODMODE), TRAIT_STATUS_EFFECT(id)) fugu.RemoveElement(/datum/element/wall_tearer, allow_reinforced = FALSE) fugu.mob_size = MOB_SIZE_SMALL fugu.melee_damage_lower = 0 fugu.melee_damage_upper = 0 - fugu.status_flags &= ~GODMODE if (fugu.stat != DEAD) fugu.icon_state = "Fugu0" fugu.obj_damage = 0 diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index eb86fd928eb..49a56cc1738 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -122,7 +122,7 @@ //Makes a blood drop, leaking amt units of blood from the mob /mob/living/carbon/proc/bleed(amt) - if(!blood_volume || (status_flags & GODMODE)) + if(!blood_volume || HAS_TRAIT(src, TRAIT_GODMODE)) return blood_volume = max(blood_volume - amt, 0) diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm index 9bebeac70ec..7ffe49951ec 100644 --- a/code/modules/mob/living/brain/life.dm +++ b/code/modules/mob/living/brain/life.dm @@ -14,7 +14,7 @@ handle_emp_damage(seconds_per_tick, times_fired) /mob/living/brain/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(health > HEALTH_THRESHOLD_DEAD) return diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 147079ae720..52f7b8dfc47 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -11,7 +11,7 @@ /mob/living/carbon/alien/larva/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= -maxHealth || !get_organ_by_type(/obj/item/organ/internal/brain)) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index f7ecd307517..7bd7d7aec49 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -3,7 +3,7 @@ return..() /mob/living/carbon/alien/check_breath(datum/gas_mixture/breath) - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(!breath || (breath.total_moles() == 0)) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 1d2371beae9..5a957754543 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -556,7 +556,7 @@ //Updates the mob's health from bodyparts and mob damage variables /mob/living/carbon/updatehealth() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/total_burn = 0 var/total_brute = 0 @@ -841,7 +841,7 @@ /mob/living/carbon/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= HEALTH_THRESHOLD_DEAD && !HAS_TRAIT(src, TRAIT_NODEATH)) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index b781b296bc8..2b50c215f89 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -103,7 +103,7 @@ . = heal_overall_damage(brute = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced) /mob/living/carbon/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE var/current = getBruteLoss() var/diff = amount - current @@ -120,7 +120,7 @@ . = heal_overall_damage(burn = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced) /mob/living/carbon/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE var/current = getFireLoss() var/diff = amount - current @@ -150,7 +150,7 @@ apply_status_effect(/datum/status_effect/incapacitating/stamcrit) /** - * If an organ exists in the slot requested, and we are capable of taking damage (we don't have [GODMODE] on), call the damage proc on that organ. + * If an organ exists in the slot requested, and we are capable of taking damage (we don't have TRAIT_GODMODE), call the damage proc on that organ. * * Arguments: * * slot - organ slot, like [ORGAN_SLOT_HEART] @@ -162,14 +162,14 @@ */ /mob/living/carbon/adjustOrganLoss(slot, amount, maximum, required_organ_flag = NONE) var/obj/item/organ/affected_organ = get_organ_slot(slot) - if(!affected_organ || (status_flags & GODMODE)) + if(!affected_organ || HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag)) return FALSE return affected_organ.apply_organ_damage(amount, maximum) /** - * If an organ exists in the slot requested, and we are capable of taking damage (we don't have [GODMODE] on), call the set damage proc on that organ, which can + * If an organ exists in the slot requested, and we are capable of taking damage (we don't have TRAIT_GODMODE), call the set damage proc on that organ, which can * set or clear the failing variable on that organ, making it either cease or start functions again, unlike adjustOrganLoss. * * Arguments: @@ -181,7 +181,7 @@ */ /mob/living/carbon/setOrganLoss(slot, amount, required_organ_flag = NONE) var/obj/item/organ/affected_organ = get_organ_slot(slot) - if(!affected_organ || (status_flags & GODMODE)) + if(!affected_organ || HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag)) return FALSE @@ -267,7 +267,7 @@ */ /mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE) . = FALSE - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_bodytype) if(!parts.len) @@ -314,7 +314,7 @@ /mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype) . = FALSE - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return // treat negative args as positive brute = abs(brute) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index a06582105f6..d11e0a3ffa8 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -1,13 +1,16 @@ /mob/living/carbon/human/dummy real_name = "Test Dummy" - status_flags = GODMODE|CANPUSH mouse_drag_pointer = MOUSE_INACTIVE_POINTER visual_only_organs = TRUE var/in_use = FALSE INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) +/mob/living/carbon/human/dummy/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_GODMODE, INNATE_TRAIT) + /mob/living/carbon/human/dummy/Destroy() in_use = FALSE return ..() diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 8aac728b8ce..28c9e987c46 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -183,7 +183,7 @@ /mob/living/carbon/proc/check_breath(datum/gas_mixture/breath) . = TRUE - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) failed_last_breath = FALSE clear_alert(ALERT_NOT_ENOUGH_OXYGEN) return diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 5382b1aebf6..7a3af83d283 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -268,7 +268,7 @@ return bruteloss /mob/living/proc/can_adjust_brute_loss(amount, forced, required_bodytype) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, BRUTE, amount, forced) & COMPONENT_IGNORE_CHANGE) return FALSE @@ -287,7 +287,7 @@ /mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE . = bruteloss bruteloss = amount @@ -303,7 +303,7 @@ /mob/living/proc/can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type) if(!forced) - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if (required_respiration_type) var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS) @@ -330,7 +330,7 @@ /mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL) if(!forced) - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS) @@ -352,7 +352,7 @@ return toxloss /mob/living/proc/can_adjust_tox_loss(amount, forced, required_biotype = ALL) - if(!forced && ((status_flags & GODMODE) || !(mob_biotypes & required_biotype))) + if(!forced && (HAS_TRAIT(src, TRAIT_GODMODE) || !(mob_biotypes & required_biotype))) return FALSE if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_TOX_DAMAGE, TOX, amount, forced) & COMPONENT_IGNORE_CHANGE) return FALSE @@ -387,7 +387,7 @@ /mob/living/proc/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if(!forced && !(mob_biotypes & required_biotype)) return FALSE @@ -403,7 +403,7 @@ return fireloss /mob/living/proc/can_adjust_fire_loss(amount, forced, required_bodytype) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return FALSE if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BURN_DAMAGE, BURN, amount, forced) & COMPONENT_IGNORE_CHANGE) return FALSE @@ -421,7 +421,7 @@ updatehealth() /mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return 0 . = fireloss fireloss = amount @@ -444,7 +444,7 @@ return staminaloss /mob/living/proc/can_adjust_stamina_loss(amount, forced, required_biotype = ALL) - if(!forced && (!(mob_biotypes & required_biotype) || status_flags & GODMODE)) + if(!forced && (!(mob_biotypes & required_biotype) || HAS_TRAIT(src, TRAIT_GODMODE))) return FALSE if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, STAMINA, amount, forced) & COMPONENT_IGNORE_CHANGE) return FALSE @@ -466,7 +466,7 @@ return delta /mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL) - if(!forced && (status_flags & GODMODE)) + if(!forced && HAS_TRAIT(src, TRAIT_GODMODE)) return 0 if(!forced && !(mob_biotypes & required_biotype)) return 0 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 166b8f1b5b0..a086755d6ab 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -849,7 +849,7 @@ /mob/living/proc/updatehealth() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return set_health(maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()) update_stat() @@ -1517,7 +1517,7 @@ * Returns a mob (what our mob turned into) or null (if we failed). */ /mob/living/proc/wabbajack(what_to_randomize, change_flags = WABBAJACK) - if(stat == DEAD || (GODMODE & status_flags) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) + if(stat == DEAD || HAS_TRAIT(src, TRAIT_GODMODE) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return if(SEND_SIGNAL(src, COMSIG_LIVING_PRE_WABBAJACKED, what_to_randomize) & STOP_WABBAJACK) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 1d3e33a5c4e..f2838d128d2 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -542,7 +542,7 @@ return 20 /mob/living/narsie_act() - if(status_flags & GODMODE || QDELETED(src)) + if(HAS_TRAIT(src, TRAIT_GODMODE) || QDELETED(src)) return if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src]) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index b11f125d38c..34aa7a0714a 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -47,7 +47,7 @@ return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha))) /mob/living/silicon/ai/updatehealth() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/old_health = health @@ -63,7 +63,7 @@ SEND_SIGNAL(src, COMSIG_LIVING_HEALTH_UPDATE) /mob/living/silicon/ai/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= HEALTH_THRESHOLD_DEAD) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 413a30fa89f..ccbdd81bfb0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -674,7 +674,7 @@ return ..() /mob/living/silicon/robot/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= -maxHealth) //die only once diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index 7a8a2fcb63b..075b40afeeb 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -4,11 +4,11 @@ * Arguments: * * amount The amount that will be used to adjust the mob's health * * updating_health If the mob's health should be immediately updated to the new value - * * forced If we should force update the adjustment of the mob's health no matter the restrictions, like GODMODE + * * forced If we should force update the adjustment of the mob's health no matter the restrictions, like TRAIT_GODMODE */ /mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE) . = FALSE - if(forced || !(status_flags & GODMODE)) + if(forced || !HAS_TRAIT(src, TRAIT_GODMODE)) bruteloss = round(clamp(bruteloss + amount, 0, maxHealth * 2), DAMAGE_PRECISION) if(updating_health) updatehealth() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 5574ca62880..ef67b1775b3 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -254,8 +254,8 @@ return FALSE if(ismob(the_target)) //Target is in godmode, ignore it. - var/mob/M = the_target - if(M.status_flags & GODMODE) + var/mob/mob = the_target + if(HAS_TRAIT(mob, TRAIT_GODMODE)) return FALSE if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index d09de265dda..3cfc4e7dd35 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -527,8 +527,7 @@ . = ..() if(isliving(arrived) && holder_animal) var/mob/living/possessor = arrived - possessor.add_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), STASIS_MUTE) - possessor.status_flags |= GODMODE + possessor.add_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM, TRAIT_GODMODE), STASIS_MUTE) possessor.mind.transfer_to(holder_animal) var/datum/action/exit_possession/escape = new(holder_animal) escape.Grant(holder_animal) @@ -536,8 +535,7 @@ /obj/structure/closet/stasis/dump_contents(kill = TRUE) for(var/mob/living/possessor in src) - possessor.remove_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM), STASIS_MUTE) - possessor.status_flags &= ~GODMODE + possessor.remove_traits(list(TRAIT_UNDENSE, TRAIT_NO_TRANSFORM, TRAIT_GODMODE), STASIS_MUTE) if(kill || !isanimal_or_basicmob(loc)) possessor.investigate_log("has died from [src].", INVESTIGATE_DEATHS) possessor.death(FALSE) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 9d5041fe870..179b50710c1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -234,7 +234,7 @@ . += "There appears to be [icon2html(access_card, user)] \a [access_card] pinned to [p_them()]." /mob/living/simple_animal/update_stat() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return if(stat != DEAD) if(health <= 0) @@ -389,8 +389,8 @@ if(see_invisible < the_target.invisibility) return FALSE if(ismob(the_target)) - var/mob/M = the_target - if(M.status_flags & GODMODE) + var/mob/mob = the_target + if(HAS_TRAIT(mob, TRAIT_GODMODE)) return FALSE if (isliving(the_target)) var/mob/living/L = the_target diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index c0e2058f23e..7bf067c7a12 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -10,7 +10,7 @@ /mob/living/proc/check_stun_immunity(check_flags = CANSTUN, force_stun = FALSE) SHOULD_CALL_PARENT(TRUE) - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return TRUE if(force_stun) // Does not take priority over god mode? I guess @@ -385,7 +385,7 @@ /mob/living/proc/Sleeping(amount) //Can't go below remaining duration if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount) & COMPONENT_NO_STUN) return - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(S) @@ -397,7 +397,7 @@ /mob/living/proc/SetSleeping(amount) //Sets remaining duration if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount) & COMPONENT_NO_STUN) return - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(amount <= 0) @@ -412,7 +412,7 @@ /mob/living/proc/AdjustSleeping(amount) //Adds to remaining duration if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, amount) & COMPONENT_NO_STUN) return - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(S) @@ -425,7 +425,7 @@ /mob/living/proc/PermaSleeping() if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_SLEEP, -1) & COMPONENT_NO_STUN) return - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return var/datum/status_effect/incapacitating/sleeping/S = IsSleeping() if(S) diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index 6e9d0693286..9ae21ab82db 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -251,7 +251,7 @@ return radio.screwdriver_act(user, tool) /mob/living/silicon/pai/updatehealth() - if(status_flags & GODMODE) + if(HAS_TRAIT(src, TRAIT_GODMODE)) return set_health(maxHealth - getBruteLoss() - getFireLoss()) update_stat() diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 0e41a7d6e86..8ae8644b306 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -187,8 +187,8 @@ /obj/energy_ball/proc/dust_mobs(atom/A) if(isliving(A)) - var/mob/living/L = A - if(L.incorporeal_move || L.status_flags & GODMODE) + var/mob/living/living = A + if(living.incorporeal_move || HAS_TRAIT(living, TRAIT_GODMODE)) return if(!iscarbon(A)) return diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 832d266723d..227f1be5165 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -11,8 +11,7 @@ var/originalcolor /datum/status_effect/rainbow_protection/on_apply() - owner.status_flags |= GODMODE - ADD_TRAIT(owner, TRAIT_PACIFISM, /datum/status_effect/rainbow_protection) + owner.add_traits(list(TRAIT_GODMODE, TRAIT_PACIFISM), TRAIT_STATUS_EFFECT(id)) owner.visible_message(span_warning("[owner] shines with a brilliant rainbow light."), span_notice("You feel protected by an unknown force!")) originalcolor = owner.color @@ -23,9 +22,8 @@ return ..() /datum/status_effect/rainbow_protection/on_remove() - owner.status_flags &= ~GODMODE owner.color = originalcolor - REMOVE_TRAIT(owner, TRAIT_PACIFISM, /datum/status_effect/rainbow_protection) + owner.remove_traits(list(TRAIT_GODMODE, TRAIT_PACIFISM), TRAIT_STATUS_EFFECT(id)) owner.visible_message(span_notice("[owner] stops glowing, the rainbow light fading away."), span_warning("You no longer feel protected...")) @@ -106,7 +104,7 @@ RegisterSignal(owner, COMSIG_LIVING_RESIST, PROC_REF(breakCube)) cube = new /obj/structure/ice_stasis(get_turf(owner)) owner.forceMove(cube) - owner.status_flags |= GODMODE + ADD_TRAIT(owner, TRAIT_GODMODE, TRAIT_STATUS_EFFECT(id)) return ..() /datum/status_effect/frozenstasis/tick(seconds_between_ticks) @@ -121,7 +119,7 @@ /datum/status_effect/frozenstasis/on_remove() if(cube) qdel(cube) - owner.status_flags &= ~GODMODE + REMOVE_TRAIT(owner, TRAIT_GODMODE, TRAIT_STATUS_EFFECT(id)) UnregisterSignal(owner, COMSIG_LIVING_RESIST) /datum/status_effect/slime_clone diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 484fa32ac87..3cbe494c8d0 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -153,9 +153,10 @@ /obj/structure/table/abductor/wabbajack/right desc = "It wakes so you may sleep." -// Bar staff, GODMODE mobs(as long as they stay in the shuttle) that just want to make sure people have drinks -// and a good time. - +/** + * Bar staff, mobs with the TRAIT_GODMODE trait (as long as they stay in the shuttle) + * that just want to make sure people have drinks and a good shuttle time. + */ /mob/living/basic/drone/snowflake/bardrone name = "Bardrone" desc = "A barkeeping drone, a robot built to tend bars." diff --git a/code/modules/spells/spell_types/self/rod_form.dm b/code/modules/spells/spell_types/self/rod_form.dm index 9989c4420c0..6f26ab16719 100644 --- a/code/modules/spells/spell_types/self/rod_form.dm +++ b/code/modules/spells/spell_types/self/rod_form.dm @@ -138,8 +138,7 @@ our_wizard = WEAKREF(wizard) wizard.forceMove(src) - wizard.status_flags |= GODMODE - wizard.add_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src)) + wizard.add_traits(list(TRAIT_GODMODE, TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src)) /** * Eject our current wizard, removing them from the rod @@ -150,8 +149,7 @@ if(QDELETED(wizard)) return - wizard.status_flags &= ~GODMODE - wizard.remove_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src)) + wizard.remove_traits(list(TRAIT_GODMODE, TRAIT_MAGICALLY_PHASED, TRAIT_NO_TRANSFORM), REF(src)) wizard.forceMove(get_turf(src)) our_wizard = null diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 2958eb02758..c79d3dacea4 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -478,7 +478,7 @@ return FALSE if (!forced) if(!isnull(owner)) - if (owner.status_flags & GODMODE) + if (HAS_TRAIT(owner, TRAIT_GODMODE)) return FALSE if (SEND_SIGNAL(owner, COMSIG_CARBON_LIMB_DAMAGED, src, brute, burn) & COMPONENT_PREVENT_LIMB_DAMAGE) return FALSE diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 24579e32748..77cf0cc53d5 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -9,9 +9,7 @@ if(!owner || (bodypart_flags & BODYPART_UNREMOVABLE)) return FALSE var/mob/living/carbon/limb_owner = owner - if(limb_owner.status_flags & GODMODE) - return FALSE - if(HAS_TRAIT(limb_owner, TRAIT_NODISMEMBER)) + if(HAS_TRAIT(limb_owner, TRAIT_GODMODE) || HAS_TRAIT(limb_owner, TRAIT_NODISMEMBER)) return FALSE var/obj/item/bodypart/affecting = limb_owner.get_bodypart(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/bodyparts/wounds.dm b/code/modules/surgery/bodyparts/wounds.dm index 93d61b091d9..fa1f9a9c5d2 100644 --- a/code/modules/surgery/bodyparts/wounds.dm +++ b/code/modules/surgery/bodyparts/wounds.dm @@ -2,7 +2,7 @@ /obj/item/bodypart/proc/painless_wound_roll(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=NONE) SHOULD_CALL_PARENT(TRUE) - if(!owner || wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND || (owner.status_flags & GODMODE)) + if(!owner || wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND || HAS_TRAIT(owner, TRAIT_GODMODE)) return var/mangled_state = get_mangled_state() @@ -52,7 +52,7 @@ SHOULD_CALL_PARENT(TRUE) RETURN_TYPE(/datum/wound) - if(HAS_TRAIT(owner, TRAIT_NEVER_WOUNDED) || (owner.status_flags & GODMODE)) + if(HAS_TRAIT(owner, TRAIT_NEVER_WOUNDED) || HAS_TRAIT(owner, TRAIT_GODMODE)) return // note that these are fed into an exponent, so these are magnified diff --git a/code/modules/surgery/organs/internal/_internal_organ.dm b/code/modules/surgery/organs/internal/_internal_organ.dm index 9f67fb3d899..8b7bd354931 100644 --- a/code/modules/surgery/organs/internal/_internal_organ.dm +++ b/code/modules/surgery/organs/internal/_internal_organ.dm @@ -17,7 +17,7 @@ /obj/item/organ/internal/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE) . = ..() - if((organ_flags & ORGAN_VITAL) && !special && !(organ_owner.status_flags & GODMODE)) + if((organ_flags & ORGAN_VITAL) && !special && !HAS_TRAIT(organ_owner, TRAIT_GODMODE)) if(organ_owner.stat != DEAD) organ_owner.investigate_log("has been killed by losing a vital organ ([src]).", INVESTIGATE_DEATHS) organ_owner.death() diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm index 3f7153638db..74d951ca4ed 100644 --- a/code/modules/surgery/organs/internal/ears/_ears.dm +++ b/code/modules/surgery/organs/internal/ears/_ears.dm @@ -65,7 +65,7 @@ * * ddeaf: Handles temporary deafness, 1 ddeaf = 2 seconds of deafness, by default (with no multiplier) */ /obj/item/organ/internal/ears/proc/adjustEarDamage(ddmg = 0, ddeaf = 0) - if(owner.status_flags & GODMODE) + if(HAS_TRAIT(owner, TRAIT_GODMODE)) update_temp_deafness() return @@ -86,7 +86,7 @@ if(isnull(owner)) return - if(owner.status_flags & GODMODE) + if(HAS_TRAIT(owner, TRAIT_GODMODE)) deaf = 0 if(deaf > 0) diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 8ff46b42352..afe29544c92 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -593,7 +593,7 @@ * * breather: A carbon mob that is using the lungs to breathe. */ /obj/item/organ/internal/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/breather) - if(breather.status_flags & GODMODE) + if(HAS_TRAIT(breather, TRAIT_GODMODE)) breather.failed_last_breath = FALSE breather.clear_alert(ALERT_NOT_ENOUGH_OXYGEN) return FALSE diff --git a/code/modules/unit_tests/mob_damage.dm b/code/modules/unit_tests/mob_damage.dm index 64b12b8f477..7496eb64434 100644 --- a/code/modules/unit_tests/mob_damage.dm +++ b/code/modules/unit_tests/mob_damage.dm @@ -289,8 +289,8 @@ /datum/unit_test/mob_damage/proc/test_godmode(mob/living/carbon/human/consistent/dummy) // Heal up, so that errors from the previous tests we won't cause this one to fail dummy.fully_heal(HEAL_DAMAGE) - // flip godmode bit to 1 - dummy.status_flags ^= GODMODE + // add godmode + ADD_TRAIT(dummy, TRAIT_GODMODE, TRAIT_GENERIC) // Apply 9 damage and then heal it if(!test_apply_damage(dummy, amount = 9, expected = 0)) @@ -306,8 +306,8 @@ if(!test_apply_damage(dummy, amount = -11, forced = TRUE)) TEST_FAIL("ABOVE FAILURE: failed test_godmode! godmode did not respect forced = TRUE") - // flip godmode bit back to 0 - dummy.status_flags ^= GODMODE + // remove godmode + REMOVE_TRAIT(dummy, TRAIT_GODMODE, TRAIT_GENERIC) /// Testing biotypes /datum/unit_test/mob_damage/proc/test_biotypes(mob/living/carbon/human/consistent/dummy) diff --git a/code/modules/unit_tests/strange_reagent.dm b/code/modules/unit_tests/strange_reagent.dm index e5e385b86fd..bcdf89f0a9c 100644 --- a/code/modules/unit_tests/strange_reagent.dm +++ b/code/modules/unit_tests/strange_reagent.dm @@ -24,7 +24,7 @@ var/is_basic = istype(target, /mob/living/basic) var/is_simple = istype(target, /mob/living/simple_animal) // check some basic stuff - if(target.status_flags & GODMODE) + if(HAS_TRAIT(target, TRAIT_GODMODE)) continue if(!(target.mob_biotypes & MOB_ORGANIC)) continue diff --git a/modular_nova/modules/death_consequences_perk/death_consequences_trauma.dm b/modular_nova/modules/death_consequences_perk/death_consequences_trauma.dm index 8693edf68a8..70ec68d57e7 100644 --- a/modular_nova/modules/death_consequences_perk/death_consequences_trauma.dm +++ b/modular_nova/modules/death_consequences_perk/death_consequences_trauma.dm @@ -184,7 +184,7 @@ last_time_degraded_on_death = world.time /datum/brain_trauma/severe/death_consequences/process(seconds_per_tick) - if (owner.status_flags & GODMODE) + if (HAS_TRAIT(owner, TRAIT_GODMODE)) return var/is_dead = (owner.stat == DEAD) diff --git a/modular_nova/modules/horrorform/code/horror_form.dm b/modular_nova/modules/horrorform/code/horror_form.dm index 767a73e455f..e48f0cf9451 100644 --- a/modular_nova/modules/horrorform/code/horror_form.dm +++ b/modular_nova/modules/horrorform/code/horror_form.dm @@ -65,7 +65,7 @@ new_mob.name = new_mob.real_name new_mob.stored_changeling = user user.loc = new_mob - user.status_flags |= GODMODE + ADD_TRAIT(user, TRAIT_GODMODE, "Changeling_True_Form") user.mind.transfer_to(new_mob) user.spawn_gibs() //feedback_add_details("changeling_powers","HF") diff --git a/modular_nova/modules/horrorform/code/true_changeling.dm b/modular_nova/modules/horrorform/code/true_changeling.dm index 604e7543a18..b09e1353f07 100644 --- a/modular_nova/modules/horrorform/code/true_changeling.dm +++ b/modular_nova/modules/horrorform/code/true_changeling.dm @@ -126,7 +126,7 @@ mind.transfer_to(stored_changeling) stored_changeling.Paralyze(10 SECONDS) //Make them helpless for 10 seconds stored_changeling.adjustBruteLoss(30, TRUE, TRUE) - stored_changeling.status_flags &= ~GODMODE + REMOVE_TRAIT(stored_changeling, TRAIT_GODMODE, "Changeling_True_Form") stored_changeling.emote("scream") stored_changeling.gib() stored_changeling = null @@ -201,7 +201,7 @@ horrorform.stored_changeling.loc = get_turf(horrorform) horrorform.mind.transfer_to(horrorform.stored_changeling) horrorform.stored_changeling.Stun(2 SECONDS) - horrorform.stored_changeling.status_flags &= ~GODMODE + REMOVE_TRAIT(horrorform.stored_changeling, TRAIT_GODMODE, "Changeling_True_Form") qdel(horrorform) return TRUE From 3e2fe7cc6961ad6a4e273882e99526771ec149a4 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:49:48 +0200 Subject: [PATCH 054/142] Fish sources are more thoroughfully stressed during unit tests. (#86637) ## About The Pull Request The profound fisher component (for both mobs and gloves) as well as the proc responsible for rolling rewards are now being tested too. This is something I've meant to do in a while, #86633 just happened to kick it off now. ## Why It's Good For The Game More tests, fewer mistakes flying under the radar. ## Changelog N/A --- code/datums/components/fishing_spot.dm | 1 + code/datums/components/profound_fisher.dm | 29 +++++++------ code/modules/fishing/fish/_fish.dm | 4 +- code/modules/unit_tests/fish_unit_tests.dm | 47 ++++++++++++++++++++-- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 816d940487f..6ecea18976c 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -24,6 +24,7 @@ /datum/component/fishing_spot/Destroy() fish_source.on_fishing_spot_del(src) fish_source = null + REMOVE_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) return ..() /datum/component/fishing_spot/proc/handle_cast(datum/source, obj/item/fishing_rod/rod, mob/user) diff --git a/code/datums/components/profound_fisher.dm b/code/datums/components/profound_fisher.dm index 3766d32b14a..6f656cd2542 100644 --- a/code/datums/components/profound_fisher.dm +++ b/code/datums/components/profound_fisher.dm @@ -64,9 +64,12 @@ /datum/component/profound_fisher/proc/on_unarmed_attack(mob/living/source, atom/attack_target, proximity_flag, list/modifiers) SIGNAL_HANDLER - if(!source.client || !should_fish_on(source, attack_target)) + if(!should_fish_on(source, attack_target)) return - INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, attack_target) + if(source.client) + INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, attack_target) + else + INVOKE_ASYNC(src, PROC_REF(pretend_fish), source, attack_target) return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/profound_fisher/proc/pre_attack(mob/living/source, atom/target) @@ -77,7 +80,7 @@ if(source.client) INVOKE_ASYNC(src, PROC_REF(begin_fishing), source, target) else - INVOKE_ASYNC(src, PROC_REF(pretend_fish), target) + INVOKE_ASYNC(src, PROC_REF(pretend_fish), source, target) return COMPONENT_HOSTILE_NO_ATTACK /datum/component/profound_fisher/proc/should_fish_on(mob/living/user, atom/target) @@ -102,9 +105,8 @@ REMOVE_TRAIT(source, TRAIT_PROFOUND_FISHER, TRAIT_GENERIC) UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING)) -/datum/component/profound_fisher/proc/pretend_fish(atom/target) - var/mob/living/living_parent = parent - if(DOING_INTERACTION_WITH_TARGET(living_parent, target)) +/datum/component/profound_fisher/proc/pretend_fish(mob/living/source, atom/target) + if(DOING_INTERACTION_WITH_TARGET(source, target)) return var/list/fish_spot_container[NPC_FISHING_SPOT] SEND_SIGNAL(target, COMSIG_NPC_FISHING, fish_spot_container) @@ -113,13 +115,14 @@ return null var/obj/effect/fishing_float/float = new(get_turf(target), target) playsound(float, 'sound/effects/splash.ogg', 100) - var/happiness_percentage = living_parent.ai_controller?.blackboard[BB_BASIC_HAPPINESS] / 100 - var/fishing_speed = 10 SECONDS - round(4 SECONDS * happiness_percentage) - if(!do_after(living_parent, fishing_speed, target = target) && !QDELETED(fish_spot)) - qdel(float) - return - var/reward_loot = fish_spot.roll_reward(our_rod, parent) - fish_spot.dispense_reward(reward_loot, parent, target) + if(!PERFORM_ALL_TESTS(fish_sources)) + var/happiness_percentage = source.ai_controller?.blackboard[BB_BASIC_HAPPINESS] * 0.01 + var/fishing_speed = 10 SECONDS - round(4 SECONDS * happiness_percentage) + if(!do_after(source, fishing_speed, target = target) && !QDELETED(fish_spot)) + qdel(float) + return + var/reward_loot = fish_spot.roll_reward(our_rod, source) + fish_spot.dispense_reward(reward_loot, source, target) playsound(float, 'sound/effects/bigsplash.ogg', 100) qdel(float) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 12a2ad2d448..bfae7f36829 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -452,7 +452,7 @@ var/make_edible = TRUE if(weight) for(var/reagent_type in grind_results) - grind_results[reagent_type] /= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1) + grind_results[reagent_type] /= max(FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1), 0.1) if(reagents) //This fish has reagents. Adjust the maximum volume of the reagent holder and do some math to adjut the reagents too. var/new_weight_ratio = new_weight / weight var/volume_diff = reagents.maximum_volume * new_weight_ratio - reagents.maximum_volume @@ -486,7 +486,7 @@ mob.update_equipment_speed_mods() for(var/reagent_type in grind_results) - grind_results[reagent_type] *= FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1) + grind_results[reagent_type] *= max(FLOOR(weight/FISH_GRIND_RESULTS_WEIGHT_DIVISOR, 0.1), 0.1) update_fish_force() diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index 63bb5e30616..0c02c0c3a90 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -280,15 +280,43 @@ growth_rate = 100 fish_traits = list() //We don't want to end up applying traits twice on the resulting lobstrosity -/datum/unit_test/explosive_fishing +/datum/unit_test/fish_sources -/datum/unit_test/explosive_fishing/Run() - var/datum/fish_source/source = GLOB.preset_fish_sources[/datum/fish_source/unit_test] +/datum/unit_test/fish_sources/Run() + var/datum/fish_source/source = GLOB.preset_fish_sources[/datum/fish_source/unit_test_explosive] source.spawn_reward_from_explosion(run_loc_floor_bottom_left, 1) if(source.fish_counts[/obj/item/wrench]) TEST_FAIL("The unit test item wasn't removed/spawned from fish_table during 'spawn_reward_from_explosion'.") -/datum/fish_source/unit_test + ///From here, we check that the profound_fisher as well as fish source procs for rolling rewards don't fail. + source = GLOB.preset_fish_sources[/datum/fish_source/unit_test_profound_fisher] + run_loc_floor_bottom_left.AddElement(/datum/element/lazy_fishing_spot, /datum/fish_source/unit_test_profound_fisher) + var/mob/living/basic/fisher = allocate(/mob/living/basic) + fisher.AddComponent(/datum/component/profound_fisher) + fisher.set_combat_mode(FALSE) + fisher.melee_attack(run_loc_floor_bottom_left, ignore_cooldown = TRUE) + if(source.fish_counts[/obj/item/fish/testdummy] != 1) + TEST_FAIL("The unit test profound fisher didn't catch the test fish on a lazy fishing spot (element)") + + ///For good measure, let's try it again, but with the component this time, and a human mob and gloves + run_loc_floor_bottom_left.RemoveElement(/datum/element/lazy_fishing_spot, /datum/fish_source/unit_test_profound_fisher) + var/datum/component/comp = run_loc_floor_bottom_left.AddComponent(/datum/component/fishing_spot, source) + var/mob/living/carbon/human/consistent/angler = allocate(/mob/living/carbon/human/consistent) + var/obj/item/clothing/gloves/noodling = allocate(/obj/item/clothing/gloves) + noodling.AddComponent(/datum/component/profound_fisher) + angler.equip_to_slot(noodling, ITEM_SLOT_GLOVES) + + angler.UnarmedAttack(run_loc_floor_bottom_left, proximity_flag = TRUE) + if(source.fish_counts[/obj/item/fish/testdummy]) + TEST_FAIL("The unit test profound fisher didn't catch the test fish on a fishing spot (component)") + qdel(comp) + + ///As a final test, let's see how it goes with a fish source containing every single fish subtype. + comp = run_loc_floor_bottom_left.AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/unit_test_all_fish]) + fisher.melee_attack(run_loc_floor_bottom_left, ignore_cooldown = TRUE) + qdel(comp) + +/datum/fish_source/unit_test_explosive fish_table = list( /obj/item/wrench = 1, /obj/item/screwdriver = INFINITY, //infinite weight, so if fish counts doesn't work as intended, this'll be always picked. @@ -298,6 +326,17 @@ /obj/item/screwdriver = 0, //this should never be picked. ) +/datum/fish_source/unit_test_profound_fisher + fish_table = list(/obj/item/fish/testdummy = 1) + fish_counts = list(/obj/item/fish/testdummy = 2) + +/datum/fish_source/unit_test_all_fish + +/datum/fish_source/unit_test_all_fish/New() + for(var/fish_type as anything in subtypesof(/obj/item/fish)) + fish_table[fish_type] = 10 + return ..() + /datum/unit_test/edible_fish /datum/unit_test/edible_fish/Run() From 86d5b823d087d72036dbccc96eb647725bc6972f Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:57:41 +0200 Subject: [PATCH 055/142] You can release fish after catching it (#86126) ## About The Pull Request This PR nerfs the mood event from fishing from 5 to 4. In exchange, after catching a fish, you can release it in the appropriate fishing spot for a minor positive mood event (if it's alive, or if the user has either the morbid or naive traits). It also counts towards fish population for fish that are limited in the amount of times they can be catched. Mobs with the naive trait (clowns) get the positive mood event even if the fish is dead or being released in a bad place like lava Some fishing spots like toilets and moisture traps don't have this option, but that's because they've their own interactions with fish that'd otherwise be overridden by it. This PR also fixes mobs with the morbid trait (coroners) not enjoying aquarium in their own morbid ways and add a few touches pertaining the naive trait like alternative chat messages when interacting with the fish. ## Why It's Good For The Game This gives players a way to get rid of unwanted fish without leaving it to die on the floor, also it's in the spirit of recreational fishing. ## Changelog :cl: fix: Fixed morbid mobs (coroners) not enjoying room beauty and aquariums in their own weird ways. add: You an now release fish after catching it for a positive moodlet (or to repopulate certain fishing spot with rare fish). /:cl: --------- Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com> --- code/__DEFINES/dcs/signals/signals_fish.dm | 3 + code/__DEFINES/traits/declarations.dm | 2 + code/_globalvars/traits/_traits.dm | 1 + code/_globalvars/traits/admin_tooling.dm | 3 +- code/datums/components/fishing_spot.dm | 5 ++ code/datums/elements/give_turf_traits.dm | 2 +- code/datums/elements/lazy_fishing_spot.dm | 7 +++ code/datums/mood.dm | 2 +- .../mood_events/generic_positive_events.dm | 16 +++++- code/game/turfs/open/ice.dm | 1 + code/game/turfs/open/lava.dm | 2 + code/game/turfs/open/water.dm | 1 + code/modules/fishing/aquarium/aquarium.dm | 2 +- code/modules/fishing/fish/_fish.dm | 55 ++++++++++++++----- .../modules/fishing/fishing_portal_machine.dm | 2 + code/modules/fishing/fishing_rod.dm | 2 +- code/modules/fishing/sources/_fish_source.dm | 29 ++++++++-- 17 files changed, 112 insertions(+), 23 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index 92c65e3b25e..a3dc7ac91b2 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -33,6 +33,9 @@ ///From /obj/item/fish/update_fish_force: (weight_rank, bonus_malus) #define COMSIG_FISH_FORCE_UPDATED "fish_force_updated" +///From /obj/item/fish/interact_with_atom_secondary, sent to the target: (fish) +#define COMSIG_FISH_RELEASED_INTO "fish_released_into" + /// Rolling a reward path for a fishing challenge #define COMSIG_FISHING_CHALLENGE_ROLL_REWARD "fishing_roll_reward" /// Adjusting the difficulty of a rishing challenge, often based on the reward path diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 2794ffd3653..f34ea9ef740 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -231,6 +231,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_EXAMINE_FISHING_SPOT "examine_fishing_spot" ///lobstrosities and carps will prioritize/flee from those that have this trait (given by the skill-locked hat) #define TRAIT_SCARY_FISHERMAN "scary_fisherman" +/// Atoms with this trait can be right-clicked with a fish to release them, presumably back in the fishing spot they were caught from. +#define TRAIT_CATCH_AND_RELEASE "catch_and_release" ///This trait lets you get the size and weight of the fish by examining them #define TRAIT_EXAMINE_FISH "examine_fish" ///This trait lets you roughly know if the fish is dead, starving, drowning or sick by examining them diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 760fb3912ad..391ee415c08 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -10,6 +10,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_AI_PAUSED" = TRAIT_AI_PAUSED, "TRAIT_BANNED_FROM_CARGO_SHUTTLE" = TRAIT_BANNED_FROM_CARGO_SHUTTLE, "TRAIT_BEING_SHOCKED" = TRAIT_BEING_SHOCKED, + "TRAIT_CATCH_AND_RELEASE" = TRAIT_CATCH_AND_RELEASE, "TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED, "TRAIT_CLIMBABLE" = TRAIT_CLIMBABLE, "TRAIT_CURRENTLY_CLEANING" = TRAIT_CURRENTLY_CLEANING, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 14f86941756..2500a63c9fd 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -4,8 +4,9 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( /atom = list( - "TRAIT_UNHITTABLE_BY_PROJECTILES" = TRAIT_UNHITTABLE_BY_PROJECTILES, + "TRAIT_CATCH_AND_RELEASE" = TRAIT_CATCH_AND_RELEASE, "TRAIT_KEEP_TOGETHER" = TRAIT_KEEP_TOGETHER, + "TRAIT_UNHITTABLE_BY_PROJECTILES" = TRAIT_UNHITTABLE_BY_PROJECTILES, ), /atom/movable = list( "TRAIT_ASHSTORM_IMMUNE" = TRAIT_ASHSTORM_IMMUNE, diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 6ecea18976c..659eaff8550 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -19,6 +19,7 @@ RegisterSignal(parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examined_more)) RegisterSignal(parent, COMSIG_NPC_FISHING, PROC_REF(return_fishing_spot)) RegisterSignal(parent, COMSIG_ATOM_EX_ACT, PROC_REF(explosive_fishing)) + RegisterSignal(parent, COMSIG_FISH_RELEASED_INTO, PROC_REF(fish_released)) ADD_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) /datum/component/fishing_spot/Destroy() @@ -82,3 +83,7 @@ /datum/component/fishing_spot/proc/explosive_fishing(atom/location, severity) SIGNAL_HANDLER fish_source.spawn_reward_from_explosion(location, severity) + +/datum/component/fishing_spot/proc/fish_released(datum/source, obj/item/fish/fish, mob/living/releaser) + SIGNAL_HANDLER + fish_source.readd_fish(fish, releaser) diff --git a/code/datums/elements/give_turf_traits.dm b/code/datums/elements/give_turf_traits.dm index 3c53d4a5e73..7e7c37d86e7 100644 --- a/code/datums/elements/give_turf_traits.dm +++ b/code/datums/elements/give_turf_traits.dm @@ -67,7 +67,7 @@ for(var/mob/living/living in location) living.update_turf_movespeed() -/// Signals and components are carried over when the turf is changed, so they've to be readded post-change. +/// Signals are carried over when the turf is changed, but traits aren't, so they've to be readded post-change. /datum/element/give_turf_traits/proc/pre_change_turf(turf/changed, path, list/new_baseturfs, flags, list/post_change_callbacks) SIGNAL_HANDLER post_change_callbacks += CALLBACK(src, PROC_REF(reoccupy_turf)) diff --git a/code/datums/elements/lazy_fishing_spot.dm b/code/datums/elements/lazy_fishing_spot.dm index eaf4351a2e8..1066f0179ea 100644 --- a/code/datums/elements/lazy_fishing_spot.dm +++ b/code/datums/elements/lazy_fishing_spot.dm @@ -20,9 +20,11 @@ RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) RegisterSignal(target, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examined_more)) RegisterSignal(target, COMSIG_ATOM_EX_ACT, PROC_REF(explosive_fishing)) + RegisterSignal(target, COMSIG_FISH_RELEASED_INTO, PROC_REF(fish_released)) /datum/element/lazy_fishing_spot/Detach(datum/target) UnregisterSignal(target, list( + COMSIG_FISH_RELEASED_INTO, COMSIG_PRE_FISHING, COMSIG_NPC_FISHING, COMSIG_ATOM_EXAMINE, @@ -66,3 +68,8 @@ /datum/element/lazy_fishing_spot/proc/return_glob_fishing_spot(datum/source, list/fish_spot_container) fish_spot_container[NPC_FISHING_SPOT] = GLOB.preset_fish_sources[configuration] + +/datum/element/lazy_fishing_spot/proc/fish_released(datum/source, obj/item/fish/fish, mob/living/releaser) + SIGNAL_HANDLER + var/datum/fish_source/fish_source = GLOB.preset_fish_sources[configuration] + fish_source.readd_fish(fish, releaser) diff --git a/code/datums/mood.dm b/code/datums/mood.dm index c279170fe74..4fb07e37503 100644 --- a/code/datums/mood.dm +++ b/code/datums/mood.dm @@ -462,7 +462,7 @@ clear_mood_event(MOOD_CATEGORY_AREA_BEAUTY) return - if(HAS_TRAIT(mob_parent, TRAIT_MORBID)) + if(HAS_MIND_TRAIT(mob_parent, TRAIT_MORBID)) if(HAS_TRAIT(mob_parent, TRAIT_SNOB)) switch(area_to_beautify.beauty) if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 8c760e8c4f8..6ca1ecc0e6e 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -333,9 +333,23 @@ /datum/mood_event/fishing description = "Fishing is relaxing." - mood_change = 5 + mood_change = 4 timeout = 3 MINUTES +/datum/mood_event/fish_released + description = "Go, fish, swim and be free!" + mood_change = 1 + timeout = 2 MINUTES + +/datum/mood_event/fish_released/add_effects(morbid, obj/item/fish/fish) + if(!morbid) + description = "Go, [fish.name], swim and be free!" + return + if(fish.status == FISH_DEAD) + description = "Some scavenger will surely find a use for the remains of [fish.name]. How pragmatic." + else + description = "Returned to the burden of the deep. But is this truly a mercy, [fish.name]? There will always be bigger fish..." + /datum/mood_event/kobun description = "You are all loved by the Universe. I’m not alone, and you aren’t either." mood_change = 14 diff --git a/code/game/turfs/open/ice.dm b/code/game/turfs/open/ice.dm index dbfff2efc8f..f28bc8dd4b0 100644 --- a/code/game/turfs/open/ice.dm +++ b/code/game/turfs/open/ice.dm @@ -53,6 +53,7 @@ return NONE balloon_alert(user, "dug hole") AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/ice_fishing]) + ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) add_overlay(mutable_appearance('icons/turf/overlays.dmi', "ice_hole")) can_make_hole = FALSE RemoveElement(/datum/element/contextual_screentip_tools, tool_screentips) diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 23e2b6b38db..c080e228438 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -48,6 +48,8 @@ . = ..() if(fish_source_type) AddElement(/datum/element/lazy_fishing_spot, fish_source_type) + // You can release chrabs and lavaloops and likes in lava, or be an absolute scumbag and drop other fish there too. + ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) refresh_light() if(!smoothing_flags) update_appearance() diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index 853557a1fe9..184475c989b 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -30,6 +30,7 @@ AddElement(/datum/element/watery_tile) if(!isnull(fishing_datum)) AddElement(/datum/element/lazy_fishing_spot, fishing_datum) + ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) /turf/open/water/jungle diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index 0d2cd462128..a3becfe6718 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -295,7 +295,7 @@ else dead_fish++ - var/morb = HAS_TRAIT(user, TRAIT_MORBID) + var/morb = HAS_MIND_TRAIT(user, TRAIT_MORBID) //Check if there are live fish - good mood //All fish dead - bad mood. //No fish - nothing. diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index bfae7f36829..5596a0f8706 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -181,6 +181,34 @@ update_size_and_weight() register_evolutions() + register_item_context() + +/obj/item/fish/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(HAS_TRAIT(source, TRAIT_CATCH_AND_RELEASE)) + context[SCREENTIP_CONTEXT_RMB] = "Release" + return CONTEXTUAL_SCREENTIP_SET + return NONE + +/obj/item/fish/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) + if(!HAS_TRAIT(interacting_with, TRAIT_CATCH_AND_RELEASE)) + return NONE + if(HAS_TRAIT(src, TRAIT_NODROP)) + balloon_alert(user, "it's stuck to your hand!") + return ITEM_INTERACT_BLOCKING + balloon_alert(user, "releasing fish...") + if(!do_after(src, 3 SECONDS, interacting_with)) + return ITEM_INTERACT_BLOCKING + balloon_alert(user, "fish released") + var/goodbye_text = "Bye bye [name]." + if(status == FISH_DEAD && !HAS_MIND_TRAIT(user, TRAIT_NAIVE)) + goodbye_text = "May it rest in peace..." + user.visible_message(span_notice("[user] releases [src] into [interacting_with]"), \ + span_notice("You release [src] into [interacting_with]. [goodbye_text]"), \ + span_notice("You hear a splash.")) + playsound(interacting_with, 'sound/effects/splash.ogg', 50) + SEND_SIGNAL(interacting_with, COMSIG_FISH_RELEASED_INTO, src) + qdel(src) + return ITEM_INTERACT_SUCCESS ///Main proc that makes the fish edible. /obj/item/fish/proc/make_edible() @@ -361,29 +389,30 @@ if(!istype(item, /obj/item/fish_feed)) return ..() if(!item.reagents.total_volume) - balloon_alert(user, "[item] is empty!") + balloon_alert(user, "[item.name] is empty!") return TRUE if(status == FISH_DEAD) - balloon_alert(user, "[src] is dead!") + balloon_alert(user, "[name] [HAS_MIND_TRAIT(user, TRAIT_NAIVE) ? "isn't hungry" : "is dead!"]") return TRUE feed(item.reagents) - balloon_alert(user, "fed [src]") + balloon_alert(user, "fed [name]") return TRUE /obj/item/fish/examine(mob/user) . = ..() if(HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH)) if(status == FISH_DEAD) - . += span_deadsay("it's dead.") - var/list/warnings = list() - if(is_hungry()) - warnings += "starving" - if(!HAS_TRAIT(src, TRAIT_FISH_STASIS) && !proper_environment()) - warnings += "drowning" - if(health < initial(health) * 0.6) - warnings += "sick" - if(length(warnings)) - . += span_warning("it's [english_list(warnings)]") + . += span_deadsay("It's [HAS_MIND_TRAIT(user, TRAIT_NAIVE) ? "taking the big snooze" : "dead"].") + else + var/list/warnings = list() + if(is_hungry()) + warnings += "starving" + if(!HAS_TRAIT(src, TRAIT_FISH_STASIS) && !proper_environment()) + warnings += "drowning" + if(health < initial(health) * 0.6) + warnings += "sick" + if(length(warnings)) + . += span_warning("It's [english_list(warnings)].") if(HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH)) . += span_notice("It's [size] cm long.") . += span_notice("It weighs [weight] g.") diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm index 8b157cbebff..9444d1368e3 100644 --- a/code/modules/fishing/fishing_portal_machine.dm +++ b/code/modules/fishing/fishing_portal_machine.dm @@ -53,12 +53,14 @@ /obj/machinery/fishing_portal_generator/proc/activate(datum/fish_source/selected_source) active = AddComponent(/datum/component/fishing_spot, selected_source) + ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) use_power = ACTIVE_POWER_USE update_icon() /obj/machinery/fishing_portal_generator/proc/deactivate() QDEL_NULL(active) use_power = IDLE_POWER_USE + REMOVE_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) update_icon() /obj/machinery/fishing_portal_generator/on_set_is_operational(old_value) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 9b088778d57..f7f4d12e6a0 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -220,7 +220,7 @@ return BEAM_CANCEL_DRAW /obj/item/fishing_rod/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - //this prevent trying to use telekinesis to fish (which would be broken anyway) + //this prevent trying to use telekinesis to fish (which would be broken anyway), also whacking people with a rod. if(!user.contains(src) || (user.combat_mode && !isturf(interacting_with)) ||HAS_TRAIT(interacting_with, TRAIT_COMBAT_MODE_SKIP_INTERACTION)) return ..() return ranged_interact_with_atom(interacting_with, user, modifiers) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index e3b3922b332..0771e3fe603 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -275,13 +275,16 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) SEND_SIGNAL(src, COMSIG_FISH_SOURCE_REWARD_DISPENSED, reward) return reward -/datum/fish_source/proc/regen_count(reward_path, regen_time) +/datum/fish_source/proc/regen_count(reward_path) + if(!LAZYACCESS(currently_on_regen, reward_path)) + return fish_counts[reward_path] += 1 currently_on_regen[reward_path] -= 1 - if(!currently_on_regen[reward_path]) + if(currently_on_regen[reward_path] <= 0) LAZYREMOVE(currently_on_regen, reward_path) - else - addtimer(CALLBACK(src, PROC_REF(regen_count), reward_path), regen_time) + return + var/regen_time = fish_count_regen[reward_path] + addtimer(CALLBACK(src, PROC_REF(regen_count), reward_path), regen_time) /// Spawns a reward from a atom path right where the fisherman is. Part of the dispense_reward() logic. /datum/fish_source/proc/spawn_reward(reward_path, atom/spawn_location, turf/fishing_spot) @@ -464,6 +467,24 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) if(severity >= EXPLODE_DEVASTATE) reward.ex_act(EXPLODE_LIGHT) +///Called when releasing a fish in a fishing spot with the TRAIT_CATCH_AND_RELEASE trait. +/datum/fish_source/proc/readd_fish(obj/item/fish/fish, mob/living/releaser) + var/is_morbid = HAS_MIND_TRAIT(releaser, TRAIT_MORBID) + var/is_naive = HAS_MIND_TRAIT(releaser, TRAIT_NAIVE) + if(fish.status == FISH_DEAD) //ded fish won't repopulate the sea. + if(is_naive || is_morbid) + releaser.add_mood_event("fish_released", /datum/mood_event/fish_released, is_morbid && !is_naive, fish) + return + if(((fish.type in fish_table) != is_morbid) || is_naive) + releaser.add_mood_event("fish_released", /datum/mood_event/fish_released, is_morbid && !is_naive, fish) + if(isnull(fish_counts[fish.type])) //This fish can be caught indefinitely so it won't matter. + return + //If this fish population isn't recovering from recent losses, we just increase it. + if(!LAZYACCESS(currently_on_regen, fish.type)) + fish_counts[fish.type] += 1 + else + regen_count(fish.type) + /** * Called by /datum/autowiki/fish_sources unless the catalog entry for this fish source is null. * It should Return a list of entries with keys named "name", "icon", "weight" and "notes" From 66eab132c46cfbdbd098eeb55d0c44b783e53c9c Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:06:49 +0200 Subject: [PATCH 056/142] Fixed the force of swordfish and armored pikes (#86620) ## About The Pull Request Noticed this while resolving conflicts on another fish PR. I had copypasted the code and then modified it, but I've forgot to change the path too. ## Why It's Good For The Game A mistake was made. ## Changelog :cl: fix: Fixed the force of swordfish and armored pikes /:cl: --- code/modules/fishing/fish/types/syndicate.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/fishing/fish/types/syndicate.dm b/code/modules/fishing/fish/types/syndicate.dm index c1c6eea06e4..bf99f430281 100644 --- a/code/modules/fishing/fish/types/syndicate.dm +++ b/code/modules/fishing/fish/types/syndicate.dm @@ -214,7 +214,7 @@ /obj/item/fish/pike/armored/get_fish_taste() return list("cooked fish" = 2.5, "metal" = 1) -/obj/item/fish/swordfish/get_force_rank() +/obj/item/fish/pike/armored/get_force_rank() switch(w_class) if(WEIGHT_CLASS_TINY) force -= 11 From d5d3c05267c4299be608f223bd559c9c501d3ea8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 14:07:14 +0000 Subject: [PATCH 057/142] Automatic changelog for PR #86596 [ci skip] --- html/changelogs/AutoChangeLog-pr-86596.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86596.yml diff --git a/html/changelogs/AutoChangeLog-pr-86596.yml b/html/changelogs/AutoChangeLog-pr-86596.yml new file mode 100644 index 00000000000..07e6141ebb0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86596.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - admin: "godmode is now a datum trait instead of a bitflag. This means the process for toggling it is a little different now." \ No newline at end of file From 7bd87049394c551c4320648f45b291ee6694760f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 14:08:24 +0000 Subject: [PATCH 058/142] Automatic changelog for PR #86126 [ci skip] --- html/changelogs/AutoChangeLog-pr-86126.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86126.yml diff --git a/html/changelogs/AutoChangeLog-pr-86126.yml b/html/changelogs/AutoChangeLog-pr-86126.yml new file mode 100644 index 00000000000..ca9efc8bac5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86126.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed morbid mobs (coroners) not enjoying room beauty and aquariums in their own weird ways." + - rscadd: "You an now release fish after catching it for a positive moodlet (or to repopulate certain fishing spot with rare fish)." \ No newline at end of file From d053bcb7b7111a4a1e3917f7212bedb77336f747 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 14:09:11 +0000 Subject: [PATCH 059/142] Automatic changelog for PR #86620 [ci skip] --- html/changelogs/AutoChangeLog-pr-86620.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86620.yml diff --git a/html/changelogs/AutoChangeLog-pr-86620.yml b/html/changelogs/AutoChangeLog-pr-86620.yml new file mode 100644 index 00000000000..c5c5ef99f82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86620.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed the force of swordfish and armored pikes" \ No newline at end of file From 4587b3c4489c985b6a4343ff4af4391832f7aea5 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:08:05 +0200 Subject: [PATCH 060/142] Quickfix for a now removed status flag (also byond issue). (#86680) ## About The Pull Request Making the code compile. EDIT: There's an on-going BYOND issue with datum subtypes (not atoms) in which trying to override the parent value with null won't work. Melbert has provided me a fix for it too (from: https://github.com/tgstation/tgstation/pull/86666/commits/d6c1dbf4fd641d160961d7964e145e93b86d672c) ## Why It's Good For The Game Making the code compile and the CI succeed ## Changelog . --- code/game/atoms_movable.dm | 2 +- .../antagonists/heretic/magic/void_prison.dm | 6 ++---- code/modules/language/_language_holder.dm | 13 ++++++++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f9e94066592..ceff77b859d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -17,7 +17,7 @@ var/tk_throw_range = 10 var/mob/pulledby = null /// What language holder type to init as - var/initial_language_holder = /datum/language_holder + var/initial_language_holder = /datum/language_holder/atom_basic /// Holds all languages this mob can speak and understand VAR_PRIVATE/datum/language_holder/language_holder /// The list of factions this atom belongs to diff --git a/code/modules/antagonists/heretic/magic/void_prison.dm b/code/modules/antagonists/heretic/magic/void_prison.dm index 22a4d17eb88..211a747c800 100644 --- a/code/modules/antagonists/heretic/magic/void_prison.dm +++ b/code/modules/antagonists/heretic/magic/void_prison.dm @@ -56,8 +56,7 @@ owner.apply_status_effect(/datum/status_effect/void_chill, 3) if(stasis_overlay) //Free our prisoner - owner.status_flags &= ~GODMODE - owner.remove_traits(list(TRAIT_NO_TRANSFORM, TRAIT_SOFTSPOKEN), REF(src)) + owner.remove_traits(list(TRAIT_GODMODE, TRAIT_NO_TRANSFORM, TRAIT_SOFTSPOKEN), REF(src)) owner.forceMove(get_turf(stasis_overlay)) stasis_overlay.forceMove(owner) owner.vis_contents += stasis_overlay @@ -72,8 +71,7 @@ /datum/status_effect/void_prison/proc/enter_prison(mob/living/prisoner) stasis_overlay.forceMove(prisoner.loc) prisoner.forceMove(stasis_overlay) - prisoner.add_traits(list(TRAIT_NO_TRANSFORM, TRAIT_SOFTSPOKEN), REF(src)) - prisoner.status_flags |= GODMODE + prisoner.add_traits(list(TRAIT_GODMODE, TRAIT_NO_TRANSFORM, TRAIT_SOFTSPOKEN), REF(src)) ///Makes sure to clear the ref in case the voidball ever suddenly disappears /datum/status_effect/void_prison/proc/clear_overlay() diff --git a/code/modules/language/_language_holder.dm b/code/modules/language/_language_holder.dm index 86a0dacc52e..47af5f1e14d 100644 --- a/code/modules/language/_language_holder.dm +++ b/code/modules/language/_language_holder.dm @@ -37,10 +37,10 @@ Key procs /datum/language_holder /// Lazyassoclist of all understood languages - var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + var/list/understood_languages /// Lazyassoclist of languages that can be spoken. /// Tongue organ may also set limits beyond this list. - var/list/spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + var/list/spoken_languages /// Lazyassoclist of blocked languages. /// Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. var/list/blocked_languages @@ -523,14 +523,21 @@ GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) /datum/language/nekomimetic = list(LANGUAGE_ATOM), ) +// Given to atoms by default +/datum/language_holder/atom_basic + understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + +// Explicitly empty one for readability /datum/language_holder/empty understood_languages = null spoken_languages = null +// Has all the languages known (via "mind") /datum/language_holder/universal understood_languages = null spoken_languages = null /datum/language_holder/universal/New() . = ..() - grant_all_languages() + grant_all_languages(source = LANGUAGE_MIND) From 2647752f784948586cc7f28f691442709919daf7 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:44:35 +0200 Subject: [PATCH 061/142] GetFlatIcon improvements. (#86077) ## About The Pull Request I've added an get_icon_dimensions() call to a place where `icon.Width()` and `icon.Height()` are called twice each. get_icon_dimensions uses a cache of values so follow-up getFlatIcon() calls with the same current icon won't have it call`icon.Width()` or `icon.Height()` which aren't exactly cheap procs iirc. I've also removed two of the fairly expensive `length(icon_states(icon(curicon, curstate, dir)))` checks, because all icon states have NORTH, EAST and WEST directions except 1-dir icon_states which are always facing SOUTH. That is, unless there is some farfetched procgenned bullshit that's probably not even possible and worth checking against. We'll see. ## Why It's Good For The Game GetFlatIcon is a very expensive proc, every bit of improvement is worth it. ## Changelog N/A --- code/__HELPERS/icons.dm | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 9c05cc2b62e..cad09ae05b7 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -466,25 +466,24 @@ world var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have - //Try to remove/optimize this section ASAP, CPU hog. - //Determines if there's directionals. - if(render_icon && curdir != SOUTH) - if ( - !length(icon_states(icon(curicon, curstate, NORTH))) \ - && !length(icon_states(icon(curicon, curstate, EAST))) \ - && !length(icon_states(icon(curicon, curstate, WEST))) \ - ) - base_icon_dir = SOUTH + if(render_icon) + //Try to remove/optimize this section if you can, it's a CPU hog. + //Determines if there're directionals. + if (curdir != SOUTH) + // icon states either have 1, 4 or 8 dirs. We only have to check + // one of NORTH, EAST or WEST to know that this isn't a 1-dir icon_state since they just have SOUTH. + if(!length(icon_states(icon(curicon, curstate, NORTH)))) + base_icon_dir = SOUTH + + var/list/icon_dimensions = get_icon_dimensions(curicon) + var/icon_width = icon_dimensions["width"] + var/icon_height = icon_dimensions["height"] + if(icon_width != 32 || icon_height != 32) + flat.Scale(icon_width, icon_height) if(!base_icon_dir) base_icon_dir = curdir - // Expand our canvas to fit if we're too big - if(render_icon) - var/icon/active_icon = icon(curicon) - if(active_icon.Width() != 32 || active_icon.Height() != 32) - flat.Scale(active_icon.Width(), active_icon.Height()) - var/curblend = appearance.blend_mode || defblend if(appearance.overlays.len || appearance.underlays.len) From 5665ddce034df9aa268b920bccf316927e03e76c Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:48:09 +0200 Subject: [PATCH 062/142] Gives detectives an ID that looks like an assistant ID when flipped. Also makes their camera silent. (#85912) ## About The Pull Request This PR adds an ID subtype which the detective outfit uses. It that can be flipped to go plainclothes as an assistant. Access retained. Spare clothes not included. I've also made the detective camera silent (a sound cue is still played to the user, others won't hear it) and with the flash disabled. ## Why It's Good For The Game I want to make it a little easier for detectives to go plainclothes. Between clothings and inventory management, it's already quite tricky as a gimmick and without doubt a double-edged sword that can lead to goofy-ass situations where officers actually confuse you for an assistant. As for the camera, it's just a stealth buff. ## Changelog :cl: add: Gave the detective an ID that can flipped to look like an assistant ID. balance: The detective camera is now silent and doesn't flash. /:cl: --- code/game/objects/items/cards_ids.dm | 48 +++++++++++++++++-- code/modules/jobs/job_types/detective.dm | 7 ++- code/modules/photography/camera/camera.dm | 6 ++- .../camera/camera_image_capturing.dm | 6 --- code/modules/photography/camera/other.dm | 10 +++- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 7dd42728690..3f6e619a4ad 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -992,6 +992,11 @@ return ..() +/obj/item/card/id/advanced/proc/after_input_check(mob/user) + if(QDELETED(user) || QDELETED(src) || !user.client || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) + return FALSE + return TRUE + /obj/item/card/id/advanced/item_interaction(mob/living/user, obj/item/tool, list/modifiers) . = ..() if(.) @@ -1447,6 +1452,44 @@ trim = /datum/id_trim/highlander wildcard_slots = WILDCARD_LIMIT_ADMIN +/// An ID that you can flip with attack_self_secondary, overriding the appearance of the ID (useful for plainclothes detectives for example). +/obj/item/card/id/advanced/plainclothes + name = "Plainclothes ID" + ///The trim that we use as plainclothes identity + var/alt_trim = /datum/id_trim/job/assistant + +/obj/item/card/id/advanced/plainclothes/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_LMB] = "Show/Flip ID" + +/obj/item/card/id/advanced/plainclothes/examine(mob/user) + . = ..() + if(trim_assignment_override) + . += span_smallnotice("it's currently under plainclothes identity.") + else + . += span_smallnotice("flip it to switch to the plainclothes identity.") + +/obj/item/card/id/advanced/plainclothes/attack_self(mob/user) + var/popup_input = tgui_input_list(user, "Choose Action", "Two-Sided ID", list("Show", "Flip")) + if(!popup_input || !after_input_check(user)) + return TRUE + if(popup_input == "Show") + return ..() + balloon_alert(user, "flipped") + if(trim_assignment_override) + SSid_access.remove_trim_from_chameleon_card(src) + else + SSid_access.apply_trim_to_chameleon_card(src, alt_trim) + update_label() + update_appearance() + +/obj/item/card/id/advanced/plainclothes/update_label() + if(!trim_assignment_override) + return ..() + var/name_string = registered_name ? "[registered_name]'s ID Card" : initial(name) + var/datum/id_trim/fake = SSid_access.trim_singletons_by_path[alt_trim] + name = "[name_string] ([fake.assignment])" + /obj/item/card/id/advanced/chameleon name = "agent card" desc = "A highly advanced chameleon ID card. Touch this card on another ID card or player to choose which accesses to copy. \ @@ -1729,11 +1772,6 @@ registered_account = account to_chat(user, span_notice("Your account number has been automatically assigned.")) -/obj/item/card/id/advanced/chameleon/proc/after_input_check(mob/user) - if(QDELETED(user) || QDELETED(src) || !user.client || !user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) - return FALSE - return TRUE - /obj/item/card/id/advanced/chameleon/add_item_context(obj/item/source, list/context, atom/target, mob/living/user,) . = ..() diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index 00bd8790d9b..258b2b322f1 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -29,13 +29,14 @@ mail_goodies = list( /obj/item/storage/fancy/cigarettes = 25, - /obj/item/ammo_box/c38 = 25, + /obj/item/ammo_box/c38 = 20, /obj/item/ammo_box/c38/dumdum = 5, /obj/item/ammo_box/c38/hotshot = 5, /obj/item/ammo_box/c38/iceblox = 5, /obj/item/ammo_box/c38/match = 5, /obj/item/ammo_box/c38/trac = 5, - /obj/item/storage/belt/holster/detective/full = 1 + /obj/item/card/id/advanced/plainclothes = 5, + /obj/item/storage/belt/holster/detective/full = 1, ) family_heirlooms = list(/obj/item/reagent_containers/cup/glass/bottle/whiskey) @@ -49,6 +50,8 @@ name = "Detective" jobtype = /datum/job/detective + id = /obj/item/card/id/advanced/plainclothes + id_trim = /datum/id_trim/job/detective uniform = /obj/item/clothing/under/rank/security/detective suit = /obj/item/clothing/suit/jacket/det_suit diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index eb29ca4b8b5..425ff9d38a4 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -30,7 +30,6 @@ var/blending = FALSE //lets not take pictures while the previous is still processing! var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it var/obj/item/disk/holodisk/disk - var/sound/custom_sound var/silent = FALSE var/picture_size_x = 2 var/picture_size_y = 2 @@ -118,7 +117,7 @@ return FALSE else if(user.client && !(get_turf(target) in get_hear(user.client.view, user))) return FALSE - else if(!(get_turf(target) in get_hear(world.view, user))) + else if(!(get_turf(target) in get_hear(CONFIG_GET(string/default_view), user))) return FALSE else if(isliving(loc)) if(!(get_turf(target) in view(world.view, loc))) @@ -252,6 +251,9 @@ if(print_picture_on_snap) printpicture(user, picture) + if(!silent) + playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) + /obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos pictures_left-- var/obj/item/photo/new_photo = new(get_turf(src), picture) diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm index 64eeb192a22..c9f8d8dbe8e 100644 --- a/code/modules/photography/camera/camera_image_capturing.dm +++ b/code/modules/photography/camera/camera_image_capturing.dm @@ -142,12 +142,6 @@ res.Blend(img, blendMode2iconMode(clone.blend_mode), xo, yo) CHECK_TICK - if(!silent) - if(istype(custom_sound)) //This is where the camera actually finishes its exposure. - playsound(loc, custom_sound, 75, TRUE, -3) - else - playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) - if(wipe_atoms) QDEL_LIST(atoms) else diff --git a/code/modules/photography/camera/other.dm b/code/modules/photography/camera/other.dm index 166517d055f..83e9a5fd28c 100644 --- a/code/modules/photography/camera/other.dm +++ b/code/modules/photography/camera/other.dm @@ -25,7 +25,13 @@ see_ghosts = CAMERA_SEE_GHOSTS_ORBIT /obj/item/camera/detective - name = "Detective's camera" - desc = "A polaroid camera with extra capacity for crime investigations." + name = "detective's camera" + desc = "A silent polaroid camera with extra capacity for crime investigations." + flash_enabled = FALSE + silent = TRUE pictures_max = 30 pictures_left = 30 + +/obj/item/camera/detective/after_picture(mob/user, datum/picture/picture) + . = ..() + user.playsound_local(get_turf(src), pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 35, TRUE) From d6f4350af12e5e4d255293511813e506f3f657b3 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:48:30 +0000 Subject: [PATCH 063/142] Automatic changelog for PR #85912 [ci skip] --- html/changelogs/AutoChangeLog-pr-85912.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-85912.yml diff --git a/html/changelogs/AutoChangeLog-pr-85912.yml b/html/changelogs/AutoChangeLog-pr-85912.yml new file mode 100644 index 00000000000..7fd91453d6d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-85912.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Gave the detective an ID that can flipped to look like an assistant ID." + - balance: "The detective camera is now silent and doesn't flash." \ No newline at end of file From 0cf2585cc1645db967ea4fae8094758dd9ca3f32 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:57:00 +0200 Subject: [PATCH 064/142] Automated announcement systems now announce researched nodes. (#86093) ## About The Pull Request The idea was born from a small conversation about bepis nodes having low visibility, which somehow degressed into the idea of announcing researched nodes to the channels of the interested departments thru the announcement system machine, which is what I'm doing here, while also adding documentation, defines and purging some, not all, instances of camel cases from announcement_system.dm. Oh, by the by, like the arrival and new head arrival messages, it can be customized or disabled by interacting with the announcement system. ## Why It's Good For The Game I think it's helpful to let players know when the research of their dept is researched, and I think it's kinda interesting to announce bepis tech on common like it's some hot stuff while it actually isn't just because it's often missed out and miscellaneous. ## Changelog :cl: add: Automated announcement systems now announce researched nodes to their respective departments. You can stop this by either disabling the announcement systems or by using a multitool on the circuitboard of the console you're researching nodes from. /:cl: # Conflicts: # code/modules/jobs/job_types/_job.dm --- code/__DEFINES/machines.dm | 9 ++ code/__HELPERS/game.dm | 12 ++- code/game/machinery/announcement_system.dm | 85 ++++++++++++------- .../circuitboards/computer_circuitboards.dm | 23 +++++ code/modules/jobs/job_types/_job.dm | 19 +++-- code/modules/research/designs.dm | 6 +- code/modules/research/rdconsole.dm | 7 +- code/modules/research/techweb/_techweb.dm | 6 +- .../modules/research/techweb/_techweb_node.dm | 30 ++++++- .../research/techweb/nodes/alien_nodes.dm | 3 + .../research/techweb/nodes/atmos_nodes.dm | 5 ++ .../research/techweb/nodes/bepis_nodes.dm | 11 +++ .../research/techweb/nodes/biology_nodes.dm | 4 + .../research/techweb/nodes/cyborg_nodes.dm | 13 +++ .../research/techweb/nodes/engi_nodes.dm | 6 ++ .../research/techweb/nodes/mech_nodes.dm | 12 +++ .../research/techweb/nodes/medbay_nodes.dm | 3 + .../research/techweb/nodes/mining_nodes.dm | 5 ++ .../research/techweb/nodes/modsuit_nodes.dm | 8 ++ .../research/techweb/nodes/research_nodes.dm | 5 ++ .../research/techweb/nodes/robo_nodes.dm | 2 + .../research/techweb/nodes/security_nodes.dm | 7 ++ .../research/techweb/nodes/service_nodes.dm | 3 + .../research/techweb/nodes/surgery_nodes.dm | 4 + .../modules/research/techweb/techweb_types.dm | 4 +- .../tgui/interfaces/AutomatedAnnouncement.tsx | 49 ++++++++++- 26 files changed, 292 insertions(+), 49 deletions(-) diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index d418c080085..67fb080ee13 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -140,6 +140,15 @@ /// Max length of a status line in the status display #define MAX_STATUS_LINE_LENGTH 40 +///Define for automated system arrival announcement +#define AUTO_ANNOUNCE_ARRIVAL "ARRIVAL" +///Define for automated system announcement when a head of staff arrives +#define AUTO_ANNOUNCE_NEWHEAD "NEWHEAD" +///Define for automated system announcement for when the arrival shuttle is broken +#define AUTO_ANNOUNCE_ARRIVALS_BROKEN "ARRIVALS_BROKEN" +///Define for automated system announcement for researched nodes +#define AUTO_ANNOUNCE_NODE "NODE" + /// Blank Status Display #define SD_BLANK 0 /// Shows the emergency shuttle timer diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c68b450c2c2..699ae8aa72c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -243,8 +243,16 @@ if(!(character.mind.assigned_role.job_flags & JOB_ANNOUNCE_ARRIVAL)) return - var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common + var/obj/machinery/announcement_system/announcer + var/list/available_machines = list() + for(var/obj/machinery/announcement_system/announce as anything in GLOB.announcement_systems) + if(announce.arrival_toggle) + available_machines += announce + break + if(!length(available_machines)) + return + announcer = pick(available_machines) + announcer.announce(AUTO_ANNOUNCE_ARRIVAL, character.real_name, rank, list()) //make the list empty to make it announce it in common ///Check if the turf pressure allows specialized equipment to work /proc/lavaland_equipment_pressure_check(turf/turf_to_check) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 1700abb0af1..c9e66c89c95 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -16,16 +16,26 @@ GLOBAL_LIST_EMPTY(announcement_systems) circuit = /obj/item/circuitboard/machine/announcement_system + ///The headset that we use for broadcasting var/obj/item/radio/headset/radio + ///The message that we send when someone is joining. var/arrival = "%PERSON has signed up as %RANK" - var/arrivalToggle = 1 + ///Whether the arrival message is sent + var/arrival_toggle = TRUE + ///The message that we send when a department head arrives. var/newhead = "%PERSON, %RANK, is the department head." - var/newheadToggle = 1 + ///Whether the newhead message is sent. + var/newhead_toggle = TRUE var/greenlight = "Light_Green" var/pinklight = "Light_Pink" var/errorlight = "Error_Red" + ///If true, researched nodes will be announced to the appropriate channels + var/announce_research_node = TRUE + /// The text that we send when announcing researched nodes. + var/node_message = "The '%NODE' techweb node has been researched" + /obj/machinery/announcement_system/Initialize(mapload) . = ..() GLOB.announcement_systems += src @@ -41,10 +51,10 @@ GLOBAL_LIST_EMPTY(announcement_systems) /obj/machinery/announcement_system/update_overlays() . = ..() - if(arrivalToggle) + if(arrival_toggle) . += greenlight - if(newheadToggle) + if(newhead_toggle) . += pinklight if(machine_stat & BROKEN) @@ -78,18 +88,25 @@ GLOBAL_LIST_EMPTY(announcement_systems) str = replacetext(str, "%RANK", "[rank]") return str -/obj/machinery/announcement_system/proc/announce(message_type, user, rank, list/channels) +/obj/machinery/announcement_system/proc/announce(message_type, target, rank, list/channels) if(!is_operational) return var/message - if(message_type == "ARRIVAL" && arrivalToggle) - message = CompileText(arrival, user, rank) - else if(message_type == "NEWHEAD" && newheadToggle) - message = CompileText(newhead, user, rank) - else if(message_type == "ARRIVALS_BROKEN") - message = "The arrivals shuttle has been damaged. Docking for repairs..." + switch(message_type) + if(AUTO_ANNOUNCE_ARRIVAL) + if(!arrival_toggle) + message = CompileText(arrival, target, rank) + return + if(AUTO_ANNOUNCE_NEWHEAD) + if(!newhead_toggle) + message = CompileText(newhead, target, rank) + return + if(AUTO_ANNOUNCE_ARRIVALS_BROKEN) + message = "The arrivals shuttle has been damaged. Docking for repairs..." + if(AUTO_ANNOUNCE_NODE) + message = replacetext(node_message, "%NODE", target) broadcast(message, channels) @@ -118,9 +135,11 @@ GLOBAL_LIST_EMPTY(announcement_systems) /obj/machinery/announcement_system/ui_data() var/list/data = list() data["arrival"] = arrival - data["arrivalToggle"] = arrivalToggle + data["arrivalToggle"] = arrival_toggle data["newhead"] = newhead - data["newheadToggle"] = newheadToggle + data["newheadToggle"] = newhead_toggle + data["node_message"] = node_message + data["node_toggle"] = announce_research_node return data /obj/machinery/announcement_system/ui_act(action, param) @@ -135,25 +154,28 @@ GLOBAL_LIST_EMPTY(announcement_systems) return switch(action) if("ArrivalText") - var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN) - if(!usr.can_perform_action(src, ALLOW_SILICON_REACH)) - return - if(NewMessage) - arrival = NewMessage - usr.log_message("updated the arrivals announcement to: [NewMessage]", LOG_GAME) + var/new_message = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN) + if(new_message) + arrival = new_message + usr.log_message("updated the arrivals announcement to: [new_message]", LOG_GAME) if("NewheadText") - var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN) - if(!usr.can_perform_action(src, ALLOW_SILICON_REACH)) - return - if(NewMessage) - newhead = NewMessage - usr.log_message("updated the head announcement to: [NewMessage]", LOG_GAME) - if("NewheadToggle") - newheadToggle = !newheadToggle + var/new_message = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN) + if(new_message) + newhead = new_message + usr.log_message("updated the head announcement to: [new_message]", LOG_GAME) + if("node_message") + var/new_message = trim(html_encode(param["new_text"]), MAX_MESSAGE_LEN) + if(new_message) + node_message = new_message + usr.log_message("updated the researched node announcement to: [node_message]", LOG_GAME) + if("newhead_toggle") + newhead_toggle = !newhead_toggle update_appearance() - if("ArrivalToggle") - arrivalToggle = !arrivalToggle + if("arrivalToggle") + arrival_toggle = !arrival_toggle update_appearance() + if("node_toggle") + announce_research_node = !announce_research_node add_fingerprint(usr) /obj/machinery/announcement_system/attack_robot(mob/living/silicon/user) @@ -173,6 +195,11 @@ GLOBAL_LIST_EMPTY(announcement_systems) arrival = pick("#!@%ERR-34%2 CANNOT LOCAT@# JO# F*LE!", "CRITICAL ERROR 99.", "ERR)#: DA#AB@#E NOT F(*ND!") newhead = pick("OV#RL()D: \[UNKNOWN??\] DET*#CT)D!", "ER)#R - B*@ TEXT F*O(ND!", "AAS.exe is not responding. NanoOS is searching for a solution to the problem.") + node_message = pick(list( + replacetext(/obj/machinery/announcement_system::node_message, "%NODE", /datum/techweb_node/mech_clown::display_name), + "R/NT1M3 A= ANNOUN-*#nt_SY!?EM.dm, LI%£ 86: N=0DE NULL!", + "BEPIS BEPIS BEPIS", + )) /obj/machinery/announcement_system/emp_act(severity) . = ..() diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 41950561571..9c3cde9f725 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -403,6 +403,29 @@ name = "R&D Console" greyscale_colors = CIRCUIT_COLOR_SCIENCE build_path = /obj/machinery/computer/rdconsole + var/silence_announcements = FALSE + +/obj/item/circuitboard/computer/rdconsole/examine(mob/user) + . = ..() + . += span_info("The board is configured to [silence_announcements ? "silence" : "announce"] researched nodes on radio.") + . += span_notice("The board mode can be changed with a [EXAMINE_HINT("multitool")].") + +/obj/item/circuitboard/computer/rdconsole/multitool_act(mob/living/user) + . = ..() + if(obj_flags & EMAGGED) + balloon_alert(user, "board mode is broken!") + return + silence_announcements = !silence_announcements + balloon_alert(user, "announcements [silence_announcements ? "enabled" : "disabled"]") + +/obj/item/circuitboard/computer/rdconsole/emag_act(mob/user, obj/item/card/emag/emag_card) + if (obj_flags & EMAGGED) + return FALSE + + obj_flags |= EMAGGED + silence_announcements = FALSE + to_chat(user, span_notice("You overload the node announcement chip, forcing every node to be announced on the common channel.")) + return TRUE /obj/item/circuitboard/computer/rdservercontrol name = "R&D Server Control" diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index afad1ffdb63..3ac69784dd9 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -234,11 +234,20 @@ dna.species.pre_equip_species_outfit(equipping, src, visual_only) equip_outfit_and_loadout(equipping.get_outfit(consistent), player_client?.prefs, visual_only, equipping) // NOVA EDIT - Loadout stuff - ORIGINAL: equip_outfit_and_loadout(equipping.get_outfit(consistent), player_client?.prefs, visual_only) -/// tells the given channel that the given mob is the new department head. See communications.dm for valid channels. -/datum/job/proc/announce_head(mob/living/carbon/human/H, channels, job_title) // NOVA EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: /datum/job/proc/announce_head(mob/living/carbon/human/H, channels) - if(H && GLOB.announcement_systems.len) - //timer because these should come after the captain announcement - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, job_title, channels), 1)) // NOVA EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, H.job, channels), 1)) +/datum/job/proc/announce_head(mob/living/carbon/human/human, channels, job_title) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels. // NOVA EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: /datum/job/proc/announce_head(mob/living/carbon/human/human, channels) + if(!human) + return + var/obj/machinery/announcement_system/system + var/list/available_machines = list() + for(var/obj/machinery/announcement_system/announce as anything in GLOB.announcement_systems) + if(announce.newhead_toggle) + available_machines += announce + break + if(!length(available_machines)) + return + system = pick(available_machines) + //timer because these should come after the captain announcement + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(system, TYPE_PROC_REF(/obj/machinery/announcement_system, announce), AUTO_ANNOUNCE_NEWHEAD, human.real_name, job_title, channels), 1)) // NOVA EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(system, TYPE_PROC_REF(/obj/machinery/announcement_system, announce), AUTO_ANNOUNCE_NEWHEAD, human.real_name, human.job, channels), 1)) //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/job/proc/player_old_enough(client/player) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index c7916f035a7..3611a75a29e 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -112,7 +112,7 @@ other types of metals and chemistry for reagents). * Args: * - stored_research - The techweb that's storing us. */ -/obj/item/disk/design_disk/proc/on_upload(datum/techweb/stored_research) +/obj/item/disk/design_disk/proc/on_upload(datum/techweb/stored_research, atom/research_source) return /obj/item/disk/design_disk/bepis @@ -133,9 +133,9 @@ other types of metals and chemistry for reagents). blueprints += new_entry ///Unhide and research our node so we show up in the R&D console. -/obj/item/disk/design_disk/bepis/on_upload(datum/techweb/stored_research) +/obj/item/disk/design_disk/bepis/on_upload(datum/techweb/stored_research, atom/research_source) stored_research.hidden_nodes -= bepis_node.id - stored_research.research_node(bepis_node, force = TRUE, auto_adjust_cost = FALSE) + stored_research.research_node(bepis_node, force = TRUE, auto_adjust_cost = FALSE, research_source = research_source) /** * Subtype of Bepis tech disk diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index d4dde8732a0..517eb7c5b9e 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -123,7 +123,7 @@ Nothing else in the console has ID requirements. user.investigate_log("researched [id]([json_encode(price)]) on techweb id [stored_research.id].", INVESTIGATE_RESEARCH) if(istype(stored_research, /datum/techweb/science)) SSblackbox.record_feedback("associative", "science_techweb_unlock", 1, list("id" = "[id]", "name" = TN.display_name, "price" = "[json_encode(price)]", "time" = ISOtime())) - if(stored_research.research_node_id(id)) + if(stored_research.research_node_id(id, research_source = src)) say("Successfully researched [TN.display_name].") var/logname = "Unknown" if(HAS_AI_ACCESS(user)) @@ -161,6 +161,9 @@ Nothing else in the console has ID requirements. balloon_alert(user, "security protocols disabled") playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) obj_flags |= EMAGGED + var/obj/item/circuitboard/computer/rdconsole/board = circuit + if(!(board.obj_flags & EMAGGED)) + board.silence_announcements = TRUE locked = FALSE return TRUE @@ -362,7 +365,7 @@ Nothing else in the console has ID requirements. if(D) stored_research.add_design(D, TRUE) say("Uploading blueprints from disk.") - d_disk.on_upload(stored_research) + d_disk.on_upload(stored_research, src) return TRUE if (params["type"] == RND_TECH_DISK) if (QDELETED(t_disk)) diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index fd6ca7949b4..3da8fe4e1c9 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -361,10 +361,10 @@ return TRUE -/datum/techweb/proc/research_node_id(id, force, auto_update_points, get_that_dosh_id) - return research_node(SSresearch.techweb_node_by_id(id), force, auto_update_points, get_that_dosh_id) +/datum/techweb/proc/research_node_id(id, force, auto_update_points, get_that_dosh_id, atom/research_source) + return research_node(SSresearch.techweb_node_by_id(id), force, auto_update_points, get_that_dosh_id, research_source) -/datum/techweb/proc/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE, get_that_dosh = TRUE) +/datum/techweb/proc/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE, get_that_dosh = TRUE, atom/research_source) if(!istype(node)) return FALSE update_node_status(node) diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 23ad6fd213d..b6d3bd74d69 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -42,6 +42,12 @@ var/show_on_wiki = TRUE /// Hidden Mech nodes unlocked when mech fabricator emaged. var/illegal_mech_node = FALSE + /** + * If set, the researched node will be announced on these channels by an announcement system + * with 'announce_research_node' set to TRUE when researched by the station. + * Not every node has to be announced if you want, some are best kept a little "subtler", like Illegal Weapons. + */ + var/list/announce_channels /datum/techweb_node/error_node id = "ERROR" @@ -109,5 +115,25 @@ return techweb_point_display_generic(get_price(TN)) ///Proc called when the Station (Science techweb specific) researches a node. -/datum/techweb_node/proc/on_station_research() - SHOULD_CALL_PARENT(FALSE) +/datum/techweb_node/proc/on_station_research(atom/research_source) + SHOULD_CALL_PARENT(TRUE) + var/channels_to_use = announce_channels + if(istype(research_source, /obj/machinery/computer/rdconsole)) + var/obj/machinery/computer/rdconsole/console = research_source + var/obj/item/circuitboard/computer/rdconsole/board = console.circuit + if(board.silence_announcements) + return + if(board.obj_flags & EMAGGED) + channels_to_use = list(RADIO_CHANNEL_COMMON) + if(!length(channels_to_use) || starting_node) + return + var/obj/machinery/announcement_system/system + var/list/available_machines = list() + for(var/obj/machinery/announcement_system/announce as anything in GLOB.announcement_systems) + if(announce.announce_research_node) + available_machines += announce + break + if(!length(available_machines)) + return + system = pick(available_machines) + system.announce(AUTO_ANNOUNCE_NODE, display_name, channels = channels_to_use) diff --git a/code/modules/research/techweb/nodes/alien_nodes.dm b/code/modules/research/techweb/nodes/alien_nodes.dm index 58e8dbfc68f..331b91bae61 100644 --- a/code/modules/research/techweb/nodes/alien_nodes.dm +++ b/code/modules/research/techweb/nodes/alien_nodes.dm @@ -30,6 +30,7 @@ hidden = TRUE /datum/techweb_node/alientech/on_station_research() + . = ..() SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_ALIENTECH] = TRUE /datum/techweb_node/alien_engi @@ -59,6 +60,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) hidden = TRUE + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/alien_surgery id = TECHWEB_NODE_ALIEN_SURGERY @@ -99,3 +101,4 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) discount_experiments = list(/datum/experiment/scanning/points/slime/hard = TECHWEB_TIER_5_POINTS) hidden = TRUE + announce_channels = list(RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/research/techweb/nodes/atmos_nodes.dm b/code/modules/research/techweb/nodes/atmos_nodes.dm index f1ec74b50f4..a61a6a6b094 100644 --- a/code/modules/research/techweb/nodes/atmos_nodes.dm +++ b/code/modules/research/techweb/nodes/atmos_nodes.dm @@ -48,6 +48,7 @@ /datum/experiment/ordnance/gaseous/bz, /datum/experiment/ordnance/gaseous/noblium, ) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/plasma_control id = TECHWEB_NODE_PLASMA_CONTROL @@ -63,6 +64,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) required_experiments = list(/datum/experiment/ordnance/gaseous/plasma) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/fusion id = TECHWEB_NODE_FUSION @@ -84,6 +86,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) discount_experiments = list(/datum/experiment/ordnance/gaseous/nitrous_oxide = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/exp_tools id = TECHWEB_NODE_EXP_TOOLS @@ -105,6 +108,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/ordnance/gaseous/bz = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/rcd_upgrade id = TECHWEB_NODE_RCD_UPGRADE @@ -122,3 +126,4 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) discount_experiments = list(/datum/experiment/ordnance/gaseous/noblium = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) diff --git a/code/modules/research/techweb/nodes/bepis_nodes.dm b/code/modules/research/techweb/nodes/bepis_nodes.dm index baefd8c11d0..f477569aea5 100644 --- a/code/modules/research/techweb/nodes/bepis_nodes.dm +++ b/code/modules/research/techweb/nodes/bepis_nodes.dm @@ -1,3 +1,5 @@ +//Nodes that are found inside Bepis Disks. + /datum/techweb_node/light_apps id = TECHWEB_NODE_LIGHT_APPS display_name = "Illumination Applications" @@ -10,6 +12,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_COMMON) /datum/techweb_node/extreme_office id = TECHWEB_NODE_EXTREME_OFFICE @@ -22,6 +25,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_COMMON) /datum/techweb_node/spec_eng id = TECHWEB_NODE_SPEC_ENG @@ -34,6 +38,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/aus_security id = TECHWEB_NODE_AUS_SECURITY @@ -46,6 +51,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/interrogation id = TECHWEB_NODE_INTERROGATION @@ -58,6 +64,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/sticky_advanced id = TECHWEB_NODE_STICKY_ADVANCED @@ -70,6 +77,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_COMMON) /datum/techweb_node/tackle_advanced id = TECHWEB_NODE_TACKLE_ADVANCED @@ -83,6 +91,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/mod_experimental id = TECHWEB_NODE_MOD_EXPERIMENTAL @@ -97,6 +106,7 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_COMMON) /datum/techweb_node/posisphere id = TECHWEB_NODE_POSITRONIC_SPHERE @@ -108,3 +118,4 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) hidden = TRUE experimental = TRUE + announce_channels = list(RADIO_CHANNEL_SCIENCE) diff --git a/code/modules/research/techweb/nodes/biology_nodes.dm b/code/modules/research/techweb/nodes/biology_nodes.dm index 7b553445a9c..25f9163ab48 100644 --- a/code/modules/research/techweb/nodes/biology_nodes.dm +++ b/code/modules/research/techweb/nodes/biology_nodes.dm @@ -14,6 +14,7 @@ "mod_reagent_scanner", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cytology id = TECHWEB_NODE_CYTOLOGY @@ -60,6 +61,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/scanning/people/mutant = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) // Botany root node /datum/techweb_node/botany_equip @@ -88,6 +90,7 @@ "portaseeder", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SERVICE) /datum/techweb_node/selection id = TECHWEB_NODE_SELECTION @@ -101,3 +104,4 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) required_experiments = list(/datum/experiment/scanning/random/plants/wild) discount_experiments = list(/datum/experiment/scanning/random/plants/traits = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SERVICE) diff --git a/code/modules/research/techweb/nodes/cyborg_nodes.dm b/code/modules/research/techweb/nodes/cyborg_nodes.dm index 8a9d09807d6..eeeed268be5 100644 --- a/code/modules/research/techweb/nodes/cyborg_nodes.dm +++ b/code/modules/research/techweb/nodes/cyborg_nodes.dm @@ -44,6 +44,7 @@ "borg_upgrade_restart", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/borg_service id = TECHWEB_NODE_BORG_SERVICES @@ -59,6 +60,7 @@ "borg_upgrade_service_cookbook", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/borg_mining id = TECHWEB_NODE_BORG_MINING @@ -71,6 +73,7 @@ "borg_upgrade_diamonddrill", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/borg_medical id = TECHWEB_NODE_BORG_MEDICAL @@ -87,6 +90,7 @@ "borg_upgrade_surgicalomnitool", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/borg_utility id = TECHWEB_NODE_BORG_UTILITY @@ -105,6 +109,7 @@ "borg_upgrade_trashofholding", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/borg_utility/New() . = ..() @@ -123,6 +128,7 @@ "borg_upgrade_inducer", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) // Implants root node /datum/techweb_node/passive_implants @@ -144,6 +150,7 @@ "c38_trac", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/cyber_implants id = TECHWEB_NODE_CYBER_IMPLANTS @@ -157,6 +164,7 @@ "ci-herculean", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/New() ..() @@ -174,6 +182,7 @@ "ci-antistun", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/integrated_toolsets id = TECHWEB_NODE_INTERGRATED_TOOLSETS @@ -186,6 +195,7 @@ "ci-surgery", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/cyber_organs id = TECHWEB_NODE_CYBER_ORGANS @@ -202,6 +212,7 @@ "cybernetic_heart_tier2", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/cyber_organs_upgraded id = TECHWEB_NODE_CYBER_ORGANS_UPGRADED @@ -221,6 +232,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) required_experiments = list(/datum/experiment/scanning/people/augmented_organs) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cyber/cyber_organs_adv id = TECHWEB_NODE_CYBER_ORGANS_ADV @@ -236,3 +248,4 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) discount_experiments = list(/datum/experiment/scanning/people/android = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/research/techweb/nodes/engi_nodes.dm b/code/modules/research/techweb/nodes/engi_nodes.dm index 949b880d1f2..0d8572130fb 100644 --- a/code/modules/research/techweb/nodes/engi_nodes.dm +++ b/code/modules/research/techweb/nodes/engi_nodes.dm @@ -42,6 +42,7 @@ "super_cell", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/parts_adv id = TECHWEB_NODE_PARTS_ADV @@ -59,6 +60,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) required_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier2_any) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/parts_bluespace @@ -78,6 +80,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/scanning/points/machinery_tiered_scan/tier3_any = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/telecomms id = TECHWEB_NODE_TELECOMS @@ -167,6 +170,7 @@ "tray_goggles", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/holographics id = TECHWEB_NODE_HOLOGRAPHICS @@ -211,6 +215,7 @@ "ci-sechud", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING, RADIO_CHANNEL_SECURITY, RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/night_vision id = TECHWEB_NODE_NIGHT_VISION @@ -226,3 +231,4 @@ "security_hud_night", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_ENGINEERING, RADIO_CHANNEL_SECURITY, RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/research/techweb/nodes/mech_nodes.dm b/code/modules/research/techweb/nodes/mech_nodes.dm index b09957076d7..82d6484bf02 100644 --- a/code/modules/research/techweb/nodes/mech_nodes.dm +++ b/code/modules/research/techweb/nodes/mech_nodes.dm @@ -36,6 +36,7 @@ "mech_radio", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_clown id = TECHWEB_NODE_MECH_CLOWN @@ -60,6 +61,7 @@ "borg_transform_clown", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_SECURITY) //The dread upon security when they hear this... /datum/techweb_node/mech_medical id = TECHWEB_NODE_MECH_MEDICAL @@ -96,6 +98,7 @@ "clarke_peri", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_SUPPLY) /datum/techweb_node/mech_combat id = TECHWEB_NODE_MECH_COMBAT @@ -112,6 +115,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) required_experiments = list(/datum/experiment/scanning/random/mecha_equipped_scan) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_assault id = TECHWEB_NODE_MECH_ASSAULT @@ -132,6 +136,7 @@ "durand_targ", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_light id = TECHWEB_NODE_MECH_LIGHT @@ -152,6 +157,7 @@ "gygax_targ", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_heavy id = TECHWEB_NODE_MECH_HEAVY @@ -172,6 +178,7 @@ "savannah_ivanov_targ", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_infiltrator id = TECHWEB_NODE_MECH_INFILTRATOR @@ -192,6 +199,7 @@ "phazon_targ", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/justice id = "mecha_justice" @@ -222,6 +230,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/scanning/random/mecha_damage_scan = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_firearms id = TECHWEB_NODE_MECH_FIREARMS @@ -237,6 +246,7 @@ "mech_carbine_ammo", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_heavy_arms id = TECHWEB_NODE_MECH_HEAVY_ARMS @@ -252,6 +262,7 @@ "mech_missile_rack_ammo", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mech_equip_bluespace id = TECHWEB_NODE_MECH_EQUIP_BLUESPACE @@ -264,3 +275,4 @@ "mech_wormhole_gen", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) diff --git a/code/modules/research/techweb/nodes/medbay_nodes.dm b/code/modules/research/techweb/nodes/medbay_nodes.dm index fababbc55e7..897a2edf18e 100644 --- a/code/modules/research/techweb/nodes/medbay_nodes.dm +++ b/code/modules/research/techweb/nodes/medbay_nodes.dm @@ -60,6 +60,7 @@ "fluid_ducts", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/medbay_equip_adv id = TECHWEB_NODE_MEDBAY_EQUIP_ADV @@ -79,6 +80,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) required_experiments = list(/datum/experiment/scanning/reagent/haloperidol) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/cryostasis id = TECHWEB_NODE_CRYOSTASIS @@ -94,3 +96,4 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/scanning/reagent/cryostylane = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/research/techweb/nodes/mining_nodes.dm b/code/modules/research/techweb/nodes/mining_nodes.dm index d8a6539caa3..1bfa3a9284a 100644 --- a/code/modules/research/techweb/nodes/mining_nodes.dm +++ b/code/modules/research/techweb/nodes/mining_nodes.dm @@ -48,6 +48,7 @@ "mesons", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SUPPLY) /datum/techweb_node/low_pressure_excavation id = TECHWEB_NODE_LOW_PRESSURE_EXCAVATION @@ -67,6 +68,7 @@ "borg_upgrade_hypermod", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SUPPLY) /datum/techweb_node/plasma_mining id = TECHWEB_NODE_PLASMA_MINING @@ -78,6 +80,7 @@ "plasmacutter_adv", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SUPPLY) /datum/techweb_node/bitrunning id = TECHWEB_NODE_BITRUNNING @@ -90,6 +93,7 @@ "netpod", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SUPPLY) /datum/techweb_node/mining_adv id = TECHWEB_NODE_MINING_ADV @@ -102,3 +106,4 @@ "mech_diamond_drill", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SUPPLY) diff --git a/code/modules/research/techweb/nodes/modsuit_nodes.dm b/code/modules/research/techweb/nodes/modsuit_nodes.dm index 955389f61ae..cc31a1fc1ef 100644 --- a/code/modules/research/techweb/nodes/modsuit_nodes.dm +++ b/code/modules/research/techweb/nodes/modsuit_nodes.dm @@ -36,6 +36,7 @@ "mod_sign_radio", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/mod_entertainment id = TECHWEB_NODE_MOD_ENTERTAINMENT @@ -49,6 +50,7 @@ "mod_waddle", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_SERVICE) /datum/techweb_node/mod_medical id = TECHWEB_NODE_MOD_MEDICAL @@ -63,6 +65,7 @@ "mod_patienttransport", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/mod_engi id = TECHWEB_NODE_MOD_ENGI @@ -77,6 +80,7 @@ "mod_mister_atmos", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/mod_security id = TECHWEB_NODE_MOD_SECURITY @@ -95,6 +99,7 @@ "mod_criminalcapture", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_SECURITY) /datum/techweb_node/mod_medical_adv id = TECHWEB_NODE_MOD_MEDICAL_ADV @@ -108,6 +113,7 @@ "mod_statusreadout", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/mod_engi_adv id = TECHWEB_NODE_MOD_ENGI_ADV @@ -122,6 +128,7 @@ "mod_storage_expanded", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_ENGINEERING) /datum/techweb_node/mod_engi_adv/New() if(HAS_TRAIT(SSstation, STATION_TRAIT_RADIOACTIVE_NEBULA)) //we'll really need the rad protection modsuit module @@ -139,3 +146,4 @@ "mod_kinesis", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) diff --git a/code/modules/research/techweb/nodes/research_nodes.dm b/code/modules/research/techweb/nodes/research_nodes.dm index 619f3fdb3c6..2cc0f9497ff 100644 --- a/code/modules/research/techweb/nodes/research_nodes.dm +++ b/code/modules/research/techweb/nodes/research_nodes.dm @@ -28,6 +28,7 @@ "bluespace_crystal", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/applied_bluespace id = TECHWEB_NODE_APPLIED_BLUESPACE @@ -49,6 +50,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) required_experiments = list(/datum/experiment/scanning/points/bluespace_crystal) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_MEDICAL, RADIO_CHANNEL_SERVICE, RADIO_CHANNEL_SUPPLY) /datum/techweb_node/bluespace_travel id = TECHWEB_NODE_BLUESPACE_TRAVEL @@ -67,6 +69,7 @@ "swapper", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/anomaly_research id = TECHWEB_NODE_ANOMALY_RESEARCH @@ -79,6 +82,7 @@ "reactive_armour", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/anomaly_shells id = TECHWEB_NODE_ANOMALY_SHELLS @@ -94,3 +98,4 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS) discount_experiments = list(/datum/experiment/scanning/points/anomalies = TECHWEB_TIER_5_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) diff --git a/code/modules/research/techweb/nodes/robo_nodes.dm b/code/modules/research/techweb/nodes/robo_nodes.dm index ff018e85b7c..9cfa3028961 100644 --- a/code/modules/research/techweb/nodes/robo_nodes.dm +++ b/code/modules/research/techweb/nodes/robo_nodes.dm @@ -51,6 +51,7 @@ "remove_module", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE) /datum/techweb_node/ai/New() . = ..() @@ -95,3 +96,4 @@ "purge_module", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SCIENCE, RADIO_CHANNEL_COMMAND) diff --git a/code/modules/research/techweb/nodes/security_nodes.dm b/code/modules/research/techweb/nodes/security_nodes.dm index 2d3dd63864f..97d2036207c 100644 --- a/code/modules/research/techweb/nodes/security_nodes.dm +++ b/code/modules/research/techweb/nodes/security_nodes.dm @@ -39,6 +39,8 @@ "electropack", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY) + /datum/techweb_node/riot_supression id = TECHWEB_NODE_RIOT_SUPRESSION @@ -55,6 +57,7 @@ "bola_energy", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/explosives id = TECHWEB_NODE_EXPLOSIVES @@ -68,6 +71,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) required_experiments = list(/datum/experiment/ordnance/explosive/lowyieldbomb) + announce_channels = list(RADIO_CHANNEL_SECURITY, RADIO_CHANNEL_MEDICAL) /datum/techweb_node/exotic_ammo id = TECHWEB_NODE_EXOTIC_AMMO @@ -81,6 +85,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/ordnance/explosive/highyieldbomb = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/electric_weapons id = TECHWEB_NODE_ELECTRIC_WEAPONS @@ -94,6 +99,7 @@ "lasershell", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY) /datum/techweb_node/beam_weapons id = TECHWEB_NODE_BEAM_WEAPONS @@ -105,3 +111,4 @@ "nuclear_gun", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_SECURITY) diff --git a/code/modules/research/techweb/nodes/service_nodes.dm b/code/modules/research/techweb/nodes/service_nodes.dm index 3735dc41b3b..a2f6b030071 100644 --- a/code/modules/research/techweb/nodes/service_nodes.dm +++ b/code/modules/research/techweb/nodes/service_nodes.dm @@ -51,6 +51,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) discount_experiments = list(/datum/experiment/scanning/random/janitor_trash = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SERVICE) /datum/techweb_node/consoles id = TECHWEB_NODE_CONSOLES @@ -78,6 +79,7 @@ "bounty_pad", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_SERVICE) /datum/techweb_node/gaming id = TECHWEB_NODE_GAMING @@ -145,6 +147,7 @@ "roastingstick", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) + announce_channels = list(RADIO_CHANNEL_SERVICE) // Fishing root node /datum/techweb_node/fishing_equip diff --git a/code/modules/research/techweb/nodes/surgery_nodes.dm b/code/modules/research/techweb/nodes/surgery_nodes.dm index 4be7a3256ac..7af1dacf1df 100644 --- a/code/modules/research/techweb/nodes/surgery_nodes.dm +++ b/code/modules/research/techweb/nodes/surgery_nodes.dm @@ -20,6 +20,7 @@ "surgery_heal_burn_upgrade", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/surgery_adv id = TECHWEB_NODE_SURGERY_ADV @@ -37,6 +38,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) required_experiments = list(/datum/experiment/autopsy/human) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/surgery_exp id = TECHWEB_NODE_SURGERY_EXP @@ -67,6 +69,7 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_3_POINTS) discount_experiments = list(/datum/experiment/autopsy/nonhuman = TECHWEB_TIER_3_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) /datum/techweb_node/surgery_tools id = TECHWEB_NODE_SURGERY_TOOLS @@ -80,3 +83,4 @@ ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_4_POINTS) discount_experiments = list(/datum/experiment/autopsy/xenomorph = TECHWEB_TIER_4_POINTS) + announce_channels = list(RADIO_CHANNEL_MEDICAL) diff --git a/code/modules/research/techweb/techweb_types.dm b/code/modules/research/techweb/techweb_types.dm index f5532e9e53f..407008b2844 100644 --- a/code/modules/research/techweb/techweb_types.dm +++ b/code/modules/research/techweb/techweb_types.dm @@ -6,10 +6,10 @@ organization = "Nanotrasen" should_generate_points = TRUE -/datum/techweb/science/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE, get_that_dosh = TRUE) +/datum/techweb/science/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE, get_that_dosh = TRUE, atom/research_source) . = ..() if(.) - node.on_station_research() + node.on_station_research(research_source) /datum/techweb/oldstation id = "CHARLIE" diff --git a/tgui/packages/tgui/interfaces/AutomatedAnnouncement.tsx b/tgui/packages/tgui/interfaces/AutomatedAnnouncement.tsx index f08ee83fd4f..f88b2da67f4 100644 --- a/tgui/packages/tgui/interfaces/AutomatedAnnouncement.tsx +++ b/tgui/packages/tgui/interfaces/AutomatedAnnouncement.tsx @@ -9,16 +9,29 @@ const TOOLTIP_TEXT = ` %RANK with their job. `; +const TOOLTIP_NODE = ` + %NODE will be replaced with the researched node. +`; + type Data = { arrivalToggle: BooleanLike; arrival: string; newheadToggle: BooleanLike; newhead: string; + node_toggle: BooleanLike; + node_message: string; }; export const AutomatedAnnouncement = (props) => { const { act, data } = useBackend(); - const { arrivalToggle, arrival, newheadToggle, newhead } = data; + const { + arrivalToggle, + arrival, + newheadToggle, + newhead, + node_toggle, + node_message, + } = data; return ( @@ -90,6 +103,40 @@ export const AutomatedAnnouncement = (props) => { +
act('node_toggle')} + /> + } + > + + + } + > + + act('node_message', { + newText: value, + }) + } + /> + + +
); From 9ca5eeb591cbc155708eb15d302867673127d081 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:57:22 +0000 Subject: [PATCH 065/142] Automatic changelog for PR #86093 [ci skip] --- html/changelogs/AutoChangeLog-pr-86093.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86093.yml diff --git a/html/changelogs/AutoChangeLog-pr-86093.yml b/html/changelogs/AutoChangeLog-pr-86093.yml new file mode 100644 index 00000000000..e0f5e74bcab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86093.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Automated announcement systems now announce researched nodes to their respective departments. You can stop this by either disabling the announcement systems or by using a multitool on the circuitboard of the console you're researching nodes from." \ No newline at end of file From 29d0baf84654d6b37f29b7c676e0463da7734e6f Mon Sep 17 00:00:00 2001 From: Pickle-Coding <58013024+Pickle-Coding@users.noreply.github.com> Date: Mon, 16 Sep 2024 04:19:29 +0100 Subject: [PATCH 066/142] Fixes supermatter zaps getting called with 0 zap_cutoff. (#85625) Supermatter high energy processing no longer calls supermatter_zap() if delta_time is 0. Also early returns in supermatter_zap() if zap_str or zap_cutoff are invalid. ## Changelog :cl: fix: Fixes high energy supermatter zaps arcing through an unusually high amount of objects and ignoring grounding rods. /:cl: --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> --- code/modules/power/supermatter/supermatter.dm | 5 +++++ .../modules/power/supermatter/supermatter_extra_effects.dm | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 89ff75ab643..8a4baf58c45 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -898,6 +898,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/proc/supermatter_zap(atom/zapstart = src, range = 5, zap_str = 3.2 MEGA JOULES, zap_flags = ZAP_SUPERMATTER_FLAGS, list/targets_hit = list(), zap_cutoff = 1.2 MEGA JOULES, power_level = 0, zap_icon = DEFAULT_ZAP_ICON_STATE, color = null) if(QDELETED(zapstart)) return + if(zap_cutoff <= 0) + stack_trace("/obj/machinery/supermatter_zap() was called with a non-positive value") + return + if(zap_str <= 0) // Just in case something scales zap_str and zap_cutoff to 0. + return . = zapstart.dir //If the strength of the zap decays past the cutoff, we stop if(zap_str < zap_cutoff) diff --git a/code/modules/power/supermatter/supermatter_extra_effects.dm b/code/modules/power/supermatter/supermatter_extra_effects.dm index b6cc1b792bd..5d4c3474d59 100644 --- a/code/modules/power/supermatter/supermatter_extra_effects.dm +++ b/code/modules/power/supermatter/supermatter_extra_effects.dm @@ -130,9 +130,10 @@ if(zap_count >= 1) playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) var/delta_time = (SSmachines.times_fired - last_high_energy_zap_perspective_machines) * SSmachines.wait / (1 SECONDS) - for(var/i in 1 to zap_count) - supermatter_zap(src, range, clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time, flags, zap_cutoff = src.zap_cutoff * delta_time, power_level = internal_energy, zap_icon = src.zap_icon) - last_high_energy_zap_perspective_machines = SSmachines.times_fired + if(delta_time) + for(var/i in 1 to zap_count) + supermatter_zap(src, range, clamp(internal_energy * 3200, 6.4e6, 3.2e7) * delta_time, flags, zap_cutoff = src.zap_cutoff * delta_time, power_level = internal_energy, zap_icon = src.zap_icon) + last_high_energy_zap_perspective_machines = SSmachines.times_fired if(prob(5)) supermatter_anomaly_gen(src, FLUX_ANOMALY, rand(5, 10)) if(prob(5)) From 7ab41ae94cd79dd3f206aea3a1c59be0ec40f23a Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:23:41 +0000 Subject: [PATCH 067/142] Automatic changelog for PR #85625 [ci skip] --- html/changelogs/AutoChangeLog-pr-85625.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-85625.yml diff --git a/html/changelogs/AutoChangeLog-pr-85625.yml b/html/changelogs/AutoChangeLog-pr-85625.yml new file mode 100644 index 00000000000..7553b074f4f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-85625.yml @@ -0,0 +1,4 @@ +author: "Pickle-Coding" +delete-after: True +changes: + - bugfix: "Fixes high energy supermatter zaps arcing through an unusually high amount of objects and ignoring grounding rods." \ No newline at end of file From 3f22c63ecd073350014757c237b5e7f83c82c1dc Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:40:06 -0500 Subject: [PATCH 068/142] Lets you dump bodybags (with people in them) down disposals (#86675) ## About The Pull Request Bodybags (with people inside them) can be click+dragged to disposals, so you can dump bodybags down disposals ## Why It's Good For The Game It's a classic crime trope, so I thought it'd be funny to represent. ## Changelog :cl: Melbert qol: You can dump bodybags (with people inside them) down disposals /:cl: --- .../crates_lockers/closets/bodybag.dm | 37 ++++++---- code/modules/recycling/disposal/bin.dm | 72 ++++++++++++++----- 2 files changed, 75 insertions(+), 34 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 9504928d206..66950b0845f 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -116,8 +116,22 @@ */ /obj/structure/closet/body_bag/proc/perform_fold(mob/living/carbon/human/the_folder) visible_message(span_notice("[the_folder] folds up [src].")) - var/obj/item/bodybag/folding_bodybag = foldedbag_instance || new foldedbag_path - the_folder.put_in_hands(folding_bodybag) + the_folder.put_in_hands(undeploy_bodybag(the_folder.loc)) + +/// Makes the bag into an item, returns that item +/obj/structure/closet/body_bag/proc/undeploy_bodybag(atom/fold_loc) + var/obj/item/bodybag/folding_bodybag = foldedbag_instance || new foldedbag_path() + if(fold_loc) + folding_bodybag.forceMove(fold_loc) + return folding_bodybag + +/obj/structure/closet/body_bag/container_resist_act(mob/living/user, loc_required = TRUE) + // ideally we support this natively but i guess that's for a later time + if(!istype(loc, /obj/machinery/disposal)) + return ..() + for(var/atom/movable/thing as anything in src) + thing.forceMove(loc) + undeploy_bodybag(loc) /obj/structure/closet/body_bag/bluespace name = "bluespace body bag" @@ -152,7 +166,7 @@ /obj/structure/closet/body_bag/bluespace/perform_fold(mob/living/carbon/human/the_folder) visible_message(span_notice("[the_folder] folds up [src].")) - var/obj/item/bodybag/folding_bodybag = foldedbag_instance || new foldedbag_path + var/obj/item/bodybag/folding_bodybag = undeploy_bodybag(the_folder.loc) var/max_weight_of_contents = initial(folding_bodybag.w_class) for(var/am in contents) var/atom/movable/content = am @@ -277,18 +291,9 @@ icon_state = initial(icon_state) /obj/structure/closet/body_bag/environmental/prisoner/container_resist_act(mob/living/user, loc_required = TRUE) - /// copy-pasted with changes because flavor text as well as some other misc stuff - if(opened) - return - if(ismovable(loc)) - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT - var/atom/movable/location = loc - location.relay_container_resist_act(user, src) - return - if(!sinched) - open(user) - return + // copy-pasted with changes because flavor text as well as some other misc stuff + if(opened || ismovable(loc) || !sinched) + return ..() user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT @@ -301,6 +306,8 @@ //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting user.visible_message(span_danger("[user] successfully broke out of [src]!"), span_notice("You successfully break out of [src]!")) + if(istype(loc, /obj/machinery/disposal)) + return ..() bust_open() else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 79c6be9f474..cd100ba0a4d 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -165,9 +165,11 @@ user.visible_message(span_notice("[user.name] places \the [I] into \the [src]."), span_notice("You place \the [I] into \the [src].")) /// Mouse drop another mob or self -/obj/machinery/disposal/mouse_drop_receive(mob/living/target, mob/living/user, params) - if(istype(target)) +/obj/machinery/disposal/mouse_drop_receive(atom/target, mob/living/user, params) + if(isliving(target)) stuff_mob_in(target, user) + if(istype(target, /obj/structure/closet/body_bag) && (user.mobility_flags & (MOBILITY_PICKUP|MOBILITY_STAND) == (MOBILITY_PICKUP|MOBILITY_STAND))) + stuff_bodybag_in(target, user) /// Handles stuffing a grabbed mob into the disposal /obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user) @@ -176,33 +178,65 @@ if (iscyborg(user)) var/mob/living/silicon/robot/borg = user if (!borg.model || !borg.model.canDispose) - return + return FALSE else - return + return FALSE if(!isturf(user.loc)) //No magically doing it from inside closets - return + return FALSE if(target.buckled || target.has_buckled_mobs()) - return + return FALSE if(target.mob_size > MOB_SIZE_HUMAN) to_chat(user, span_warning("[target] doesn't fit inside [src]!")) - return + return FALSE add_fingerprint(user) if(user == target) user.visible_message(span_warning("[user] starts climbing into [src]."), span_notice("You start climbing into [src]...")) else target.visible_message(span_danger("[user] starts putting [target] into [src]."), span_userdanger("[user] starts putting you into [src]!")) - if(do_after(user, 2 SECONDS, target)) - if (!loc) - return - target.forceMove(src) - if(user == target) - user.visible_message(span_warning("[user] climbs into [src]."), span_notice("You climb into [src].")) - . = TRUE - else - target.visible_message(span_danger("[user] places [target] in [src]."), span_userdanger("[user] places you in [src].")) - log_combat(user, target, "stuffed", addition="into [src]") - . = TRUE - update_appearance() + if(!do_after(user, 2 SECONDS, target) || QDELETED(src)) + return FALSE + target.forceMove(src) + if(user == target) + user.visible_message(span_warning("[user] climbs into [src]."), span_notice("You climb into [src].")) + else + target.visible_message(span_danger("[user] places [target] in [src]."), span_userdanger("[user] places you in [src].")) + log_combat(user, target, "stuffed", addition="into [src]") + update_appearance() + return TRUE + +/obj/machinery/disposal/proc/stuff_bodybag_in(obj/structure/closet/body_bag/bag, mob/living/user) + if(!length(bag.contents)) + bag.undeploy_bodybag(src) + qdel(bag) + user.visible_message( + span_warning("[user] stuffs the empty [bag.name] into [src]."), + span_notice("You stuff the empty [bag.name] into [src].") + ) + return TRUE + + user.visible_message( + span_warning("[user] starts putting [bag] into [src]."), + span_notice("You start putting [bag] into [src]...") + ) + + if(!do_after(user, 4 SECONDS, bag) || QDELETED(src)) + return FALSE + + user.visible_message( + span_warning("[user] places [bag] in [src]."), + span_notice("You place [bag] in [src].") + ) + + if(!length(bag.contents)) + bag.undeploy_bodybag(src) + qdel(bag) + else + bag.add_fingerprint(user) + bag.forceMove(src) + + add_fingerprint(user) + update_appearance() + return TRUE /obj/machinery/disposal/relaymove(mob/living/user, direction) attempt_escape(user) From abc76d060c21a6fab5de04f9f700a0ab64633859 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 06:40:29 +0000 Subject: [PATCH 069/142] Automatic changelog for PR #86675 [ci skip] --- html/changelogs/AutoChangeLog-pr-86675.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86675.yml diff --git a/html/changelogs/AutoChangeLog-pr-86675.yml b/html/changelogs/AutoChangeLog-pr-86675.yml new file mode 100644 index 00000000000..de20fac8f85 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86675.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - qol: "You can dump bodybags (with people inside them) down disposals" \ No newline at end of file From 7d0ef8eb1c2a98a80d8313745d199b6dfcca42a4 Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Mon, 16 Sep 2024 02:40:52 -0400 Subject: [PATCH 070/142] Adds linebreaks to smartfridge examine (#86673) ## About The Pull Request Tin. Smartfridges have a nonstandard way of arranging their examine text printout. This just puts it in line with the rest of examines so it will display multiline and get line breaks added. ## Why It's Good For The Game Further standardizes examine text. Before: ![image](https://github.com/user-attachments/assets/85805e36-3733-42c1-850b-cf5e87d550b4) After: ![ShareX_x7nCaw74BH](https://github.com/user-attachments/assets/2f539109-9601-4688-9cd8-77f29467114f) ## Changelog :cl: fix: smartfridges and drying racks will now display their examine text information mutlilined /:cl: --- code/modules/food_and_drinks/machinery/smartfridge.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index 46baf21fd6c..26fe387ba61 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -203,7 +203,7 @@ /// Returns details related to the fridge structure /obj/machinery/smartfridge/proc/structure_examine() - . = "" + . = list() if(welded_down) . += span_info("It's moorings are firmly [EXAMINE_HINT("welded")] to the floor.") From 937600ff7cd0eac8f6ca506592152a3c7756d611 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 06:41:13 +0000 Subject: [PATCH 071/142] Automatic changelog for PR #86673 [ci skip] --- html/changelogs/AutoChangeLog-pr-86673.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86673.yml diff --git a/html/changelogs/AutoChangeLog-pr-86673.yml b/html/changelogs/AutoChangeLog-pr-86673.yml new file mode 100644 index 00000000000..877b403b42e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86673.yml @@ -0,0 +1,4 @@ +author: "vinylspiders" +delete-after: True +changes: + - bugfix: "smartfridges and drying racks will now display their examine text information mutlilined" \ No newline at end of file From 13ef10c80d0c2b3a3e7a19b8d28fadd9f598233b Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Mon, 16 Sep 2024 09:42:34 +0300 Subject: [PATCH 072/142] reverts some unintended duplicate checks (#86674) ## About The Pull Request when working on #86031 , i added some checks that were already being handled earlier in the chain, serving nothing. thanks to melbert for catching these ## Why It's Good For The Game removes some duplicated checks --- code/datums/storage/storage.dm | 4 ---- code/game/machinery/pipe/pipe_dispenser.dm | 3 --- code/game/objects/items/devices/radio/headset.dm | 4 +--- code/game/objects/items/storage/bags.dm | 2 -- code/game/objects/structures/crates_lockers/closets.dm | 2 -- 5 files changed, 1 insertion(+), 14 deletions(-) diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 82e1bf6b37c..5b2c9ce6980 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -826,10 +826,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return if(!iscarbon(user) && !isdrone(user)) return - var/mob/living/user_living = user - if(user_living.incapacitated) - return - attempt_insert(dropping, user) return COMPONENT_CANCEL_MOUSEDROPPED_ONTO diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 1e90b270c8c..de7c6351e38 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -187,9 +187,6 @@ //Allow you to drag-drop disposal pipes and transit tubes into it /obj/machinery/pipedispenser/disposal/mouse_drop_receive(obj/structure/pipe, mob/user, params) - if(user.incapacitated) - return - if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod)) return diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 7be5b2352aa..a04c199c44b 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -468,9 +468,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( grant_headset_languages(mob_loc) /obj/item/radio/headset/click_alt(mob/living/user) - if(!istype(user) || !Adjacent(user) || user.incapacitated) - return CLICK_ACTION_BLOCKING - if (!command) + if(!istype(user) || !command) return CLICK_ACTION_BLOCKING use_command = !use_command to_chat(user, span_notice("You toggle high-volume mode [use_command ? "on" : "off"].")) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 2a2affef2cb..11013fe7ad5 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -274,8 +274,6 @@ . += span_notice("Ctrl-click to activate seed extraction.") /obj/item/storage/bag/plants/portaseeder/item_ctrl_click(mob/user) - if(user.incapacitated) - return for(var/obj/item/plant in contents) seedify(plant, 1) return CLICK_ACTION_SUCCESS diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 3bfac213ba5..7370c69da30 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -915,8 +915,6 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/mouse_drop_receive(atom/movable/O, mob/living/user, params) if(!istype(O) || O.anchored || istype(O, /atom/movable/screen)) return - if(!istype(user) || user.incapacitated || user.body_position == LYING_DOWN) - return if(user == O) //try to climb onto it return ..() if(!opened) From 485ef58f526799863f8138a37aca23519ab2a70e Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Mon, 16 Sep 2024 08:43:46 +0200 Subject: [PATCH 073/142] Once again re-assigns tackling to r-clicks (#86669) ## About The Pull Request This will fix #86668, caused by #86031 ## Why It's Good For The Game This will fix #86668, caused by #86031 ## Changelog :cl: fix: You once again need to right click to use tackling gloves. /:cl: --- code/datums/components/tackle.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index ebb3dafd2ff..c3b3911f858 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -71,7 +71,7 @@ /datum/component/tackler/proc/checkTackle(mob/living/carbon/user, atom/clicked_atom, list/modifiers) SIGNAL_HANDLER - if(modifiers[ALT_CLICK] || modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[MIDDLE_CLICK]) + if(!modifiers[RIGHT_CLICK] || modifiers[ALT_CLICK] || modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[MIDDLE_CLICK]) return if(!user.throw_mode || user.get_active_held_item() || user.pulling || user.buckled || user.incapacitated) From e00c4ea5328ae5cc80141bf34e4b2397f84e3ac6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 06:44:06 +0000 Subject: [PATCH 074/142] Automatic changelog for PR #86669 [ci skip] --- html/changelogs/AutoChangeLog-pr-86669.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86669.yml diff --git a/html/changelogs/AutoChangeLog-pr-86669.yml b/html/changelogs/AutoChangeLog-pr-86669.yml new file mode 100644 index 00000000000..1d0c9a9ea23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86669.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "You once again need to right click to use tackling gloves." \ No newline at end of file From 8ffff08be8ccda584f66418bbe247a28f18a7ca4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:03:34 +0000 Subject: [PATCH 075/142] Automatic changelog for PR #86682 [ci skip] --- html/changelogs/AutoChangeLog-pr-86682.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86682.yml diff --git a/html/changelogs/AutoChangeLog-pr-86682.yml b/html/changelogs/AutoChangeLog-pr-86682.yml new file mode 100644 index 00000000000..6d7c02c52c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86682.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - bugfix: "Fixes plasmamen having all external organ species preferences" \ No newline at end of file From 8cd9ed2225d061dcc6229ad03eee88d952c52f2a Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:15:17 +0000 Subject: [PATCH 076/142] Automatic changelog for PR #86678 [ci skip] --- html/changelogs/AutoChangeLog-pr-86678.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86678.yml diff --git a/html/changelogs/AutoChangeLog-pr-86678.yml b/html/changelogs/AutoChangeLog-pr-86678.yml new file mode 100644 index 00000000000..4f56b48464d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86678.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - refactor: "Refactored how examines display item properties. A lot of them are now displayed as tags that you can hover over to receive details about, like item size, resistances and materials an object is made of." + - qol: "Protection classes now better elaborate on thermal resistances of items, displaying the exact temperatures they can protect you from." \ No newline at end of file From 4d23c205d249e350a0ec2e44137550284dd5b8a9 Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Mon, 16 Sep 2024 09:15:42 -0400 Subject: [PATCH 077/142] Fixes autochangelog just dying if fed an invalid changelog entry (#86670) ## About The Pull Request Something that really has annoyed me for a while, if a user puts something invalid in their changelog body like: `tweak: something something` (a common one I encounter) then this results in the autochangelog script crashing and not creating a changelog at all. So many changelogs get dumpstered because of this and it is stupid. This PR changes it so the changelog parser is able to continue past the invalid lines and complete the action. It would be nice to have the ci bot comment on the user's pr if it detects bad input to inform them of it but that's beyond what I have the time and skills for right now. This was tested downstream and confirmed to work. ## Why It's Good For The Game
Less changelogs getting lost to the void. ![image](https://github.com/user-attachments/assets/a82e746f-d6ea-4234-af79-e432be5d21af)
## Changelog Nothing player-facing --- tools/pull_request_hooks/changelogParser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pull_request_hooks/changelogParser.js b/tools/pull_request_hooks/changelogParser.js index df4e4b2e912..3d9bfc86689 100644 --- a/tools/pull_request_hooks/changelogParser.js +++ b/tools/pull_request_hooks/changelogParser.js @@ -42,7 +42,7 @@ function parseChangelogBody(lines, openTag) { const entry = CHANGELOG_KEYS_TO_ENTRY[type]; - if (entry.placeholders.includes(description)) { + if (!entry || entry.placeholders.includes(description)) { continue; } From 58064a90c9fd876ebccdf71eaf376032b9794911 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:17:09 +0200 Subject: [PATCH 078/142] Adds a small vertical margin to ID card image in new examine panel to ensure that it doesn't collide with text (#86663) ## About The Pull Request This is how it currently looks, the distance between the card and font is minimal and highlight collides with it ![image](https://github.com/user-attachments/assets/8929b246-9712-4aed-b786-832574f07316) After adding a 6 px margin ![image](https://github.com/user-attachments/assets/1d2de75f-1994-45b0-8fee-8db2ae346a11) and without highlights ![image](https://github.com/user-attachments/assets/a36e273f-0422-4d92-b7ee-34c3558581c8) This is intentionally in px and not em to prevent the same issue from occuring with smaller font sizes ## Why It's Good For The Game Visual jank bad ## Changelog :cl: qol: Added a small vertical margin to ID card image in new examine panel to ensure that it doesn't collide with text /:cl: --- tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss | 1 + tgui/packages/tgui-panel/styles/tgchat/chat-light.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index 44899c0726d..099290b7afb 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -1111,6 +1111,7 @@ em { width: 3em; // a css guru can probably dehardcode this later height: auto; margin-right: 12px; + margin-top: 6px; } .img_by_text_container .img_text { diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index 397e9229f78..9c8c471132f 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -1031,6 +1031,7 @@ h2.alert { width: 2.5em; // a css guru can probably dehardcode this later height: auto; margin-right: 12px; + margin-top: 6px; } .img_by_text_container .img_text { From ca22b98e871167bd3153e062fca34ca52477699b Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:17:43 +0200 Subject: [PATCH 079/142] Moves walls to item_interaction (#86661) ## About The Pull Request Closes #86658 ## Changelog :cl: fix: Dismantling walls with plasma cutters works once more /:cl: --- code/game/turfs/closed/walls.dm | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 7a93549611a..611c01f3e8e 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -189,23 +189,18 @@ playsound(src, 'sound/weapons/genhit.ogg', 25, TRUE) add_fingerprint(user) -/turf/closed/wall/attackby(obj/item/W, mob/user, params) - user.changeNext_move(CLICK_CD_MELEE) +/turf/closed/wall/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if (!ISADVANCEDTOOLUSER(user)) to_chat(user, span_warning("You don't have the dexterity to do this!")) - return - - //get the user's location - if(!isturf(user.loc)) - return //can't do this stuff whilst inside objects and such + return ITEM_INTERACT_BLOCKING add_fingerprint(user) //the istype cascade has been spread among various procs for easy overriding - if(try_clean(W, user) || try_wallmount(W, user) || try_decon(W, user)) - return + if(try_clean(tool, user) || try_wallmount(tool, user) || try_decon(tool, user)) + return ITEM_INTERACT_SUCCESS - return ..() + return NONE /turf/closed/wall/proc/try_clean(obj/item/W, mob/living/user) if((user.combat_mode) || !LAZYLEN(dent_decals)) From 73507fdd3665ef5fa5b26c3cfd1446e620740ad9 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:18:09 +0200 Subject: [PATCH 080/142] The fishing line and float are now actually offset to match the fishing spot (#86659) ## About The Pull Request I've made a PR before so that beam datum (and therefore the fishing line) would take pixel_w/z into account, but what I didn't consider is that the fishing line is actually attached to the float (as it should be), so it did basically nothing on the other end of fishing lines while fishing. This PR fixes that. ## Why It's Good For The Game Fixing a small visual inconsistency. ## Changelog N/A --- code/modules/fishing/fishing_minigame.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm index 41b8009cbd6..0eb2d9846ab 100644 --- a/code/modules/fishing/fishing_minigame.dm +++ b/code/modules/fishing/fishing_minigame.dm @@ -758,8 +758,12 @@ /obj/effect/fishing_float/Initialize(mapload, atom/spot) . = ..() + if(!spot) + return if(ismovable(spot)) // we want the float and therefore the fishing line to stay connected with the fishing spot. RegisterSignal(spot, COMSIG_MOVABLE_MOVED, PROC_REF(follow_movable)) + SET_BASE_PIXEL(spot.pixel_x, spot.pixel_y) + SET_BASE_VISUAL_PIXEL(spot.pixel_w, spot.pixel_z) /obj/effect/fishing_float/proc/follow_movable(atom/movable/source) SIGNAL_HANDLER From c356a9a4a87188f0195e434d5ca713d1e56a4e46 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:19:50 +0200 Subject: [PATCH 081/142] Being abducted by a contractor no longer recursively dumps contents of all of your boxes and belts, nor does it break your UI anymore (#86657) ## About The Pull Request Contractor abductions no longer recursively dump all of your items on the ground, instead only doing a single depth loop. Also fixed storage UI getting broken after being kidnapped due to using a wrong proc ## Why It's Good For The Game There's zero reason as for why it should behave like that other than just making recovery far more annoying. ## Changelog :cl: fix: Your UI no longer breaks after being kidnapped by a contractor qol: Being kidnapped by a contractor no longer dumps all of your boxes and belts /:cl: --- .../traitor/contractor/syndicate_contract.dm | 7 +++++-- .../antagonists/traitor/objectives/kidnapping.dm | 5 +++-- code/modules/mob/inventory.dm | 10 +++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/code/modules/antagonists/traitor/contractor/syndicate_contract.dm b/code/modules/antagonists/traitor/contractor/syndicate_contract.dm index 876aea675de..3c9b8c45b24 100644 --- a/code/modules/antagonists/traitor/contractor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/contractor/syndicate_contract.dm @@ -109,14 +109,17 @@ if(opfor_data.contractor_hub.current_contract == src) // NOVA EDIT CHANGE - ORIGINAL: if(traitor_data.uplink_handler.contractor_hub.current_contract == src) opfor_data.contractor_hub.current_contract = null // NOVA EDIT CHANGE - ORIGINAL: traitor_data.uplink_handler.contractor_hub.current_contract = null - for(var/obj/item/person_contents as anything in person_sent.gather_belongings()) + for(var/obj/item/person_contents as anything in person_sent.gather_belongings(FALSE, FALSE)) if(ishuman(person_sent)) var/mob/living/carbon/human/human_sent = person_sent if(person_contents == human_sent.w_uniform) continue //So all they're left with are shoes and uniform. if(person_contents == human_sent.shoes) continue - person_sent.transferItemToLoc(person_contents) + var/unequipped = person_sent.temporarilyRemoveItemFromInventory(person_contents) + if (!unequipped) + continue + person_contents.moveToNullspace() victim_belongings.Add(WEAKREF(person_contents)) var/obj/structure/closet/supplypod/extractionpod/pod = source diff --git a/code/modules/antagonists/traitor/objectives/kidnapping.dm b/code/modules/antagonists/traitor/objectives/kidnapping.dm index ea7fef9b4b6..0d4ff5cfd99 100644 --- a/code/modules/antagonists/traitor/objectives/kidnapping.dm +++ b/code/modules/antagonists/traitor/objectives/kidnapping.dm @@ -228,13 +228,14 @@ var/mob/living/carbon/human/sent_mob = entered_atom - for(var/obj/item/belonging in sent_mob.gather_belongings()) + for(var/obj/item/belonging in sent_mob.gather_belongings(FALSE, FALSE)) if(belonging == sent_mob.get_item_by_slot(ITEM_SLOT_ICLOTHING) || belonging == sent_mob.get_item_by_slot(ITEM_SLOT_FEET)) continue - var/unequipped = sent_mob.transferItemToLoc(belonging) + var/unequipped = sent_mob.temporarilyRemoveItemFromInventory(belonging) if (!unequipped) continue + belonging.moveToNullspace() target_belongings.Add(WEAKREF(belonging)) var/datum/market_item/hostage/market_item = sent_mob.process_capture(rand(1000, 3000)) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 1cedbfd64be..aa023274611 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -590,19 +590,19 @@ hud_used.build_hand_slots() //GetAllContents that is reasonable and not stupid -/mob/living/proc/get_all_gear() - var/list/processing_list = get_equipped_items(INCLUDE_POCKETS | INCLUDE_ACCESSORIES | INCLUDE_HELD) +/mob/living/proc/get_all_gear(accessories = TRUE, recursive = TRUE) + var/list/processing_list = get_equipped_items(INCLUDE_POCKETS | INCLUDE_HELD | (accessories ? INCLUDE_ACCESSORIES : NONE)) list_clear_nulls(processing_list) // handles empty hands var/i = 0 while(i < length(processing_list)) var/atom/A = processing_list[++i] - if(A.atom_storage) + if(A.atom_storage && recursive) processing_list += A.atom_storage.return_inv() return processing_list /// Returns a list of things that the provided mob has, including any storage-capable implants. -/mob/living/proc/gather_belongings() - var/list/belongings = get_all_gear() +/mob/living/proc/gather_belongings(accessories = TRUE, recursive = TRUE) + var/list/belongings = get_all_gear(accessories, recursive) for (var/obj/item/implant/storage/internal_bag in implants) belongings += internal_bag.contents return belongings From 6c58bc33933e6c86fbb5e9a9d0cf9e0861462870 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:20:40 +0200 Subject: [PATCH 082/142] Lesser gorillas (And gutlunchers' grubs) now use the `current_size` variable instead of directly scaling the transform matrix (#86656) ## About The Pull Request Yeah, as I suspected, lab gorillas from the Self-Gorillafication Nerf weren't the only mobs to be resized without the `current_size` var or the `update_transform` proc. The other one that does this (at least on init) is, drum roll, yet another gorilla subtype. Wow, the apple doesn't fall far from the tree. EDIT: I was wrong... there's another mob who does this too. ## Why It's Good For The Game For those of you who care but don't know what the difference is: the transform matrix of an object works around the center of the icon, which means that if you multiply the transform matrix a 32x32 icon by 0.5, the icon will then appear roughly 8 px above the lower edge of the turf. For most objects, we don't care about it, but for mobs, this is a small visual issue because the lower end of the icon should be aligned with the floor (or the shadow in the case of the wallening for non-floating mobs). This where the `update_transform` comes handy, since it offsets the icon by that amount to compensate for the scaled transform matrix. Alas, the transform matrix is used for a lot of things and it's perhaps impossible to have the CI look into it. ## Changelog It's a very subtle nit, people won't notice. --- .../modules/mob/living/basic/farm_animals/gorilla/gorilla.dm | 5 +---- .../mob/living/basic/lavaland/gutlunchers/gutlunchers.dm | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 3a70afd7b62..fcb61892e57 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -146,10 +146,7 @@ obj_damage = 15 ai_controller = /datum/ai_controller/basic_controller/gorilla/lesser butcher_results = list(/obj/item/food/meat/slab/gorilla = 2) - -/mob/living/basic/gorilla/lesser/Initialize(mapload) - . = ..() - transform *= 0.75 + current_size = 0.75 /// Cargo's wonderful mascot, the tranquil box-carrying ape /mob/living/basic/gorilla/cargorilla diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm index f9e1d458ef2..6b822d490de 100644 --- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm +++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm @@ -139,12 +139,12 @@ can_breed = FALSE gender = NEUTER ai_controller = /datum/ai_controller/basic_controller/gutlunch/gutlunch_baby + current_size = 0.6 ///list of stats we inherited var/datum/gutlunch_inherited_stats/inherited_stats /mob/living/basic/mining/gutlunch/grub/Initialize(mapload) . = ..() - transform = transform.Scale(0.6, 0.6) AddComponent(\ /datum/component/growth_and_differentiation,\ growth_time = 3 MINUTES,\ From 014241bee056ead329138bca44331f83ed511933 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:21:46 +0000 Subject: [PATCH 083/142] Automatic changelog for PR #86663 [ci skip] --- html/changelogs/AutoChangeLog-pr-86663.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86663.yml diff --git a/html/changelogs/AutoChangeLog-pr-86663.yml b/html/changelogs/AutoChangeLog-pr-86663.yml new file mode 100644 index 00000000000..b069bf63a23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86663.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - qol: "Added a small vertical margin to ID card image in new examine panel to ensure that it doesn't collide with text" \ No newline at end of file From 967ede588f07943824df9ddbc7979debdd742303 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:23:07 +0000 Subject: [PATCH 084/142] Automatic changelog for PR #86661 [ci skip] --- html/changelogs/AutoChangeLog-pr-86661.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86661.yml diff --git a/html/changelogs/AutoChangeLog-pr-86661.yml b/html/changelogs/AutoChangeLog-pr-86661.yml new file mode 100644 index 00000000000..e04429018f6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86661.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Dismantling walls with plasma cutters works once more" \ No newline at end of file From d651d0a980ae5daf6d60220596b7798e83e1edbc Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:23:47 +0000 Subject: [PATCH 085/142] Automatic changelog for PR #86657 [ci skip] --- html/changelogs/AutoChangeLog-pr-86657.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86657.yml diff --git a/html/changelogs/AutoChangeLog-pr-86657.yml b/html/changelogs/AutoChangeLog-pr-86657.yml new file mode 100644 index 00000000000..8a886126f0f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86657.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Your UI no longer breaks after being kidnapped by a contractor" + - qol: "Being kidnapped by a contractor no longer dumps all of your boxes and belts" \ No newline at end of file From b360d2afdccdf75006eaa8d7dddcaf1b53e3092b Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:28:25 +0200 Subject: [PATCH 086/142] Adds IGNORE_DENSITY flag to windoors and railings to allow crafting on their tile (#86651) ## About The Pull Request I am bored enough to the point where I'm diving into downstream github issues. Thindows have IGNORE_DENSITY but windoors and railings do not, preventing crafting on their tiles. This ***should not*** cause any side effects as I went through all the recipes and they still have BLOCKS_CONSTRUCTION_DIR which should block duplicates or windows from being constructed on the same tile, but ideally this needs another pair of eyes. ## Why It's Good For The Game Windoors/railings should not be preventing you from crafting sprears and boxes on their tiles. Also parity with thindows. ## Changelog :cl: fix: You can now craft things on tiles with windoors and railings on them. /:cl: --- code/game/machinery/doors/windowdoor.dm | 2 +- code/game/objects/structures/railings.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 0c897c68096..a287aefeaa8 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -6,7 +6,7 @@ layer = ABOVE_WINDOW_LAYER closingLayer = ABOVE_WINDOW_LAYER resistance_flags = ACID_PROOF - obj_flags = CAN_BE_HIT | BLOCKS_CONSTRUCTION_DIR + obj_flags = CAN_BE_HIT | IGNORE_DENSITY | BLOCKS_CONSTRUCTION_DIR var/base_state = "left" max_integrity = 150 //If you change this, consider changing ../door/window/brigdoor/ max_integrity at the bottom of this .dm file integrity_failure = 0 diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 06a099ad4f9..fe2e4b06b4f 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/railings.dmi' icon_state = "railing" flags_1 = ON_BORDER_1 - obj_flags = CAN_BE_HIT | BLOCKS_CONSTRUCTION_DIR + obj_flags = CAN_BE_HIT | BLOCKS_CONSTRUCTION_DIR | IGNORE_DENSITY density = TRUE anchored = TRUE pass_flags_self = LETPASSTHROW|PASSSTRUCTURE From 049331e30ccb0a2b0c43f79cbf19ace97c501ee4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:29:33 +0000 Subject: [PATCH 087/142] Automatic changelog for PR #86651 [ci skip] --- html/changelogs/AutoChangeLog-pr-86651.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86651.yml diff --git a/html/changelogs/AutoChangeLog-pr-86651.yml b/html/changelogs/AutoChangeLog-pr-86651.yml new file mode 100644 index 00000000000..e109e82a6a3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86651.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "You can now craft things on tiles with windoors and railings on them." \ No newline at end of file From 4801376152d24921f65563d58ca30dd4d46bd258 Mon Sep 17 00:00:00 2001 From: MelokGleb <99420088+MelokGleb@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:19:51 +0300 Subject: [PATCH 088/142] Big B (#86684) ## About The Pull Request makes "busser" id trim "Busser" ## Why It's Good For The Game other job's the first letter is capital ## Changelog :cl: spellcheck: busser is now Busser (with big B) /:cl: --- code/datums/id_trim/jobs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index c7514b86a1b..0bb7dabe262 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -157,7 +157,7 @@ job = /datum/job/bartender /datum/id_trim/job/pun_pun - assignment = "busser" + assignment = "Busser" trim_state = "trim_busser" department_color = COLOR_SERVICE_LIME subdepartment_color = COLOR_SERVICE_LIME From 8a809a1279d3db36143309f2eb53a34b5256d046 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:20:18 +0000 Subject: [PATCH 089/142] Automatic changelog for PR #86684 [ci skip] --- html/changelogs/AutoChangeLog-pr-86684.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86684.yml diff --git a/html/changelogs/AutoChangeLog-pr-86684.yml b/html/changelogs/AutoChangeLog-pr-86684.yml new file mode 100644 index 00000000000..166438c5c2a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86684.yml @@ -0,0 +1,4 @@ +author: "MelokGleb" +delete-after: True +changes: + - spellcheck: "busser is now Busser (with big B)" \ No newline at end of file From 6c7276746400f0ea66e5dfc79627477df0992a56 Mon Sep 17 00:00:00 2001 From: PowerfulBacon <26465327+PowerfulBacon@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:16:25 +0100 Subject: [PATCH 090/142] Adds 'required_neighbors' to maplint and conditional lints (#86640) ## About The Pull Request Allows us to test for atoms that are required to be placed alongside another atom, such as APCs to cables. There are many situations where a structure spawner is not good enough: - APC cables need to be in any colour or any direction - Airlock mapping helpers may be any access to any airlock and would create too many subtypes. ## Why It's Good For The Game This allows us to have more comprehensive linting added to future mapping changes. This is needed to support the following lints: - Airlocks should not have an access helper if they have access requirement variables set. - Access requirement helpers MUST have an airlock placed on their tile. Needed to satisfy the following review: https://github.com/BeeStation/BeeStation-Hornet/pull/11469#discussion_r1757608360 ## Testing Photographs and Procedure ### Test required neighbors ![image](https://github.com/user-attachments/assets/ea79aa85-048f-40ca-b27b-2a1da0e1ba2e) ### Conditional Rulesets (I know this rule is useless since it mimics banned_variables, but we can make more complex rules with the other ones and with banned_neighbors) ![image](https://github.com/user-attachments/assets/a607a4cd-0e97-4557-8129-7cf5875a2ebd) ![image](https://github.com/user-attachments/assets/81e43bb6-acc8-441f-97a3-936f5bc88203) Test a more complex query with set operations: ![image](https://github.com/user-attachments/assets/2d309060-8360-4b55-a4d2-2a5d11d7bad5) ![image](https://github.com/user-attachments/assets/33b30d70-3971-40d8-97d5-2f610d73cf86) ![image](https://github.com/user-attachments/assets/50e564eb-9b82-413f-99c3-4655e6c23c75) Super complex query: ![image](https://github.com/user-attachments/assets/0d12c56f-6ff5-4663-bd5b-738c12c3f085) ![image](https://github.com/user-attachments/assets/a46afaa8-4385-4017-a452-a3a624d968c4) ![image](https://github.com/user-attachments/assets/7a6f5fe5-9a0c-4f55-afc9-2fb1777c8a7d) Test like: ![image](https://github.com/user-attachments/assets/2f0187e2-c7f1-4631-8f40-c8d8ae68942b) ![image](https://github.com/user-attachments/assets/1d63faf1-934f-4d6d-8091-f484fcd44c7a) ![image](https://github.com/user-attachments/assets/86dd3593-a3de-47bf-8061-ff206366d387) Not set: ![image](https://github.com/user-attachments/assets/2ae61dfe-4214-42a5-96a9-37ae5e91e6b0) Test is: ![image](https://github.com/user-attachments/assets/ace87258-f9cd-4898-86ba-1cf86bf52a3a) ![image](https://github.com/user-attachments/assets/067acb26-1bf7-4038-9d2f-3e304810fadd) ## Changelog :cl: add: Implements the ability to lint for required neighbors in maplint. add: Adds conditional linting rules in maplint, allowing a lint to apply only if certain conditions are met (Variable is/isn't set, Variable is/isn't a value, Variable matches a regex). /:cl: --- tools/maplint/README.md | 54 +++++++++ tools/maplint/source/common.py | 6 +- tools/maplint/source/lint.py | 193 +++++++++++++++++++++++++++++++-- 3 files changed, 243 insertions(+), 10 deletions(-) diff --git a/tools/maplint/README.md b/tools/maplint/README.md index 82ee0bd0ced..7f9930231a7 100644 --- a/tools/maplint/README.md +++ b/tools/maplint/README.md @@ -130,3 +130,57 @@ help: Pugs haven't existed on Sol since 2450. /mob/dog/pug: banned: true ``` + +### `when` - Conditional Rules + +Sometimes it may be necessary for a rule to be given conditions which have to be met before it needs to be applied. All children of the when node must be satisfied for the rule to execute. + +If we wanted to create a rule which disallows the placement of access helpers when an airlock's access has been manually set via a variable edit, then we could make the following rule: + +```yml +/obj/machinery/door/airlock: + when: + - req_access_txt is set + banned_neighbors: + - /obj/effect/mapping_helper/airlock/access +``` + +The following conditions are valid: +- **{var_name} is set**: The variable named *var_name* has been modified. +- **{var_name} is not set**: The variable named *var_name* has not been modified. +- **{var_name} is '{value}'**: The variable named *var_name* has a specific value. +- **{var_name} is not '{value}'**: The variable named *var_name* does not have a specific value. +- **{var_name} like '{regex}'**: The variable named *var_name* matches the provided regex. + +#### `any` + +The any node may be added as a child to the when node to specify that it will be satisfied if any of its child conditions are met. + +```yml +/mob/dog: + # Rule only applies when the dog is any of the following breeds + when: + - any: + - breed is 'labrador' + - breed is 'pug' + - breed is 'corgi' + # These breeds of dogs must have a dogbed + required_neighbors: + - /obj/dogbed +``` + +#### `all` + +The all node may be added as a child to the when node to specify that it will be satisfied only when all of its child conditions are met. Note that the `all` node only makes sense to use when the parent node is an `any` node, as the default behaviour of `when` is to require all conditions to be met. + +```yml +/mob/dog: + # Rule only applies if the dog breed is capitalised and has an owner + when: + - all: + - breed like '[A-Z][a-z]*' + - owner is set + # These dogs must have a dogbed for their owner + required_neighbors: + - /obj/dogbed +``` diff --git a/tools/maplint/source/common.py b/tools/maplint/source/common.py index 6fc0080009a..44f0abaf011 100644 --- a/tools/maplint/source/common.py +++ b/tools/maplint/source/common.py @@ -29,8 +29,12 @@ def __str__(self) -> str: class Filename: path: str + def __str__(self) -> str: + return self.path + @dataclass class Null: - pass + def __str__(self) -> str: + return "null" Constant = str | float | Filename | Typepath | Null | list['Constant'] | dict['Constant', 'Constant'] diff --git a/tools/maplint/source/lint.py b/tools/maplint/source/lint.py index ee86d29be52..0847b10ed71 100644 --- a/tools/maplint/source/lint.py +++ b/tools/maplint/source/lint.py @@ -1,5 +1,5 @@ import re -from typing import Optional +from typing import Optional, Union from .common import Constant, Typepath from .dmm import DMM, Content @@ -41,7 +41,7 @@ def matches_path(self, path: Typepath): return self.typepath.segments == path.segments[:len(self.typepath.segments)] -class BannedNeighbor: +class AtomNeighbor: identical: bool = False typepath: Optional[TypepathExtra] = None pattern: Optional[re.Pattern] = None @@ -84,6 +84,12 @@ def matches(self, identified: Content, neighbor: Content): return False + def to_string(self) -> str: + if (self.typepath is not None): + return self.typepath.typepath.path + elif (self.pattern is not None): + return self.pattern.pattern + Choices = list[Constant] | re.Pattern def extract_choices(data, key) -> Optional[Choices]: @@ -153,10 +159,151 @@ def run(self, identified: Content) -> str: return f"This variable is not allowed for this type." +# Base class for conditional rules +class ConditionalRule: + def is_met(self, identified: Content) -> bool: + raise NotImplementedError("This method should be implemented by subclasses.") + + def match_string(self, parent_intersection: bool) -> str: + raise NotImplementedError("This method should be implemented by subclasses") + +# A single conditional expression +class WhenCondition(ConditionalRule): + condition: str + match_set: Optional[re.Match[str]] + match_not_set: Optional[re.Match[str]] + match_equal: Optional[re.Match[str]] + match_not_equal: Optional[re.Match[str]] + match_like: Optional[re.Match[str]] + + def __init__(self, condition: str): + self.condition = condition + self.match_set = re.match("(.+) is set", condition) + self.match_not_set = re.match("(.+) is not set", condition) + self.match_equal = re.match("(.+) is '(.+)'", condition) + self.match_not_equal = re.match("(.+) is not '(.+)'", condition) + self.match_like = re.match("(.+) like '(.+)'", condition) + matches = 0 + if self.match_set is not None: + matches = matches + 1 + if self.match_not_set is not None: + matches = matches + 1 + if self.match_equal is not None: + matches = matches + 1 + if self.match_not_equal is not None: + matches = matches + 1 + if self.match_like is not None: + matches = matches + 1 + if (matches != 1): + raise RuntimeError(f"Conditional rule must be either is set, is not set, is 'value', is not 'value', or like 'regex'. Instead found: {condition}") + + def is_met(self, identified: Content) -> bool: + var_edits = identified.var_edits + + if self.match_set is not None: + var_name = self.match_set.group(1) + return var_name in var_edits + + elif self.match_not_set is not None: + var_name = self.match_not_set.group(1) + return var_name not in var_edits + + elif self.match_equal is not None: + var_name = self.match_equal.group(1) + expected_value = self.match_equal.group(2) + if var_name not in var_edits: + return False + if (isinstance(var_edits[var_name], float)): + # If something is a float (number), check it as an int and a float + # Hack for integer value parsing + if var_edits[var_name] % 1 == 0: + return str(int(var_edits[var_name])).strip() == expected_value.strip() + return str(var_edits[var_name]).strip() == expected_value.strip() + + elif self.match_not_equal is not None: + var_name = self.match_not_equal.group(1) + unexpected_value = self.match_not_equal.group(2) + if var_name not in var_edits: + return True + if (isinstance(var_edits[var_name], float)): + # If something is a float (number), check it as an int and a float + # Hack for integer value parsing + if var_edits[var_name] % 1 == 0: + return str(int(var_edits[var_name])).strip() != expected_value.strip() + return str(var_edits[var_name]).strip() != expected_value.strip() + + elif self.match_like is not None: + var_name = self.match_like.group(1) + pattern = self.match_like.group(2) + return (var_name in var_edits) and re.match(pattern, str(var_edits[var_name])) + + return False + + def match_string(self, parent_intersection: bool) -> str: + return self.condition + +# A conditional group (Joining with AND and OR) +class WhenGroup(ConditionalRule): + conditions: list[ConditionalRule] + all_group: bool + + def __init__(self, conditions: list[Union[dict, str]], all_group: bool = True): + self.conditions = [self.parse_condition(condition) for condition in conditions] + self.all_group = all_group + + def parse_condition(self, condition: Union[dict, str]) -> ConditionalRule: + if isinstance(condition, dict): + if "all" in condition: + return WhenGroup(condition["all"], all_group=True) + elif "any" in condition: + return WhenGroup(condition["any"], all_group=False) + else: + raise RuntimeError(f"Unknown conditional group in when clause: {list(condition.keys())[0]}") + elif isinstance(condition, str): + return WhenCondition(condition) + else: + raise RuntimeError(f"Invalid condition type: {type(condition)}") + + def is_met(self, identified: Content) -> bool: + if self.all_group: + # For `all` group, all conditions must be met + return all(condition.is_met(identified) for condition in self.conditions) + else: + # For `any` group, only one condition must be met + return any(condition.is_met(identified) for condition in self.conditions) + + # Add parenthesis where required + def match_string(self, parent_intersection: bool) -> str: + match_symbol = " and " if self.all_group else " or " + match_text = match_symbol.join(condition.match_string(self.all_group) for condition in self.conditions); + if (self.all_group == False and parent_intersection == True and len(self.conditions) > 1): + return f"({match_text})" + else: + return match_text + +class When: + root_group: WhenGroup + + def __init__(self, conditions: list[Union[dict, str]]): + expect(isinstance(conditions, list), "when must be a list of conditions.") + # Default to 'all' group if there are multiple conditions with no explicit 'any' or 'all' + if len(conditions) > 1 and not any(isinstance(cond, dict) for cond in conditions): + self.root_group = WhenGroup(conditions, all_group=True) + else: + self.root_group = WhenGroup(conditions) + + def evaluate(self, identified: Content) -> bool: + return self.root_group.is_met(identified) + + def match_string(self) -> str: + return f" when {self.root_group.match_string(True)}"; + class Rules: banned: bool = False - banned_neighbors: list[BannedNeighbor] = [] + banned_neighbors: list[AtomNeighbor] = [] banned_variables: bool | list[BannedVariable] = [] + required_neighbors: list[AtomNeighbor] = [] + when: Optional[When] = None def __init__(self, data): expect(isinstance(data, dict), "Lint rules must be a dictionary.") @@ -171,9 +318,19 @@ def __init__(self, data): expect(isinstance(banned_neighbors_data, list) or isinstance(banned_neighbors_data, dict), "banned_neighbors must be a list, or a dictionary keyed by type.") if isinstance(banned_neighbors_data, dict): - self.banned_neighbors = [BannedNeighbor(typepath, data) for typepath, data in banned_neighbors_data.items()] + self.banned_neighbors = [AtomNeighbor(typepath, data) for typepath, data in banned_neighbors_data.items()] + else: + self.banned_neighbors = [AtomNeighbor(typepath) for typepath in banned_neighbors_data] + + if "required_neighbors" in data: + required_neighbors_data = data.pop("required_neighbors") + + expect(isinstance(required_neighbors_data, list) or isinstance(required_neighbors_data, dict), "required_neighbors must be a list, or a dictionary keyed by type.") + + if isinstance(required_neighbors_data, dict): + self.required_neighbors = [AtomNeighbor(typepath, data) for typepath, data in required_neighbors_data.items()] else: - self.banned_neighbors = [BannedNeighbor(typepath) for typepath in banned_neighbors_data] + self.required_neighbors = [AtomNeighbor(typepath) for typepath in required_neighbors_data] if "banned_variables" in data: banned_variables_data = data.pop("banned_variables") @@ -187,24 +344,41 @@ def __init__(self, data): else: self.banned_variables = [BannedVariable(variable) for variable in banned_variables_data] + if "when" in data: + self.when = When(data.pop("when")) + expect(len(data) == 0, f"Unknown lint rules: {', '.join(data.keys())}.") def run(self, identified: Content, contents: list[Content], identified_index) -> list[MaplintError]: failures: list[MaplintError] = [] + when_text = self.when.match_string() if self.when is not None else "" + + # If a when is present and is unmet, skip evaluation of this rule + if self.when and not self.when.evaluate(identified): + return failures if self.banned: - failures.append(fail_content(identified, f"Typepath {identified.path} is banned.")) + failures.append(fail_content(identified, f"Typepath {identified.path} is banned{when_text}.")) for banned_neighbor in self.banned_neighbors: for neighbor in contents[:identified_index] + contents[identified_index + 1:]: if not banned_neighbor.matches(identified, neighbor): continue - failures.append(fail_content(identified, f"Typepath {identified.path} has a banned neighbor: {neighbor.path}")) + failures.append(fail_content(identified, f"Typepath {identified.path} has a banned neighbor{when_text}: {neighbor.path}")) + + for required_neighbor in self.required_neighbors: + found = False + for neighbor in contents[:identified_index] + contents[identified_index + 1:]: + if required_neighbor.matches(identified, neighbor): + found = True + break + if found == False: + failures.append(fail_content(identified, f"Typepath {identified.path} is missing a required neighbor{when_text}: {required_neighbor.to_string()}")) if self.banned_variables == True: if len(identified.var_edits) > 0: - failures.append(fail_content(identified, f"Typepath {identified.path} should not have any variable edits.")) + failures.append(fail_content(identified, f"Typepath {identified.path} should not have any variable edits{when_text}.")) else: assert isinstance(self.banned_variables, list) for banned_variable in self.banned_variables: @@ -212,13 +386,14 @@ def run(self, identified: Content, contents: list[Content], identified_index) -> ban_reason = banned_variable.run(identified) if ban_reason is None: continue - failures.append(fail_content(identified, f"Typepath {identified.path} has a banned variable (set to {identified.var_edits[banned_variable.variable]}): {banned_variable.variable}. {ban_reason}")) + failures.append(fail_content(identified, f"Typepath {identified.path} has a banned variable (set to {identified.var_edits[banned_variable.variable]}){when_text}: {banned_variable.variable}. {ban_reason}")) return failures class Lint: help: Optional[str] = None rules: dict[TypepathExtra, Rules] + disabled: bool = False def __init__(self, data): expect(isinstance(data, dict), "Lint must be a dictionary.") From d460b84acbc9fcf502419135dc673eaf11efbd15 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:16:49 +0000 Subject: [PATCH 091/142] Automatic changelog for PR #86640 [ci skip] --- html/changelogs/AutoChangeLog-pr-86640.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86640.yml diff --git a/html/changelogs/AutoChangeLog-pr-86640.yml b/html/changelogs/AutoChangeLog-pr-86640.yml new file mode 100644 index 00000000000..5c82f92523b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86640.yml @@ -0,0 +1,5 @@ +author: "PowerfulBacon" +delete-after: True +changes: + - rscadd: "Implements the ability to lint for required neighbors in maplint." + - rscadd: "Adds conditional linting rules in maplint, allowing a lint to apply only if certain conditions are met (Variable is/isn't set, Variable is/isn't a value, Variable matches a regex)." \ No newline at end of file From 124151ec5ab08da2676bd1bfb925aa8aae2e84f1 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:53:01 -0500 Subject: [PATCH 092/142] Adds #error to compiling on 515.1643 (#86713) ## About The Pull Request ![image](https://github.com/user-attachments/assets/caf328dd-c52e-4923-8751-ca3085fa09b0) --- code/__byond_version_compat.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/__byond_version_compat.dm b/code/__byond_version_compat.dm index 0f19332934d..6680e655551 100644 --- a/code/__byond_version_compat.dm +++ b/code/__byond_version_compat.dm @@ -9,6 +9,11 @@ #error You need version 515.1627 or higher #endif +// Unable to compile this version thanks to mutable appearance changes +#if (DM_VERSION == 515 && DM_BUILD == 1643) +#error This version of BYOND cannot compile this project. Visit www.byond.com/download/build to download an older version or update (if possible). +#endif + // Keep savefile compatibilty at minimum supported level /savefile/byond_version = MIN_COMPILER_VERSION From 5d1e1e0cfe159d9462fa72b44d3891d91f1d3576 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Mon, 16 Sep 2024 18:55:56 -0700 Subject: [PATCH 093/142] Remove the default max length from tgui_input_text. (#86692) this should mirror `input() as text`, and `input() as text` has no default max length. Anything that needs a limited input must specifically request it to avoid collateral damage for inputs that don't need it (like admin verbs) --- code/modules/tgui_input/text.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/tgui_input/text.dm b/code/modules/tgui_input/text.dm index ec94fbd6766..2476ec16342 100644 --- a/code/modules/tgui_input/text.dm +++ b/code/modules/tgui_input/text.dm @@ -15,7 +15,7 @@ * * encode - Toggling this determines if input is filtered via html_encode. Setting this to FALSE gives raw input. * * timeout - The timeout of the textbox, after which the modal will close and qdel itself. Set to zero for no timeout. */ -/proc/tgui_input_text(mob/user, message = "", title = "Text Input", default, max_length = MAX_MESSAGE_LEN, multiline = FALSE, encode = TRUE, timeout = 0, ui_state = GLOB.always_state) +/proc/tgui_input_text(mob/user, message = "", title = "Text Input", default, max_length = INFINITY, multiline = FALSE, encode = TRUE, timeout = 0, ui_state = GLOB.always_state) if (!user) user = usr if (!istype(user)) From 5b6813358d9aa13aef32fd3bd6671fe26768be40 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 17 Sep 2024 03:58:18 +0200 Subject: [PATCH 094/142] Fixes veteran advisor not spawning on security officer landmarks (#86683) ## About The Pull Request Potato found it in discord, landmarks aren't an assoc list and we already have a proc for finding spawnpoints. ## Changelog :cl: fix: Fixed veteran advisor not spawning on security officer landmarks /:cl: --- .../job_types/station_trait/veteran_advisor.dm | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/code/modules/jobs/job_types/station_trait/veteran_advisor.dm b/code/modules/jobs/job_types/station_trait/veteran_advisor.dm index 6fcb8d94707..f8a0f2f801d 100644 --- a/code/modules/jobs/job_types/station_trait/veteran_advisor.dm +++ b/code/modules/jobs/job_types/station_trait/veteran_advisor.dm @@ -37,10 +37,19 @@ allow_bureaucratic_error = FALSE job_flags = STATION_JOB_FLAGS | STATION_TRAIT_JOB_FLAGS -/datum/job/veteran_advisor/get_roundstart_spawn_point() //Spawning at Brig where Officers spawn - if (length(GLOB.start_landmarks_list["Security Officer"])) - return pick(GLOB.start_landmarks_list["Security Officer"]) - return ..() +/datum/job/veteran_advisor/get_default_roundstart_spawn_point() + for(var/obj/effect/landmark/start/spawn_point as anything in GLOB.start_landmarks_list) + if(spawn_point.name != "Security Officer") + continue + . = spawn_point + if(spawn_point.used) //so we can revert to spawning them on top of eachother if something goes wrong + continue + spawn_point.used = TRUE + break + if(!.) // Try to fall back to "our" landmark + . = ..() + if(!.) + log_mapping("Job [title] ([type]) couldn't find a round start spawn point.") /datum/job/veteran_advisor/after_spawn(mob/living/spawned, client/player_client) . = ..() From d23fa4a32b9298066e26ef8032bd7ecd55633736 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 01:58:56 +0000 Subject: [PATCH 095/142] Automatic changelog for PR #86683 [ci skip] --- html/changelogs/AutoChangeLog-pr-86683.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86683.yml diff --git a/html/changelogs/AutoChangeLog-pr-86683.yml b/html/changelogs/AutoChangeLog-pr-86683.yml new file mode 100644 index 00000000000..9c09db4a6d8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86683.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed veteran advisor not spawning on security officer landmarks" \ No newline at end of file From d73bf64574fe4a929e292eca83accf95fef0c331 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Tue, 17 Sep 2024 04:10:14 +0200 Subject: [PATCH 096/142] Squashs four fish boolean vars into a bitfield (plus VV support) (#86623) ## About The Pull Request this is a very marginal code improvement to fish. One bitfield is better than a bunch of booleans, and it lets me add more TRUE/FALSE settings in the future without having to make new vars for it. Also VV support for several vars (fish_traits will have to wait), if me or someone else wants to var-edit fish for testing purposes or whatsnot. ## Why It's Good For The Game Slight code improvement and var-edititing support. ## Changelog N/A --- code/__DEFINES/fish.dm | 11 ++ code/_globalvars/bitfields.dm | 7 ++ code/modules/autowiki/pages/fishing.dm | 6 +- .../experiment/types/scanning_fish.dm | 2 +- code/modules/fishing/bait.dm | 2 +- code/modules/fishing/fish/_fish.dm | 119 +++++++++++++----- code/modules/fishing/fish/types/freshwater.dm | 4 +- .../modules/fishing/fish/types/holographic.dm | 3 +- code/modules/fishing/fish/types/ruins.dm | 6 +- code/modules/fishing/fish/types/station.dm | 2 +- code/modules/fishing/fish_catalog.dm | 2 +- code/modules/fishing/sources/_fish_source.dm | 6 +- code/modules/unit_tests/fish_unit_tests.dm | 27 +++- 13 files changed, 144 insertions(+), 53 deletions(-) diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index 7f8e8462a98..43e0e8587f9 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -151,6 +151,17 @@ ///The last feeding timestamp of newly instantiated fish is multiplied by this: ergo, they spawn 50% hungry. #define NEW_FISH_LAST_FEEDING_MULT 0.5 +//IF YOU ADD ANY NEW FLAG, ADD IT TO THE RESPECTIVE BITFIELD in _globalvars/bitfields.dm TOO! + +///This fish is shown in the catalog and on the wiki (this only matters as an initial, compile-time value) +#define FISH_FLAG_SHOW_IN_CATALOG (1<<0) +///This fish has a flopping animation done through matrices +#define FISH_DO_FLOP_ANIM (1<<1) +///This fish has been petted in the last 30 seconds +#define FISH_FLAG_PETTED (1<<2) +///This fish can be scanned to complete fish scanning experiments +#define FISH_FLAG_EXPERIMENT_SCANNABLE (1<<3) + #define MIN_AQUARIUM_TEMP T0C #define MAX_AQUARIUM_TEMP (T0C + 100) #define DEFAULT_AQUARIUM_TEMP (T0C + 24) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 3fcc9e1cedc..a7de6be2fc2 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -586,6 +586,13 @@ DEFINE_BITFIELD(gun_flags, list( "TURRET_INCOMPATIBLE" = TURRET_INCOMPATIBLE, )) +DEFINE_BITFIELD(fish_flags, list( + "FISH_FLAG_SHOW_IN_CATALOG" = FISH_FLAG_SHOW_IN_CATALOG, + "FISH_DO_FLOP_ANIM" = FISH_DO_FLOP_ANIM, + "FISH_FLAG_PETTED" = FISH_FLAG_PETTED, + "FISH_FLAG_EXPERIMENT_SCANNABLE" = FISH_FLAG_EXPERIMENT_SCANNABLE, +)) + DEFINE_BITFIELD(bot_mode_flags, list( "POWER_ON" = BOT_MODE_ON, "AUTO_PATROL" = BOT_MODE_AUTOPATROL, diff --git a/code/modules/autowiki/pages/fishing.dm b/code/modules/autowiki/pages/fishing.dm index 1267547c85c..b71b8dab330 100644 --- a/code/modules/autowiki/pages/fishing.dm +++ b/code/modules/autowiki/pages/fishing.dm @@ -23,7 +23,7 @@ upload_icon(icon(fish:icon, fish::icon_state, frame = 1), filename) generated_icons[filename] = TRUE - if(!fish::show_in_catalog) + if(!(fish::fish_flags & FISH_FLAG_SHOW_IN_CATALOG)) continue var/list/properties = SSfishing.fish_properties[fish] @@ -402,7 +402,7 @@ var/output = "" for(var/obj/item/fish/fish as anything in GLOB.fishes_by_fish_evolution[evo_type]) - if(!initial(fish.show_in_catalog)) + if(!(initial(fish.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG)) continue output += include_template("Autowiki/FishEvolutionCandidate", list( "name" = escape_value(full_capitalize(initial(fish.name))), @@ -435,7 +435,7 @@ var/output = "" for(var/obj/item/fish/fish as anything in catchables) - if(!initial(fish.show_in_catalog)) + if(!(initial(fish.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG)) continue output += include_template("Autowiki/FishLureCatchables", list( "name" = escape_value(full_capitalize(initial(fish.name))), diff --git a/code/modules/experisci/experiment/types/scanning_fish.dm b/code/modules/experisci/experiment/types/scanning_fish.dm index f1c2263a84c..3ea4f543687 100644 --- a/code/modules/experisci/experiment/types/scanning_fish.dm +++ b/code/modules/experisci/experiment/types/scanning_fish.dm @@ -64,7 +64,7 @@ GLOBAL_LIST_EMPTY(scanned_fish_by_techweb) ///Only scannable fish will contribute towards the experiment. /datum/experiment/scanning/fish/final_contributing_index_checks(datum/component/experiment_handler/experiment_handler, obj/item/fish/target, typepath) - return target.experisci_scannable + return target.fish_flags & FISH_FLAG_EXPERIMENT_SCANNABLE /** * After a fish scanning experiment is done, more may be unlocked. If so, add them to the techweb diff --git a/code/modules/fishing/bait.dm b/code/modules/fishing/bait.dm index fbbe23d2ccc..9bd36daa7be 100644 --- a/code/modules/fishing/bait.dm +++ b/code/modules/fishing/bait.dm @@ -112,7 +112,7 @@ var/list/known_fishes = list() for(var/obj/item/fish/fish_type as anything in SSfishing.lure_catchables[type]) - if(initial(fish_type.show_in_catalog)) + if(initial(fish_type.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG) known_fishes += initial(fish_type.name) if(!length(known_fishes)) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 5596a0f8706..2831d2c166b 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -1,9 +1,8 @@ #define FISH_SAD 0 -#define FISH_NEUTRAL 1 -#define FISH_SATISFIED 2 -#define FISH_HAPPY 3 #define FISH_VERY_HAPPY 4 +#define GET_FISH_ELECTROGENESIS(fish) (fish.electrogenesis_power * fish.size * 0.1) + // Fish path used for autogenerated fish /obj/item/fish name = "fish" @@ -23,6 +22,9 @@ obj_flags = UNIQUE_RENAME item_flags = IMMUTABLE_SLOW|SLOWS_WHILE_IN_HAND + /// Flags for fish variables that would otherwise be TRUE/FALSE + var/fish_flags = FISH_FLAG_SHOW_IN_CATALOG|FISH_DO_FLOP_ANIM|FISH_FLAG_EXPERIMENT_SCANNABLE + /// width of aquarium visual icon var/sprite_width /// height of aquarium visual icon @@ -57,16 +59,12 @@ var/status = FISH_ALIVE ///icon used when the fish is dead, ifset. var/icon_state_dead - ///If this fish should do the flopping animation - var/do_flop_animation = TRUE /// Current fish health. Dies at 0. var/health = 100 /// The message shown when the fish dies. var/death_text = "%SRC dies." - /// Should this fish type show in fish catalog - var/show_in_catalog = TRUE /// How rare this fish is in the random cases var/random_case_rarity = FISH_RARITY_BASIC @@ -136,8 +134,6 @@ var/min_pressure = WARNING_LOW_PRESSURE var/max_pressure = HAZARD_HIGH_PRESSURE - /// If this fish type counts towards the Fish Species Scanning experiments - var/experisci_scannable = TRUE /// cooldown on creating tesla zaps COOLDOWN_DECLARE(electrogenesis_cooldown) /// power of the tesla zap created by the fish in a bioelectric generator. Scales with size. @@ -145,8 +141,6 @@ /// The beauty this fish provides to the aquarium it's inserted in. var/beauty = FISH_BEAUTY_GENERIC - ///have we recently pet this fish - var/recently_petted = FALSE /** * If you wonder why this isn't being tracked by the edible component instead: @@ -165,9 +159,9 @@ AddComponent(/datum/component/aquarium_content, list(COMSIG_FISH_STIRRED), beauty) RegisterSignal(src, COMSIG_ATOM_ON_LAZARUS_INJECTOR, PROC_REF(use_lazarus)) - if(do_flop_animation) + if(fish_flags & FISH_DO_FLOP_ANIM) RegisterSignal(src, COMSIG_ATOM_TEMPORARY_ANIMATION_START, PROC_REF(on_temp_animation)) - check_environment() + check_flopping() if(status != FISH_DEAD) ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, REF(src)) //Composting a food that is not real food wouldn't work anyway. START_PROCESSING(SSobj, src) @@ -435,12 +429,12 @@ /obj/item/fish/proc/update_size_and_weight(new_size = average_size, new_weight = average_weight) SEND_SIGNAL(src, COMSIG_FISH_UPDATE_SIZE_AND_WEIGHT, new_size, new_weight) if(size) - if(fillet_type) - RemoveElement(/datum/element/processable, TOOL_KNIFE, fillet_type, num_fillets, 0.5 SECONDS * num_fillets, screentip_verb = "Cut") + remove_fillet_type() if(size > FISH_SIZE_TWO_HANDS_REQUIRED) qdel(GetComponent(/datum/component/two_handed)) + size = new_size - electrogenesis_power = initial(electrogenesis_power) * size * 0.1 + var/init_icon_state = initial(inhand_icon_state) switch(size) if(0 to FISH_SIZE_TINY_MAX) @@ -472,11 +466,7 @@ inhand_icon_state = "[inhand_icon_state]_wielded" AddComponent(/datum/component/two_handed, require_twohands = TRUE) - if(fillet_type) - var/init_fillets = initial(num_fillets) - var/amount = max(round(init_fillets * size / FISH_FILLET_NUMBER_SIZE_DIVISOR, 1), 1) - num_fillets = amount - AddElement(/datum/element/processable, TOOL_KNIFE, fillet_type, num_fillets, 0.5 SECONDS * num_fillets, screentip_verb = "Cut") + add_fillet_type() var/make_edible = TRUE if(weight) @@ -519,6 +509,21 @@ update_fish_force() +/obj/item/fish/proc/remove_fillet_type() + if(!fillet_type) + return + var/amount = max(round(num_fillets * size / FISH_FILLET_NUMBER_SIZE_DIVISOR, 1), 1) + var/time = PERFORM_ALL_TESTS(fish_size_weight) ? 0 : 0.5 SECONDS * amount + RemoveElement(/datum/element/processable, TOOL_KNIFE, fillet_type, amount, time, screentip_verb = "Cut") + +/obj/item/fish/proc/add_fillet_type() + if(!fillet_type) + return + var/amount = max(round(num_fillets * size / FISH_FILLET_NUMBER_SIZE_DIVISOR, 1), 1) + var/time = PERFORM_ALL_TESTS(fish_size_weight) ? 0 : 0.5 SECONDS * amount + AddElement(/datum/element/processable, TOOL_KNIFE, fillet_type, amount, time, screentip_verb = "Cut") + return amount //checked by a unit test + ///Reset weapon-related variables of this items and recalculates those values based on the fish weight and size. /obj/item/fish/proc/update_fish_force() if(force >= 15 && hitsound == SFX_ALT_FISH_SLAP) @@ -653,7 +658,7 @@ /obj/item/fish/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() - check_environment() + check_flopping() /obj/item/fish/proc/enter_stasis() ADD_TRAIT(src, TRAIT_FISH_STASIS, INNATE_TRAIT) @@ -682,11 +687,11 @@ fed_reagents.remove_reagent(fed_reagent_type, 0.1) SEND_SIGNAL(src, COMSIG_FISH_FED, fed_reagents, fed_reagent_type) -/obj/item/fish/proc/check_environment() +/obj/item/fish/proc/check_flopping() if(QDELETED(src)) //we don't care anymore return - if(!do_flop_animation) + if(!(fish_flags & FISH_DO_FLOP_ANIM)) return // Do additional stuff @@ -721,7 +726,7 @@ health = initial(health) // since the fishe has been revived regenerate_bites(bites_amount) last_feeding = world.time //reset hunger - check_environment() + check_flopping() START_PROCESSING(SSobj, src) ADD_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT) if(FISH_DEAD) @@ -739,6 +744,51 @@ update_fish_force() SEND_SIGNAL(src, COMSIG_FISH_STATUS_CHANGED) +/obj/item/fish/vv_edit_var(var_name, var_value) + switch(var_name) + if(NAMEOF(src, status)) + if(var_value != FISH_DEAD && var_value != FISH_ALIVE) + var_value = var_value ? FISH_ALIVE : FISH_DEAD + set_status(var_value) + if(NAMEOF(src, size)) + if(!isnum(var_value) || var_value == 0) + return FALSE + update_size_and_weight(var_value, weight) + if(NAMEOF(src, weight)) + if(!isnum(var_value) || var_value == 0) + return FALSE + update_size_and_weight(size, var_value) + if(NAMEOF(src, health)) + if(!isnum(var_value)) + return FALSE + adjust_health(health) + if(NAMEOF(src, fish_flags)) + var/old_fish_flags = fish_flags + fish_flags = var_value + if((old_fish_flags ^ fish_flags) & FISH_DO_FLOP_ANIM) //the flopping flag wasn't added nor removed + return TRUE + if(fish_flags & FISH_DO_FLOP_ANIM) + RegisterSignal(src, COMSIG_ATOM_TEMPORARY_ANIMATION_START, PROC_REF(on_temp_animation)) + else + UnregisterSignal(src, COMSIG_ATOM_TEMPORARY_ANIMATION_START) + check_flopping() + if(NAMEOF(src, fillet_type)) + if(!ispath(var_value)) + return FALSE + remove_fillet_type() + fillet_type = var_value + add_fillet_type() + if(NAMEOF(src, num_fillets)) + if(!isnum(var_value)) + return FALSE + remove_fillet_type() + num_fillets = var_value + add_fillet_type() + else + return ..() + + return TRUE + /obj/item/fish/expose_reagents(list/reagents, datum/reagents/source, methods = TOUCH, volume_modifier = 1, show_message = TRUE) . = ..() if(. & COMPONENT_NO_EXPOSE_REAGENTS || status != FISH_DEAD) @@ -1082,7 +1132,7 @@ var/fish_zap_flags = ZAP_MOB_DAMAGE if(istype(loc, /obj/structure/aquarium/bioelec_gen)) fish_zap_range = 5 - fish_zap_power = electrogenesis_power + fish_zap_power = GET_FISH_ELECTROGENESIS(src) fish_zap_flags |= (ZAP_GENERATES_POWER | ZAP_MOB_STUN) tesla_zap(source = get_turf(src), zap_range = fish_zap_range, power = fish_zap_power, cutoff = 1 MEGA JOULES, zap_flags = fish_zap_flags) @@ -1096,7 +1146,7 @@ /obj/item/fish/proc/get_happiness_value() var/happiness_value = 0 - if(recently_petted) + if(fish_flags & FISH_FLAG_PETTED) happiness_value++ if(HAS_TRAIT(src, TRAIT_FISH_NO_HUNGER) || min((world.time - last_feeding) / feeding_frequency, 1) < 0.5) happiness_value++ @@ -1114,15 +1164,18 @@ return clamp(happiness_value, FISH_SAD, FISH_VERY_HAPPY) /obj/item/fish/proc/pet_fish(mob/living/user) - if(recently_petted) + if(fish_flags & FISH_FLAG_PETTED) to_chat(user, span_warning("[src] runs away from your finger as you dip it into the water!")) return - if(HAS_TRAIT(src, TRAIT_FISH_ELECTROGENESIS) && electrogenesis_power > 15 MEGA JOULES) + if(HAS_TRAIT(src, TRAIT_FISH_ELECTROGENESIS) && GET_FISH_ELECTROGENESIS(src) > 15 MEGA JOULES) user.electrocute_act(5, src) //was it all worth it? - recently_petted = TRUE + fish_flags |= FISH_FLAG_PETTED SEND_SIGNAL(src, COMSIG_FISH_PETTED) to_chat(user, span_notice("[src] dances around!")) - addtimer(VARSET_CALLBACK(src, recently_petted, FALSE), 30 SECONDS) + addtimer(CALLBACK(src, PROC_REF(undo_petted)), 30 SECONDS) + +/obj/item/fish/proc/undo_petted() + fish_flags &= ~FISH_FLAG_PETTED /// Returns random fish, using random_case_rarity probabilities. /proc/random_fish_type(required_fluid) @@ -1153,3 +1206,7 @@ return fluid_type == AQUARIUM_FLUID_SALTWATER || fluid_type == AQUARIUM_FLUID_FRESHWATER else return fish_fluid_type == fluid_type + +#undef GET_FISH_ELECTROGENESIS +#undef FISH_SAD +#undef FISH_VERY_HAPPY diff --git a/code/modules/fishing/fish/types/freshwater.dm b/code/modules/fishing/fish/types/freshwater.dm index b5891e19fb9..68254f66137 100644 --- a/code/modules/fishing/fish/types/freshwater.dm +++ b/code/modules/fishing/fish/types/freshwater.dm @@ -26,7 +26,7 @@ desc = "A great rubber duck tool for Lawyers who can't get a grasp over their case." stable_population = 1 random_case_rarity = FISH_RARITY_NOPE - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG beauty = FISH_BEAUTY_GOOD compatible_types = list(/obj/item/fish/goldfish, /obj/item/fish/goldfish/three_eyes) fish_traits = list(/datum/fish_trait/recessive) @@ -61,7 +61,7 @@ desc = "A great rubber duck tool for Lawyers who can't get a grasp over their case. It looks kinda different today..." compatible_types = list(/obj/item/fish/goldfish, /obj/item/fish/goldfish/three_eyes) beauty = FISH_BEAUTY_GREAT - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG stable_population = 1 random_case_rarity = FISH_RARITY_NOPE diff --git a/code/modules/fishing/fish/types/holographic.dm b/code/modules/fishing/fish/types/holographic.dm index 159334002bc..64de7d866d6 100644 --- a/code/modules/fishing/fish/types/holographic.dm +++ b/code/modules/fishing/fish/types/holographic.dm @@ -3,7 +3,7 @@ name = "holographic goldfish" desc = "A holographic representation of a common goldfish, slowly flickering out, removed from its holo-habitat." icon_state = /obj/item/fish/goldfish::icon_state - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~(FISH_FLAG_SHOW_IN_CATALOG|FISH_FLAG_EXPERIMENT_SCANNABLE) random_case_rarity = FISH_RARITY_NOPE dedicated_in_aquarium_icon_state = /obj/item/fish/goldfish::dedicated_in_aquarium_icon_state aquarium_vc_color = /obj/item/fish/goldfish::aquarium_vc_color @@ -16,7 +16,6 @@ fillet_type = null death_text = "%SRC gently disappears." fish_traits = list(/datum/fish_trait/no_mating) //just to be sure, these shouldn't reproduce - experisci_scannable = FALSE beauty = /obj/item/fish/goldfish::beauty /obj/item/fish/holo/Initialize(mapload, apply_qualities = TRUE) diff --git a/code/modules/fishing/fish/types/ruins.dm b/code/modules/fishing/fish/types/ruins.dm index a01cd062354..153a5bc3b7b 100644 --- a/code/modules/fishing/fish/types/ruins.dm +++ b/code/modules/fishing/fish/types/ruins.dm @@ -8,7 +8,7 @@ pixel_x = -16 sprite_width = 12 sprite_height = 7 - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG random_case_rarity = FISH_RARITY_NOPE fishing_difficulty_modifier = 30 required_fluid_type = AQUARIUM_FLUID_ANY_WATER @@ -39,7 +39,7 @@ average_size = 60 average_weight = 1200 stable_population = 4 - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG beauty = FISH_BEAUTY_EXCELLENT fish_movement_type = /datum/fish_movement/choppy //Glideless legacy movement? in my fishing minigame? favorite_bait = list( @@ -72,7 +72,7 @@ average_size = 40 average_weight = 750 stable_population = 5 - show_in_catalog = FALSE + fish_flags = parent_type::fish_flags & ~FISH_FLAG_SHOW_IN_CATALOG beauty = FISH_BEAUTY_GREAT favorite_bait = list( list( diff --git a/code/modules/fishing/fish/types/station.dm b/code/modules/fishing/fish/types/station.dm index 0fa8032d979..baf104ae14f 100644 --- a/code/modules/fishing/fish/types/station.dm +++ b/code/modules/fishing/fish/types/station.dm @@ -74,7 +74,7 @@ icon_state_dead = "slimefish_dead" sprite_width = 7 sprite_height = 7 - do_flop_animation = FALSE //it already has a cute bouncy wiggle. :3 + fish_flags = parent_type::fish_flags & ~FISH_DO_FLOP_ANIM //it already has a cute bouncy wiggle. :3 random_case_rarity = FISH_RARITY_VERY_RARE required_fluid_type = AQUARIUM_FLUID_ANADROMOUS stable_population = 4 diff --git a/code/modules/fishing/fish_catalog.dm b/code/modules/fishing/fish_catalog.dm index 6a64b85184f..4235e5fe88d 100644 --- a/code/modules/fishing/fish_catalog.dm +++ b/code/modules/fishing/fish_catalog.dm @@ -17,7 +17,7 @@ if(!fish_info) fish_info = list() for(var/obj/item/fish/fish as anything in subtypesof(/obj/item/fish)) - if(!initial(fish.show_in_catalog)) + if(!(initial(fish.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG)) continue var/list/fish_data = list() fish_data["name"] = initial(fish.name) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 0771e3fe603..35d14a5c734 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -394,7 +394,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) if(!ispath(reward, /obj/item/fish)) continue var/obj/item/fish/prototype = reward - if(initial(prototype.show_in_catalog)) + if(initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG) return TRUE return FALSE @@ -410,7 +410,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) if(!ispath(reward, /obj/item/fish)) continue var/obj/item/fish/prototype = reward - if(initial(prototype.show_in_catalog)) + if(initial(prototype.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG) var/init_name = initial(prototype.name) if(rod) var/init_weight = fish_table[reward] @@ -510,7 +510,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) total_weight_without_bait += weight total_weight_no_fish += weight continue - if(initial(fish.show_in_catalog)) + if(initial(fish.fish_flags) & FISH_FLAG_SHOW_IN_CATALOG) only_fish += fish total_weight_without_bait += round(fish_table[fish] * FISH_WEIGHT_MULT_WITHOUT_BAIT, 1) diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index 0c02c0c3a90..91d0c006522 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -21,14 +21,26 @@ /datum/unit_test/fish_size_weight /datum/unit_test/fish_size_weight/Run() - var/obj/item/fish/fish = allocate(/obj/item/fish/testdummy) + + var/obj/structure/table/table = allocate(/obj/structure/table) + var/obj/item/fish/testdummy/fish = new /obj/item/fish/testdummy (table.loc) + allocated += fish var/datum/reagent/reagent = fish.reagents?.has_reagent(/datum/reagent/fishdummy) TEST_ASSERT(reagent, "the test fish doesn't have the test reagent.[fish.reagents ? "" : " It doesn't even have a reagent holder."]") var/expected_units = FISH_REAGENT_AMOUNT * fish.weight / FISH_WEIGHT_BITE_DIVISOR TEST_ASSERT_EQUAL(reagent.volume, expected_units, "the test fish has [reagent.volume] units of the test reagent when it should have [expected_units]") TEST_ASSERT_EQUAL(fish.w_class, WEIGHT_CLASS_BULKY, "the test fish has w_class of [fish.w_class] when it should have been [WEIGHT_CLASS_BULKY]") - var/expected_num_fillets = round(FISH_SIZE_BULKY_MAX / FISH_FILLET_NUMBER_SIZE_DIVISOR * 2, 1) - TEST_ASSERT_EQUAL(fish.num_fillets, expected_num_fillets, "the test fish has [fish.num_fillets] number of fillets when it should have [expected_num_fillets]") + var/mob/living/carbon/human/consistent/chef = allocate(/mob/living/carbon/human/consistent) + var/obj/item/knife/kitchen/blade = allocate(/obj/item/knife/kitchen) + var/fish_fillet_type = fish.fillet_type + var/expected_num_fillets = fish.expected_num_fillets + blade.melee_attack_chain(chef, fish) + var/counted_fillets = 0 + for(var/atom/movable/content as anything in table.loc.contents) + if(istype(content, fish_fillet_type)) + counted_fillets++ + allocated += content + TEST_ASSERT_EQUAL(counted_fillets, expected_num_fillets, "the test fish yielded [counted_fillets] fillets when it should have been [expected_num_fillets]") ///Checks that fish breeding works correctly. /datum/unit_test/fish_breeding @@ -71,7 +83,7 @@ /datum/unit_test/fish_scanning/Run() var/scannable_fishes = 0 for(var/obj/item/fish/fish_prototype as anything in subtypesof(/obj/item/fish)) - if(initial(fish_prototype.experisci_scannable)) + if(initial(fish_prototype.fish_flags) & FISH_FLAG_EXPERIMENT_SCANNABLE) scannable_fishes++ for(var/datum/experiment/scanning/fish/fish_scan as anything in typesof(/datum/experiment/scanning/fish)) fish_scan = new fish_scan @@ -88,7 +100,12 @@ fish_traits = list(/datum/fish_trait/dummy) stable_population = INFINITY breeding_timeout = 0 - show_in_catalog = FALSE //skipped by the autowiki unit test. + fish_flags = parent_type::fish_flags & ~(FISH_FLAG_SHOW_IN_CATALOG|FISH_FLAG_EXPERIMENT_SCANNABLE) + var/expected_num_fillets = 0 //used to know how many fillets should be gotten out of this fish + +/obj/item/fish/testdummy/add_fillet_type() + expected_num_fillets = ..() + return expected_num_fillets /obj/item/fish/testdummy/two fish_traits = list(/datum/fish_trait/dummy/two) From 1bca4f4fd6a0f5c7f550aa4a2c2718adf45076cb Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:14:37 +0200 Subject: [PATCH 097/142] Another examine refactor: Tag edition (#86678) Another batch of changes to examine, ideas being courtesy of Melbert and Swanni. When examining an item you will now see tags with tooltips elaborating on their meaning instead of having each property displayed in a separate line. Additionally, examines now use fieldsets, saving a line previously spent on displaying an item's name and instead putting it directly into the top outline. Embedding and slapcrafting also display their properties as tags, and combat info now displays item's sharpness. Here are some examples, each tag previously taking up its own line. ![image](https://github.com/user-attachments/assets/f2cabc5a-daff-41b3-b320-4414eaf31c99) ![image](https://github.com/user-attachments/assets/3e2dff49-4f11-45dd-94a7-93205030f985) ![image](https://github.com/user-attachments/assets/359152ce-2a1d-4db2-8914-3a9416a6d4a9) Additionally, protection classes now better elaborate on items' temperature protection properties and tell you the exact temperatures that an item can withstand ![image](https://github.com/user-attachments/assets/a75f989d-d7d3-4305-b87d-ccd3124c0b6f) Tags are a very intuitive system used in many games and we could benefit from it too. Compressing seven lines of text into one while retaining readability and all information within by using tooltips will majorly cut down on chat space used by examines. :cl: refactor: Refactored how examines display item properties. A lot of them are now displayed as tags that you can hover over to receive details about, like item size, resistances and materials an object is made of. qol: Protection classes now better elaborate on thermal resistances of items, displaying the exact temperatures they can protect you from. /:cl: --- code/__DEFINES/chat.dm | 2 + .../signals/signals_atom/signals_atom_main.dm | 2 + code/datums/elements/embed.dm | 8 +-- code/datums/elements/slapcrafting.dm | 4 +- code/datums/elements/weapon_description.dm | 4 ++ code/game/atom/atom_examine.dm | 43 ++++++++++++-- code/game/machinery/_machinery.dm | 3 + code/game/objects/items.dm | 39 +++++++----- code/game/objects/objs.dm | 5 +- code/game/objects/structures.dm | 3 + code/game/turfs/closed/_closed.dm | 3 + code/game/turfs/closed/walls.dm | 1 - code/game/turfs/open/_open.dm | 3 + code/modules/clothing/clothing.dm | 59 +++++++++++++++---- code/modules/mob/mob.dm | 6 +- 15 files changed, 141 insertions(+), 44 deletions(-) diff --git a/code/__DEFINES/chat.dm b/code/__DEFINES/chat.dm index f4f88df6c70..40f342df268 100644 --- a/code/__DEFINES/chat.dm +++ b/code/__DEFINES/chat.dm @@ -45,6 +45,8 @@ #define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]") /// Adds a generic box around whatever message you're sending in chat. Really makes things stand out. #define examine_block(str) ("
" + str + "
") +/// Makes a fieldset with a name in the middle top part. Can apply additional classes +#define fieldset_block(title, content, classes) ("
" + title + "
" + content + "
") /// Makes a horizontal line with text in the middle #define separator_hr(str) ("
" + str + "
") /// Emboldens runechat messages 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 3282c9387a1..2e42957aa3a 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -9,6 +9,8 @@ #define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON "atom_init_success_on" ///from base of atom/examine(): (/mob, list/examine_text) #define COMSIG_ATOM_EXAMINE "atom_examine" +///from base of atom/examine_tags(): (/mob, list/examine_tags) +#define COMSIG_ATOM_EXAMINE_TAGS "atom_examine_tags" ///from base of atom/get_examine_name(): (/mob, list/overrides) #define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //Positions for overrides list diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 5217738dff6..2aae03fb3a4 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -23,7 +23,7 @@ return RegisterSignal(target, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(check_embed)) - RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(examined)) + RegisterSignal(target, COMSIG_ATOM_EXAMINE_TAGS, PROC_REF(examined_tags)) RegisterSignal(target, COMSIG_EMBED_TRY_FORCE, PROC_REF(try_force_embed)) RegisterSignal(target, COMSIG_ITEM_DISABLE_EMBED, PROC_REF(detach_from_weapon)) @@ -82,13 +82,13 @@ Detach(weapon) ///Someone inspected our embeddable item -/datum/element/embed/proc/examined(obj/item/I, mob/user, list/examine_list) +/datum/element/embed/proc/examined_tags(obj/item/I, mob/user, list/examine_list) SIGNAL_HANDLER if(I.is_embed_harmless()) - examine_list += "[I] feels sticky, and could probably get stuck to someone if thrown properly!" + examine_list["sticky"] = "[I] feels sticky, and could probably get stuck to someone if thrown properly!" else - examine_list += "[I] has a fine point, and could probably embed in someone if thrown properly!" + examine_list["embeddable"] = "[I] has a fine point, and could probably embed in someone if thrown properly!" /** * check_embed_projectile() is what we get when a projectile with a defined shrapnel_type impacts a target. diff --git a/code/datums/elements/slapcrafting.dm b/code/datums/elements/slapcrafting.dm index 42776bf31f7..4b58bddd2a0 100644 --- a/code/datums/elements/slapcrafting.dm +++ b/code/datums/elements/slapcrafting.dm @@ -26,7 +26,7 @@ return //Don't do anything, it just shouldn't be used in crafting. RegisterSignal(target, COMSIG_ATOM_ATTACKBY, PROC_REF(attempt_slapcraft)) - RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(get_examine_info)) + RegisterSignal(target, COMSIG_ATOM_EXAMINE_TAGS, PROC_REF(get_examine_info)) RegisterSignal(target, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(get_examine_more_info)) RegisterSignal(target, COMSIG_TOPIC, PROC_REF(topic_handler)) @@ -126,7 +126,7 @@ already_used_names += initial(result.name) string_results += list("\a [initial(result.name)]") - examine_list += span_notice("You think [source] could be used to make [english_list(string_results)]! Examine again to look at the details...") + examine_list["crafting component"] = "You think [source] could be used to make [english_list(string_results)]! Examine again to look at the details..." /// Alerts any examiners to the details of the recipe. /datum/element/slapcrafting/proc/get_examine_more_info(atom/source, mob/user, list/examine_list) diff --git a/code/datums/elements/weapon_description.dm b/code/datums/elements/weapon_description.dm index 0897b571159..eda7ca59b49 100644 --- a/code/datums/elements/weapon_description.dm +++ b/code/datums/elements/weapon_description.dm @@ -73,6 +73,10 @@ // Doesn't show the base notes for items that have the override notes variable set to true if(!source.override_notes) + if (source.sharpness & SHARP_EDGED) + readout += "It's sharp and could cause bleeding wounds." + if (source.sharpness & SHARP_POINTY) + readout += "It's pointy and could cause piercing wounds." // Make sure not to divide by 0 on accident if(source.force > 0) readout += "It takes about [span_warning("[HITS_TO_CRIT(source.force)] melee hit\s")] to take down an enemy." diff --git a/code/game/atom/atom_examine.dm b/code/game/atom/atom_examine.dm index 50ad54c429b..fee219f7b4b 100644 --- a/code/game/atom/atom_examine.dm +++ b/code/game/atom/atom_examine.dm @@ -24,12 +24,15 @@ if(desc) . += "[desc]" - if(custom_materials) - var/list/materials_list = list() - for(var/custom_material in custom_materials) - var/datum/material/current_material = GET_MATERIAL_REF(custom_material) - materials_list += "[current_material.name]" - . += "[EXAMINE_SECTION_BREAK]It is made out of [english_list(materials_list)]." // NOVA EDIT CHANGE - ORIGINAL: . += "It is made out of [english_list(materials_list)]." + var/list/tags_list = examine_tags(user) + if (length(tags_list)) + var/tag_string = list() + for (var/atom_tag in tags_list) + tag_string += (isnull(tags_list[atom_tag]) ? atom_tag : span_tooltip(tags_list[atom_tag], atom_tag)) + // Weird bit but ensures that if the final element has its own "and" we don't add another one + tag_string = english_list(tag_string, and_text = (findtext(tag_string[length(tag_string)], " and ")) ? ", " : " and ") + var/post_descriptor = examine_post_descriptor(user) + . += "[p_They()] [p_are()] a [tag_string] [examine_descriptor(user)][length(post_descriptor) ? " [jointext(post_descriptor, " ")]" : ""]." if(reagents) var/user_sees_reagents = user.can_see_reagents() @@ -55,6 +58,34 @@ SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE, user, .) +/* + * A list of "tags" displayed after atom's description in examine. + * This should return an assoc list of tags -> tooltips for them. If item if null, then no tooltip is assigned. + * For example: + * list("small" = "This is a small size class item.", "fireproof" = "This item is impervious to fire.") + * will result in + * This is a small, fireproof item. + * where "item" is pulled from examine_descriptor() proc + */ +/atom/proc/examine_tags(mob/user) + . = list() + SEND_SIGNAL(src, COMSIG_ATOM_EXAMINE_TAGS, user, .) + +/// What this atom should be called in examine tags +/atom/proc/examine_descriptor(mob/user) + return "object" + +/// Returns a list of strings to be displayed after the descriptor +/atom/proc/examine_post_descriptor(mob/user) + . = list() + if(!custom_materials) + return + var/mats_list = list() + for(var/custom_material in custom_materials) + var/datum/material/current_material = GET_MATERIAL_REF(custom_material) + mats_list += span_tooltip("It is made out of [current_material.name].", current_material.name) + . += "made of [english_list(mats_list)]" + /** * Called when a mob examines (shift click or verb) this atom twice (or more) within EXAMINE_MORE_WINDOW (default 1 second) * diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 67616de8fca..7d22fcc4916 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -1148,6 +1148,9 @@ if(0 to 25) . += span_warning("It's falling apart!") +/obj/machinery/examine_descriptor(mob/user) + return "machine" + /obj/machinery/examine_more(mob/user) . = ..() if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER) && component_parts) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4f2a2c08a85..fed40fdde62 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -461,27 +461,36 @@ abstract_move(null) forceMove(T) -/obj/item/examine(mob/user) //This might be spammy. Remove? - . = ..() - - . += "[gender == PLURAL ? "They are" : "It is"] a [weight_class_to_text(w_class)] item." +/obj/item/examine_tags(mob/user) + var/list/parent_tags = ..() + parent_tags.Insert(1, weight_class_to_text(w_class)) // To make size display first, otherwise it looks goofy + . = parent_tags + .[weight_class_to_text(w_class)] = "[gender == PLURAL ? "They are" : "It is"] a [weight_class_to_text(w_class)] item." if(item_flags & CRUEL_IMPLEMENT) - . += "[src] seems quite practical for particularly morbid procedures and experiments." + .[span_red("morbid")] = "It seems quite practical for particularly morbid procedures and experiments." + + if (siemens_coefficient == 0) + .["insulated"] = "It is made from a robust electrical insulator and will block any electricity passing through it!" + else if (siemens_coefficient <= 0.5) + .["partially insulated"] = "It is made from a poor insulator that will dampen (but not fully block) electric shocks passing through it." if(resistance_flags & INDESTRUCTIBLE) - . += "[src] seems extremely robust! It'll probably withstand anything that could happen to it!" - else - if(resistance_flags & LAVA_PROOF) - . += "[src] is made of an extremely heat-resistant material, it'd probably be able to withstand lava!" - if(resistance_flags & (ACID_PROOF | UNACIDABLE)) - . += "[src] looks pretty robust! It'd probably be able to withstand acid!" - if(resistance_flags & FREEZE_PROOF) - . += "[src] is made of cold-resistant materials." - if(resistance_flags & FIRE_PROOF) - . += "[src] is made of fire-retardant materials." + .["indestructible"] = "It is extremely robust! It'll probably withstand anything that could happen to it!" return + if(resistance_flags & LAVA_PROOF) + .["lavaproof"] = "It is made of an extremely heat-resistant material, it'd probably be able to withstand lava!" + if(resistance_flags & (ACID_PROOF | UNACIDABLE)) + .["acidproof"] = "It looks pretty robust! It'd probably be able to withstand acid!" + if(resistance_flags & FREEZE_PROOF) + .["freezeproof"] = "It is made of cold-resistant materials." + if(resistance_flags & FIRE_PROOF) + .["fireproof"] = "It is made of fire-retardant materials." + +/obj/item/examine_descriptor(mob/user) + return "item" + /obj/item/examine_more(mob/user) . = ..() if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER)) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index ef436e24e8c..0a88aade697 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -187,8 +187,11 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) . = ..() if(desc_controls) . += span_notice(desc_controls) + +/obj/examine_tags(mob/user) + . = ..() if(obj_flags & UNIQUE_RENAME) - . += span_notice("Use a pen on it to rename it or change its description.") + .["renameable"] = "Use a pen on it to rename it or change its description." /obj/analyzer_act(mob/living/user, obj/item/analyzer/tool) if(atmos_scan(user=user, target=src, silent=FALSE)) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 701c13bfcf7..e6c9579d679 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -58,6 +58,9 @@ if(!broken) return span_warning("It's falling apart!") +/obj/structure/examine_descriptor(mob/user) + return "structure" + /obj/structure/rust_heretic_act() take_damage(500, BRUTE, "melee", 1) diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm index 8ccaabc46c0..cf287a6eb6d 100644 --- a/code/game/turfs/closed/_closed.dm +++ b/code/game/turfs/closed/_closed.dm @@ -15,3 +15,6 @@ /turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) return FALSE + +/turf/closed/examine_descriptor(mob/user) + return "wall" diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 611c01f3e8e..b4df62d7a07 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -68,7 +68,6 @@ GLOB.station_turfs -= src return ..() - /turf/closed/wall/examine(mob/user) . += ..() . += deconstruction_hints(user) diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index 92593095ca8..d01bdde3b3e 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -74,6 +74,9 @@ . += burnt_appearance +/turf/open/examine_descriptor(mob/user) + return "floor" + //direction is direction of travel of A /turf/open/zPassIn(direction) if(direction != DOWN) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 880d6f667c2..e24f80e3642 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -314,14 +314,6 @@ . += span_warning("[p_Theyre()] completely shredded and require[p_s()] mending before [p_they()] can be worn again!") return - switch (max_heat_protection_temperature) - if (400 to 1000) - . += "[src] offers the wearer limited protection from fire." - if (1001 to 1600) - . += "[src] offers the wearer some protection from fire." - if (1601 to 35000) - . += "[src] offers the wearer robust protection from fire." - if(TRAIT_FAST_CUFFING in clothing_traits) . += "[src] increase the speed that you handcuff others." @@ -356,6 +348,38 @@ if(get_armor().has_any_armor() || (flags_cover & (HEADCOVERSMOUTH|PEPPERPROOF)) || (clothing_flags & STOPSPRESSUREDAMAGE) || (visor_flags & STOPSPRESSUREDAMAGE)) . += span_notice("OOC: Click
here to see its protection classes.") // NOVA EDIT CHANGE - ORIGINAL: += span_notice("It has a tag listing its protection classes.") +/obj/item/clothing/examine_tags(mob/user) + . = ..() + if (clothing_flags & THICKMATERIAL) + .["thick"] = "Protects from most injections and sprays." + if (clothing_flags & CASTING_CLOTHES) + .["magical"] = "Allows magical beings to cast spells when wearing [src]." + if((clothing_flags & STOPSPRESSUREDAMAGE) || (visor_flags & STOPSPRESSUREDAMAGE)) + .["pressureproof"] = "Protects the wearer from extremely low or high pressure, such as vacuum of space." + if(flags_cover & PEPPERPROOF) + .["pepperproof"] = "Protects the wearer from the effects of pepperspray." + if (heat_protection || cold_protection) + var/heat_desc + var/cold_desc + switch (max_heat_protection_temperature) + if (400 to 1000) + heat_desc = "high" + if (1001 to 1600) + heat_desc = "very high" + if (1601 to 35000) + heat_desc = "extremely high" + switch (min_cold_protection_temperature) + if (160 to 272) + cold_desc = "low" + if (72 to 159) + cold_desc = "very low" + if (0 to 71) + cold_desc = "extremely low" + .["thermally insulated"] = "Protects the wearer from [jointext(list(heat_desc, cold_desc), " and ")] temperatures." + +/obj/item/clothing/examine_descriptor(mob/user) + return "clothing" + /obj/item/clothing/Topic(href, href_list) . = ..() @@ -383,7 +407,7 @@ added_damage_header = TRUE readout += "[armor_to_protection_name(durability_key)] [armor_to_protection_class(rating)]" - if(flags_cover & HEADCOVERSMOUTH || flags_cover & PEPPERPROOF) + if((flags_cover & HEADCOVERSMOUTH) || (flags_cover & PEPPERPROOF)) var/list/things_blocked = list() if(flags_cover & HEADCOVERSMOUTH) things_blocked += span_tooltip("Because this item is worn on the head and is covering the mouth, it will block facehugger proboscides, killing facehuggers.", "facehuggers") @@ -393,7 +417,7 @@ readout += "COVERAGE" readout += "It will block [english_list(things_blocked)]." - if(clothing_flags & STOPSPRESSUREDAMAGE || visor_flags & STOPSPRESSUREDAMAGE) + if((clothing_flags & STOPSPRESSUREDAMAGE) || (visor_flags & STOPSPRESSUREDAMAGE)) var/list/parts_covered = list() var/output_string = "It" if(!(clothing_flags & STOPSPRESSUREDAMAGE)) @@ -405,8 +429,19 @@ if(length(parts_covered)) // Just in case someone makes spaceproof gloves or something readout += "[output_string] will protect the wearer's [english_list(parts_covered)] from [span_tooltip("The extremely low pressure is the biggest danger posed by the vacuum of space.", "low pressure")]." - if(min_cold_protection_temperature == SPACE_SUIT_MIN_TEMP_PROTECT) - readout += "It will insulate the wearer from [span_tooltip("While not as dangerous as the lack of pressure, the extremely low temperature of space is also a hazard.", "the cold of space")]." + var/heat_prot + switch (max_heat_protection_temperature) + if (400 to 1000) + heat_prot = "minor" + if (1001 to 1600) + heat_prot = "some" + if (1601 to 35000) + heat_prot = "extreme" + if (heat_prot) + . += "[src] offers the wearer [heat_protection] protection from heat, up to [max_heat_protection_temperature] kelvin." + + if(min_cold_protection_temperature) + readout += "It will insulate the wearer from [min_cold_protection_temperature <= SPACE_SUIT_MIN_TEMP_PROTECT ? span_tooltip("While not as dangerous as the lack of pressure, the extremely low temperature of space is also a hazard.", "the cold of space, down to [min_cold_protection_temperature] kelvin") : "cold, down to [min_cold_protection_temperature] kelvin"]." if(!length(readout)) readout += "No armor or durability information available." diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7fd68426033..d7a8d07835f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -575,10 +575,10 @@ var/list/result = examinify.examine(src) var/atom_title = examinify.examine_title(src, thats = TRUE) SEND_SIGNAL(src, COMSIG_MOB_EXAMINING, examinify, result) - result_combined = (atom_title ? "[span_slightly_larger("[atom_title][ismob(examinify) ? "!" :"."][EXAMINE_SECTION_BREAK]")]" : "") + jointext(result, "
") // NOVA EDIT CHANGE - No more separator_hr + exclamation point for mobs - ORIGINAL: result_combined = (atom_title ? "[span_slightly_larger(separator_hr("[atom_title]."))]" : "") + jointext(result, "
") - result_combined = replacetext(result_combined, "

", "
") // NOVA EDIT ADDITION - bit of a hack here to make sure we don't get linebreaks coming after headers + result_combined = (atom_title ? "[span_slightly_larger("[atom_title][ismob(examinify) ? "!" :"."][EXAMINE_SECTION_BREAK]")]" : "") + jointext(result, "
") // NOVA EDIT CHANGE - No centered title + exclamation point for mobs - ORIGINAL: result_combined = (atom_title ? fieldset_block("[span_slightly_larger(atom_title)].", jointext(result, "
"), "examine_block") : examine_block(jointext(result, "
"))) + result_combined = examine_block(replacetext(result_combined, "

", "
")) // NOVA EDIT ADDITION - bit of a hack here to make sure we don't get linebreaks coming after headers, as well as properly adding the examine_block - to_chat(src, examine_block(span_infoplain(result_combined))) + to_chat(src, span_infoplain(result_combined)) SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, examinify) /mob/proc/blind_examine_check(atom/examined_thing) From 2745a0ff9c2ede9db023fd5ea5cf1f50940d5ef1 Mon Sep 17 00:00:00 2001 From: deathrobotpunch <87455177+deathrobotpunch@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:48:31 +0800 Subject: [PATCH 098/142] adds fishing category to games vendor (#86699) ## About The Pull Request this pull request adds a fishing category to the games vendor with items that cost 50 credits more than their goodie alternatives. ## Why It's Good For The Game this allows people to start their fishing goals earlier without waiting 20 minutes for cargo at the caveat of the items costing 50 credits extra than normal ## Changelog :cl: add: Added new fishing category to games vendor /:cl: --- code/modules/fishing/aquarium/fish_analyzer.dm | 1 + code/modules/fishing/fish_catalog.dm | 1 + code/modules/fishing/fishing_equipment.dm | 4 ++++ code/modules/fishing/fishing_rod.dm | 1 + code/modules/vending/games.dm | 13 +++++++++++++ 5 files changed, 20 insertions(+) diff --git a/code/modules/fishing/aquarium/fish_analyzer.dm b/code/modules/fishing/aquarium/fish_analyzer.dm index 3d01479ef5a..764626fddbf 100644 --- a/code/modules/fishing/aquarium/fish_analyzer.dm +++ b/code/modules/fishing/aquarium/fish_analyzer.dm @@ -8,6 +8,7 @@ worn_icon_state = "fish_analyzer" desc = "A fish-shaped scanner used to monitor fish's status and evolutionary traits." obj_flags = CONDUCTS_ELECTRICITY + custom_price = PAYCHECK_CREW * 3 item_flags = NOBLUDGEON slot_flags = ITEM_SLOT_BELT throwforce = 3 diff --git a/code/modules/fishing/fish_catalog.dm b/code/modules/fishing/fish_catalog.dm index 4235e5fe88d..6e0216dcb8c 100644 --- a/code/modules/fishing/fish_catalog.dm +++ b/code/modules/fishing/fish_catalog.dm @@ -3,6 +3,7 @@ name = "Fish Encyclopedia" desc = "Indexes all fish known to mankind (and related species)." icon_state = "fishbook" + custom_price = PAYCHECK_CREW * 2 starting_content = "Lot of fish stuff" //book wrappers could use cleaning so this is not necessary /obj/item/book/manual/fish_catalog/ui_interact(mob/user, datum/tgui/ui) diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 5b2a250f42b..e2b4523448b 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -287,6 +287,7 @@ icon_state = "fishing" inhand_icon_state = "artistic_toolbox" material_flags = NONE + custom_price = PAYCHECK_CREW * 3 /obj/item/storage/toolbox/fishing/Initialize(mapload) . = ..() @@ -339,6 +340,7 @@ /obj/item/storage/box/fishing_hooks name = "fishing hook set" illustration = "fish" + custom_price = PAYCHECK_CREW * 2 /obj/item/storage/box/fishing_hooks/PopulateContents() new /obj/item/fishing_hook/magnet(src) @@ -355,6 +357,7 @@ /obj/item/storage/box/fishing_lines name = "fishing line set" illustration = "fish" + custom_price = PAYCHECK_CREW * 2 /obj/item/storage/box/fishing_lines/PopulateContents() new /obj/item/fishing_line/bouncy(src) @@ -403,6 +406,7 @@ icon_state = "plasticbox" foldable_result = null illustration = "fish" + custom_price = PAYCHECK_CREW * 9 /obj/item/storage/box/fishing_lures/PopulateContents() new /obj/item/paper/lures_instructions(src) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index f7f4d12e6a0..7ee15cead66 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -502,6 +502,7 @@ icon_state = "fishing_rod_telescopic" desc = "A lightweight, ergonomic, easy to store telescopic fishing rod. " inhand_icon_state = null + custom_price = PAYCHECK_CREW * 9 force = 0 w_class = WEIGHT_CLASS_NORMAL ui_description = "A collapsible fishing rod that can fit within a backpack." diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index d1a237eaf64..98a77c7f40c 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -45,6 +45,19 @@ /obj/item/stack/pipe_cleaner_coil/random = 10, ), ), + list( + "name" = "Fishing", + "icon" = "fish", + "products" = list( + /obj/item/storage/toolbox/fishing = 2, + /obj/item/storage/box/fishing_hooks = 2, + /obj/item/storage/box/fishing_lines = 2, + /obj/item/storage/box/fishing_lures = 2, + /obj/item/book/manual/fish_catalog = 5, + /obj/item/fish_analyzer = 2, + /obj/item/fishing_rod/telescopic = 1, + ), + ), list( "name" = "Skillchips", "icon" = "floppy-disk", From 307a0b10986c1828b073f3ce102eafe6ba8ff8e4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:02:51 +0000 Subject: [PATCH 099/142] Automatic changelog for PR #86699 [ci skip] --- html/changelogs/AutoChangeLog-pr-86699.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86699.yml diff --git a/html/changelogs/AutoChangeLog-pr-86699.yml b/html/changelogs/AutoChangeLog-pr-86699.yml new file mode 100644 index 00000000000..d33b4dd7426 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86699.yml @@ -0,0 +1,4 @@ +author: "deathrobotpunch" +delete-after: True +changes: + - rscadd: "Added new fishing category to games vendor" \ No newline at end of file From 9175226cfe59c6823764b0d940a6dc654577fdbf Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 17 Sep 2024 21:02:52 +0200 Subject: [PATCH 100/142] Fixes petrification not removing NOBLOOD trait after ending (#86712) ## About The Pull Request Closes #86710, statues now add noblood themselves from a different source ## Changelog :cl: fix: Fixed petrification not removing NOBLOOD trait after ending /:cl: --- code/game/objects/structures/petrified_statue.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index d7fdfab74e2..d27a2e8e1cd 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -111,7 +111,6 @@ return FALSE var/obj/structure/statue/petrified/S = new(loc, src, statue_timer, save_brain) S.name = "statue of [name]" - ADD_TRAIT(src, TRAIT_NOBLOOD, MAGIC_TRAIT) S.copy_overlays(src) var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) if(colorlist) From 48de6ba43d5997a51e3bc3fe5a4d594de2b57d2b Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:03:14 +0000 Subject: [PATCH 101/142] Automatic changelog for PR #86712 [ci skip] --- html/changelogs/AutoChangeLog-pr-86712.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86712.yml diff --git a/html/changelogs/AutoChangeLog-pr-86712.yml b/html/changelogs/AutoChangeLog-pr-86712.yml new file mode 100644 index 00000000000..72397760378 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86712.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Fixed petrification not removing NOBLOOD trait after ending" \ No newline at end of file From 2e2adb50643b9bf47bdb831a5a9d5d8d66e18db9 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Tue, 17 Sep 2024 21:05:11 +0200 Subject: [PATCH 102/142] Changing ID card's trim now properly adjusts linked bank account's job (#86711) ## About The Pull Request Closes #61216 Closes #57516 Arcane gave greenlight on this PR as its unlikely that this'll be cheesed or affect balance in any way, and in worst case scenario mass account changes will just summon space IRS on the offending HoP ## Changelog :cl: fix: Changing ID card's trim now properly adjusts linked bank account's job, allowing you to receive bounties for your new job /:cl: --- code/controllers/subsystem/id_access.dm | 4 ++++ code/datums/id_trim/_id_trim.dm | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/code/controllers/subsystem/id_access.dm b/code/controllers/subsystem/id_access.dm index ef4e8835ab7..af2dea8c5dd 100644 --- a/code/controllers/subsystem/id_access.dm +++ b/code/controllers/subsystem/id_access.dm @@ -410,6 +410,10 @@ SUBSYSTEM_DEF(id_access) if(trim.assignment) id_card.assignment = trim.assignment + var/datum/job/trim_job = trim.find_job() + if (!isnull(trim_job) && !isnull(id_card.registered_account)) + id_card.registered_account.account_job = trim_job + id_card.update_label() id_card.update_icon() diff --git a/code/datums/id_trim/_id_trim.dm b/code/datums/id_trim/_id_trim.dm index 562232214b3..a64b71e357f 100644 --- a/code/datums/id_trim/_id_trim.dm +++ b/code/datums/id_trim/_id_trim.dm @@ -29,6 +29,12 @@ ///If set, IDs with this trim will give wearers arrows of different colors when pointing var/pointer_color +/datum/id_trim/proc/find_job() + for (var/datum/job/job as anything in SSjob.all_occupations) + if (job.title == assignment) + return job + return null + /// Returns the SecHUD job icon state for whatever this object's ID card is, if it has one. /obj/item/proc/get_sechud_job_icon_state() var/obj/item/card/id/id_card = GetID() From 58f5a3a5b4a12c65f7b8f97acc3a621e154854b8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:05:49 +0000 Subject: [PATCH 103/142] Automatic changelog for PR #86711 [ci skip] --- html/changelogs/AutoChangeLog-pr-86711.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86711.yml diff --git a/html/changelogs/AutoChangeLog-pr-86711.yml b/html/changelogs/AutoChangeLog-pr-86711.yml new file mode 100644 index 00000000000..a5c105fc256 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86711.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Changing ID card's trim now properly adjusts linked bank account's job, allowing you to receive bounties for your new job" \ No newline at end of file From d3bff24afb924264c218530ed7bbf148ce9f91b7 Mon Sep 17 00:00:00 2001 From: Jay <19880843+googobbug@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:12:50 -0500 Subject: [PATCH 104/142] Fixes penlights not being able to look at peoples' eyes and mouth (#86702) ## About The Pull Request Currently, flashlights need a minimum light_power of 1 to be able to look at peoples' eyes and mouth. Penlights have a light_power of 0.8, so they don't work. This PR bumps the minimum light_power required down to 0.5 so penlights can be used to diagnose patients again. ## Why It's Good For The Game Items should function as intended ## Changelog :cl: Bumtickley00 fix: Penlights can once again be used to look at people's eyes and mouth. /:cl: Co-authored-by: Jay <19880843+AdmiralPancakes1@users.noreply.github.com> --- code/game/objects/items/devices/flashlight.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index e8242f2817f..5e59ee700c6 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -254,7 +254,7 @@ if(!scanning.get_bodypart(BODY_ZONE_HEAD)) to_chat(user, span_warning("[scanning] doesn't have a head!")) return - if(light_power < 1) + if(light_power < 0.5) to_chat(user, span_warning("[src] isn't bright enough to see anything!")) return From 8c109090e2e25ce4f1d3f9099076d9a16726ca5c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:13:15 +0000 Subject: [PATCH 105/142] Automatic changelog for PR #86702 [ci skip] --- html/changelogs/AutoChangeLog-pr-86702.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86702.yml diff --git a/html/changelogs/AutoChangeLog-pr-86702.yml b/html/changelogs/AutoChangeLog-pr-86702.yml new file mode 100644 index 00000000000..fc0918267b4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86702.yml @@ -0,0 +1,4 @@ +author: "Bumtickley00" +delete-after: True +changes: + - bugfix: "Penlights can once again be used to look at people's eyes and mouth." \ No newline at end of file From 9beedae48fb263d7122569d818f546cf2fa32b4e Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Tue, 17 Sep 2024 23:56:22 +0200 Subject: [PATCH 106/142] Fixing a runtime with examining fishing spots while wielding a rod (#86689) ## About The Pull Request Well, it seems examining a fishing spot (with sufficient skill) while wielding a rod is borked because of a bad line. It should be `init_name` and not `reward`. Thanks to vinylspider for informing me about it. ## Why It's Good For The Game Fixing stuff I made and then broke. ## Changelog :cl: fix: examining fishing spots while wielding a rod (with sufficient skill) now works. /:cl: --- code/modules/fishing/sources/_fish_source.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 35d14a5c734..51ff20db513 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -421,7 +421,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) if(weight/init_weight >= 3.5) init_name = "init_name" else if(weight < init_weight) - init_name = span_small(reward) + init_name = span_small(init_name) known_fishes += init_name if(!length(known_fishes)) From 1aa706d105580baed77971d1ad8ed23a9d06b999 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 21:56:46 +0000 Subject: [PATCH 107/142] Automatic changelog for PR #86689 [ci skip] --- html/changelogs/AutoChangeLog-pr-86689.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86689.yml diff --git a/html/changelogs/AutoChangeLog-pr-86689.yml b/html/changelogs/AutoChangeLog-pr-86689.yml new file mode 100644 index 00000000000..88e0de2b340 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86689.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "examining fishing spots while wielding a rod (with sufficient skill) now works." \ No newline at end of file From 2f150390b7958af7f61a33182f312bada1a5a829 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 18 Sep 2024 00:33:04 +0200 Subject: [PATCH 108/142] What you wear and on what chair you sit on can now influence fishing difficulty (#86646) ## About The Pull Request A foreword, I had to refactor a few bits of shitcode my past self added first. For context, the "gone fishing" and "actively fishing" traits only had one source, which is the fishing challenge itself, ad there was no way to access the challenge from outside its code, except for a few weakrefs which were being used as sources for the aforementioned traits (the shitcode in a nutshell). There were also a few signals that I didn't like because they were being sent to the harder-to-access challenge datum rather than the user. So I scrapped the traits for a couple signals to send to the user, then added a global list as a mean to easily access the challenge datum, and lastly changed the code to accomodate the titled feature (and allow the challenge to recalculate its difficulty DURING the minigame phase) Moving on to the actual feature: I've added a component that can be added to objects on which mobs can be buckled to or items. When equipped in the right slots or buckled to, the object will adjust the difficulty of current and future fishing challenges by a certain amount (more often than not positive, but there're many exceptions) as long as the object isn't equipped or the user is unbuckled. I've been having some fun adding component to a ton of clothes in the game as well as chairs. Way too many objects to enumerate, so I'll give you the general idea: - each carp-themed article provides a slight positive modifier (easier) - some (not all) doctor-related garbs provide a marginal positive modifier each (fish doctor jokes) - floortile camo clothes have positive modifiers - Tuxedo, laceups, gowns provide negative modifier (more difficult) - utility garbs such as bio/bomb/rad hoods and suits are quite bad. Riot armor too. - boxing gloves are very, very bad. Insulated gloves and haul gauntlets are also very bad, to a lesser degree. - **tackle** gloves are good. (pun intended) - wizard garbs are good, because wizards are good at casting. (also a pun) - magboots slightly bad. Space suits bad. - Blindfolds and welding protection are also bad. Gas masks marginally bad. - Pirate attire is nice to have. (I just vibed a little on this one) - plastic chairs are quite versatile because they can be carried around, but the mime chair is the best, followed by ratvarian chairs. - Fishing toolboxes, analyzers and the fish catalog are a plus, because they can be held. - And the fishing hat, obviously (not as great as you'd think) Some of these may be subject to change depending on what people say. ## Why It's Good For The Game A hundred lines of fishing challenge code made ever-so-slightly less awful, and a way to modify fishing diffculty beside skills and bait. ## Changelog :cl: add: Your current clothes and what chair you sit on can now influence the difficulty of fishing minigames. Having a bare minimum of fishing skill will let you distinguish which objects can help and which won't, so keep an eye out. Holding fishing toolboxes, fish analyzers or fish catalogs can also help. /:cl: # Conflicts: # code/modules/clothing/shoes/clown.dm # code/modules/clothing/suits/labcoat.dm --- code/__DEFINES/dcs/signals/signals_fish.dm | 10 +- code/__DEFINES/traits/declarations.dm | 5 - code/_globalvars/traits/_traits.dm | 2 - .../components/adjust_fishing_difficulty.dm | 111 ++++++++++++++++++ code/datums/components/fishing_spot.dm | 2 +- code/datums/components/profound_fisher.dm | 10 +- code/game/objects/items/storage/belt.dm | 1 + .../objects/structures/beds_chairs/chair.dm | 28 ++++- .../objects/structures/beds_chairs/sofa.dm | 1 + code/modules/clothing/ears/_ears.dm | 1 + code/modules/clothing/glasses/_glasses.dm | 31 ++++- code/modules/clothing/gloves/bone.dm | 4 + code/modules/clothing/gloves/botany.dm | 4 + code/modules/clothing/gloves/boxing.dm | 1 + code/modules/clothing/gloves/color.dm | 1 + code/modules/clothing/gloves/combat.dm | 8 ++ code/modules/clothing/gloves/insulated.dm | 14 +++ code/modules/clothing/gloves/punch_mitts.dm | 2 +- code/modules/clothing/gloves/special.dm | 42 +++++-- code/modules/clothing/gloves/tacklers.dm | 9 ++ code/modules/clothing/head/collectable.dm | 12 ++ code/modules/clothing/head/fedora.dm | 4 + code/modules/clothing/head/hardhat.dm | 4 + code/modules/clothing/head/helmet.dm | 12 ++ code/modules/clothing/head/jobs.dm | 8 ++ code/modules/clothing/head/moth.dm | 1 + code/modules/clothing/head/pirate.dm | 5 +- code/modules/clothing/head/soft_caps.dm | 1 + code/modules/clothing/head/welding.dm | 12 ++ code/modules/clothing/masks/animal_masks.dm | 36 ++++++ code/modules/clothing/masks/boxing.dm | 4 + code/modules/clothing/masks/gasmask.dm | 39 +++++- code/modules/clothing/masks/hailer.dm | 3 + code/modules/clothing/neck/_neck.dm | 4 + code/modules/clothing/shoes/boots.dm | 8 ++ code/modules/clothing/shoes/clown.dm | 3 +- code/modules/clothing/shoes/costume.dm | 2 + code/modules/clothing/shoes/galoshes.dm | 7 ++ code/modules/clothing/shoes/laceup.dm | 4 + code/modules/clothing/shoes/magboots.dm | 26 +++- .../clothing/spacesuits/_spacesuits.dm | 12 ++ code/modules/clothing/spacesuits/freedom.dm | 2 + code/modules/clothing/spacesuits/pirate.dm | 2 + code/modules/clothing/spacesuits/plasmamen.dm | 2 + code/modules/clothing/spacesuits/santa.dm | 2 + .../modules/clothing/spacesuits/specialops.dm | 2 + code/modules/clothing/suits/armor.dm | 12 ++ code/modules/clothing/suits/bio.dm | 5 + code/modules/clothing/suits/costume.dm | 28 +++++ code/modules/clothing/suits/ethereal.dm | 12 ++ code/modules/clothing/suits/ghostsheet.dm | 1 + code/modules/clothing/suits/jobs.dm | 8 ++ code/modules/clothing/suits/labcoat.dm | 10 +- code/modules/clothing/suits/moth.dm | 2 +- code/modules/clothing/suits/utility.dm | 11 ++ code/modules/clothing/suits/wiz_robe.dm | 19 +++ .../clothing/under/jobs/civilian/curator.dm | 4 + code/modules/clothing/under/jobs/medical.dm | 8 ++ code/modules/clothing/under/miscellaneous.dm | 4 + code/modules/clothing/under/skirt_dress.dm | 8 ++ code/modules/clothing/under/suits.dm | 8 ++ code/modules/clothing/under/syndicate.dm | 12 ++ .../modules/fishing/aquarium/fish_analyzer.dm | 2 +- code/modules/fishing/fish_catalog.dm | 4 + code/modules/fishing/fish_movement.dm | 10 ++ code/modules/fishing/fishing_equipment.dm | 4 + code/modules/fishing/fishing_minigame.dm | 74 ++++++++---- code/modules/fishing/fishing_rod.dm | 6 +- code/modules/fishing/sources/_fish_source.dm | 18 +-- code/modules/mod/modules/modules_general.dm | 11 +- .../code/modules/clothing/shoes/clown.dm | 5 + .../code/modules/clothing/suits/labcoat.dm | 6 + strings/fishing_tips.txt | 3 +- tgstation.dme | 2 + 74 files changed, 712 insertions(+), 89 deletions(-) create mode 100644 code/datums/components/adjust_fishing_difficulty.dm create mode 100644 modular_nova/master_files/code/modules/clothing/shoes/clown.dm diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index a3dc7ac91b2..45f90e9b9b2 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -36,14 +36,20 @@ ///From /obj/item/fish/interact_with_atom_secondary, sent to the target: (fish) #define COMSIG_FISH_RELEASED_INTO "fish_released_into" +///From /datum/fishing_challenge/New: (datum/fishing_challenge/challenge) +#define COMSIG_MOB_BEGIN_FISHING "mob_begin_fishing" +///From /datum/fishing_challenge/start_minigame_phase: (datum/fishing_challenge/challenge) +#define COMSIG_MOB_BEGIN_FISHING_MINIGAME "mob_begin_fishing_minigame" +///From /datum/fishing_challenge/completed: (datum/fishing_challenge/challenge, win) +#define COMSIG_MOB_COMPLETE_FISHING "mob_complete_fishing" + /// Rolling a reward path for a fishing challenge #define COMSIG_FISHING_CHALLENGE_ROLL_REWARD "fishing_roll_reward" /// Adjusting the difficulty of a rishing challenge, often based on the reward path #define COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY "fishing_get_difficulty" /// Fishing challenge completed -#define COMSIG_FISHING_CHALLENGE_COMPLETED "fishing_completed" /// Sent to the fisherman when the reward is dispensed: (reward) -#define COMSIG_FISH_SOURCE_REWARD_DISPENSED "mob_fish_source_reward_dispensed" +#define COMSIG_FISH_SOURCE_REWARD_DISPENSED "fish_source_reward_dispensed" /// Called when you try to use fishing rod on anything #define COMSIG_PRE_FISHING "pre_fishing" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index f34ea9ef740..4d6a39e64e1 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1135,11 +1135,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// this object has been frozen #define TRAIT_FROZEN "frozen" -/// Currently fishing -#define TRAIT_GONE_FISHING "fishing" -/// Currently fishing, and it's the active minigame phase -#define TRAIT_ACTIVELY_FISHING "actively_fishing" - /// Makes a character be better/worse at tackling depending on their wing's status #define TRAIT_TACKLING_WINGED_ATTACKER "tacking_winged_attacker" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 391ee415c08..7103c0d3d34 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -129,7 +129,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING, "TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST, "TRAIT_ACT_AS_HERETIC" = TRAIT_ACT_AS_HERETIC, - "TRAIT_ACTIVELY_FISHING" = TRAIT_ACTIVELY_FISHING, "TRAIT_ADAMANTINE_EXTRACT_ARMOR" = TRAIT_ADAMANTINE_EXTRACT_ARMOR, "TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER, "TRAIT_AGENDER" = TRAIT_AGENDER, @@ -265,7 +264,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_GENELESS" = TRAIT_GENELESS, "TRAIT_GIANT" = TRAIT_GIANT, "TRAIT_GODMODE" = TRAIT_GODMODE, - "TRAIT_GONE_FISHING" = TRAIT_GONE_FISHING, "TRAIT_GOOD_HEARING" = TRAIT_GOOD_HEARING, "TRAIT_GRABWEAKNESS" = TRAIT_GRABWEAKNESS, "TRAIT_GREENTEXT_CURSED" = TRAIT_GREENTEXT_CURSED, diff --git a/code/datums/components/adjust_fishing_difficulty.dm b/code/datums/components/adjust_fishing_difficulty.dm new file mode 100644 index 00000000000..abb7c768653 --- /dev/null +++ b/code/datums/components/adjust_fishing_difficulty.dm @@ -0,0 +1,111 @@ +///Influences the difficulty of the minigame when worn or if buckled to. +/datum/component/adjust_fishing_difficulty + ///The additive numerical modifier to the difficulty of the minigame + var/modifier + ///For items, in which slot it has to be worn to influence the difficulty of the minigame + var/slots + +/datum/component/adjust_fishing_difficulty/Initialize(modifier, slots = NONE) + if(!ismovable(parent) || !modifier) + return COMPONENT_INCOMPATIBLE + + if(!isitem(parent)) + var/atom/movable/movable_parent = parent + if(!movable_parent.can_buckle) + return COMPONENT_INCOMPATIBLE + + src.modifier = modifier + src.slots = slots + +/datum/component/adjust_fishing_difficulty/RegisterWithParent() + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_item_examine)) + else + RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, PROC_REF(on_buckle)) + RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, PROC_REF(on_unbuckle)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_buckle_examine)) + + update_check() + +/datum/component/adjust_fishing_difficulty/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_EXAMINE, + COMSIG_MOVABLE_BUCKLE, + COMSIG_MOVABLE_UNBUCKLE, + COMSIG_ITEM_EQUIPPED, + COMSIG_ITEM_DROPPED, + )) + + update_check(TRUE) + +/datum/component/adjust_fishing_difficulty/proc/update_check(removing = FALSE) + var/atom/movable/movable_parent = parent + for(var/mob/living/buckled_mob as anything in movable_parent.buckled_mobs) + update_user(buckled_mob, removing) + if(!isitem(movable_parent) || !isliving(movable_parent.loc)) + return + var/mob/living/holder = movable_parent.loc + var/obj/item/item = parent + if(holder.get_slot_by_item(movable_parent) & (slots || item.slot_flags)) + update_user(holder, removing) + +/datum/component/adjust_fishing_difficulty/proc/on_item_examine(obj/item/item, mob/user, list/examine_text) + SIGNAL_HANDLER + if(!HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH)) + return + var/method = "[(slots || item.slot_flags) & ITEM_SLOT_HANDS ? "Holding" : "Wearing"] [item.p_them()]" + add_examine_line(user, examine_text, method) + +/datum/component/adjust_fishing_difficulty/proc/on_buckle_examine(atom/movable/source, mob/user, list/examine_text) + SIGNAL_HANDLER + if(!HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH)) + return + var/percent = HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH) ? "[modifier]% " : "" + add_examine_line(user, examine_text, "Buckling to [source.p_them()]") + +/datum/component/adjust_fishing_difficulty/proc/add_examine_line(mob/user, list/examine_text, method) + var/percent = HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH) ? "[modifier]% " : "" + var/text = "[method] will make fishing [percent][modifier > 0 ? "easier" : "harder"]." + if(modifier > 0) + examine_text += span_nicegreen(text) + else + examine_text += span_danger(text) + +/datum/component/adjust_fishing_difficulty/proc/on_buckle(atom/movable/source, mob/living/buckled_mob, forced) + SIGNAL_HANDLER + update_user(buckled_mob) + +/datum/component/adjust_fishing_difficulty/proc/on_unbuckle(atom/movable/source, mob/living/buckled_mob, forced) + SIGNAL_HANDLER + update_user(buckled_mob, TRUE) + +/datum/component/adjust_fishing_difficulty/proc/on_equipped(obj/item/source, mob/living/wearer, slot) + SIGNAL_HANDLER + if(slot & (slots || source.slot_flags)) + update_user(wearer) + +/datum/component/adjust_fishing_difficulty/proc/on_dropped(obj/item/source, mob/living/dropper) + SIGNAL_HANDLER + update_user(dropper, TRUE) + +/datum/component/adjust_fishing_difficulty/proc/update_user(mob/living/user, removing = FALSE) + var/datum/fishing_challenge/challenge = GLOB.fishing_challenges_by_user[user] + if(removing) + UnregisterSignal(user, COMSIG_MOB_BEGIN_FISHING) + if(challenge) + UnregisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY) + else + RegisterSignal(user, COMSIG_MOB_BEGIN_FISHING, PROC_REF(on_minigame_started)) + if(challenge) + RegisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, PROC_REF(adjust_difficulty)) + challenge?.update_difficulty() + +/datum/component/adjust_fishing_difficulty/proc/on_minigame_started(mob/living/source, datum/fishing_challenge/challenge) + SIGNAL_HANDLER + RegisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, PROC_REF(adjust_difficulty), TRUE) + +/datum/component/adjust_fishing_difficulty/proc/adjust_difficulty(datum/fishing_challenge/challenge, reward_path, obj/item/fishing_rod/rod, mob/living/user, list/holder) + SIGNAL_HANDLER + holder[1] += modifier diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 659eaff8550..5f0fd143444 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -63,7 +63,7 @@ var/obj/item/fishing_rod/rod = possibly_rod if(!istype(rod)) return - if(HAS_TRAIT(user,TRAIT_GONE_FISHING) || rod.fishing_line) + if(GLOB.fishing_challenges_by_user[user] || rod.fishing_line) user.balloon_alert(user, "already fishing") return COMPONENT_NO_AFTERATTACK var/denial_reason = fish_source.reason_we_cant_fish(rod, user, parent) diff --git a/code/datums/components/profound_fisher.dm b/code/datums/components/profound_fisher.dm index 6f656cd2542..61f6543bd12 100644 --- a/code/datums/components/profound_fisher.dm +++ b/code/datums/components/profound_fisher.dm @@ -84,26 +84,26 @@ return COMPONENT_HOSTILE_NO_ATTACK /datum/component/profound_fisher/proc/should_fish_on(mob/living/user, atom/target) - if(!HAS_TRAIT(target, TRAIT_FISHING_SPOT) || HAS_TRAIT(user, TRAIT_GONE_FISHING)) + if(!HAS_TRAIT(target, TRAIT_FISHING_SPOT) || GLOB.fishing_challenges_by_user[user]) return FALSE if(user.combat_mode || !user.CanReach(target)) return FALSE return TRUE /datum/component/profound_fisher/proc/begin_fishing(mob/living/user, atom/target) - RegisterSignal(user, SIGNAL_ADDTRAIT(TRAIT_GONE_FISHING), PROC_REF(actually_fishing_with_internal_rod)) + RegisterSignal(user, COMSIG_MOB_BEGIN_FISHING, PROC_REF(actually_fishing_with_internal_rod)) our_rod.melee_attack_chain(user, target) - UnregisterSignal(user, SIGNAL_ADDTRAIT(TRAIT_GONE_FISHING)) + UnregisterSignal(user, COMSIG_MOB_BEGIN_FISHING) /datum/component/profound_fisher/proc/actually_fishing_with_internal_rod(datum/source) SIGNAL_HANDLER ADD_TRAIT(source, TRAIT_PROFOUND_FISHER, REF(parent)) - RegisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING), PROC_REF(remove_profound_fisher)) + RegisterSignal(source, COMSIG_MOB_COMPLETE_FISHING, PROC_REF(remove_profound_fisher)) /datum/component/profound_fisher/proc/remove_profound_fisher(datum/source) SIGNAL_HANDLER REMOVE_TRAIT(source, TRAIT_PROFOUND_FISHER, TRAIT_GENERIC) - UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING)) + UnregisterSignal(source, COMSIG_MOB_COMPLETE_FISHING) /datum/component/profound_fisher/proc/pretend_fish(mob/living/source, atom/target) if(DOING_INTERACTION_WITH_TARGET(source, target)) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 4ffad149053..4e0d514e493 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -523,6 +523,7 @@ . = ..() atom_storage.max_slots = 1 atom_storage.set_holdable(/obj/item/clothing/mask/luchador) + AddComponent(/datum/component/adjust_fishing_difficulty, -2) /obj/item/storage/belt/military name = "chest rig" diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 57ae5e7adf6..2a2620689ac 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -16,7 +16,17 @@ var/buildstacktype = /obj/item/stack/sheet/iron var/buildstackamount = 1 var/item_chair = /obj/item/chair // if null it can't be picked up + ///How much sitting on this chair influences fishing difficulty + var/fishing_modifier = -3 +/obj/structure/chair/Initialize(mapload) + . = ..() + if(prob(0.2)) + name = "tactical [name]" + fishing_modifier -= 4 + MakeRotate() + if(can_buckle && fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) /obj/structure/chair/examine(mob/user) . = ..() @@ -24,12 +34,6 @@ if(!has_buckled_mobs() && can_buckle) . += span_notice("While standing on [src], drag and drop your sprite onto [src] to buckle to it.") -/obj/structure/chair/Initialize(mapload) - . = ..() - if(prob(0.2)) - name = "tactical [name]" - MakeRotate() - ///This proc adds the rotate component, overwrite this if you for some reason want to change some specific args. /obj/structure/chair/proc/MakeRotate() AddComponent(/datum/component/simple_rotation, ROTATION_IGNORE_ANCHORED|ROTATION_GHOSTS_ALLOWED) @@ -139,6 +143,7 @@ buildstacktype = /obj/item/stack/sheet/mineral/wood buildstackamount = 3 item_chair = /obj/item/chair/wood + fishing_modifier = -4 /obj/structure/chair/wood/narsie_act() return @@ -156,6 +161,7 @@ max_integrity = 70 buildstackamount = 2 item_chair = null + fishing_modifier = -5 // The mutable appearance used for the overlay over buckled mobs. var/mutable_appearance/armrest @@ -231,11 +237,13 @@ desc = "A luxurious chair, the many purple scales reflect the light in a most pleasing manner." icon_state = "carp_chair" buildstacktype = /obj/item/stack/sheet/animalhide/carp + fishing_modifier = -10 /obj/structure/chair/office anchored = FALSE buildstackamount = 5 item_chair = null + fishing_modifier = -4 icon_state = "officechair_dark" /obj/structure/chair/office/Initialize(mapload) @@ -250,6 +258,10 @@ /obj/structure/chair/office/tactical name = "tactical swivel chair" +/obj/structure/chair/office/tactical/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -10) + /obj/structure/chair/office/light icon_state = "officechair_white" @@ -441,6 +453,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) desc = "You sit in this. Either by will or force. Looks REALLY uncomfortable." icon_state = "chairold" item_chair = null + fishing_modifier = 4 /obj/structure/chair/bronze name = "brass chair" @@ -450,6 +463,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) buildstacktype = /obj/item/stack/sheet/bronze buildstackamount = 1 item_chair = null + fishing_modifier = -12 //the pinnacle of Ratvarian technology. /// Total rotations made var/turns = 0 @@ -489,6 +503,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) item_chair = null obj_flags = parent_type::obj_flags | NO_DEBRIS_AFTER_DECONSTRUCTION alpha = 0 + fishing_modifier = -20 //it only lives for 25 seconds, so we make them worth it. /obj/structure/chair/mime/wrench_act_secondary(mob/living/user, obj/item/weapon) return NONE @@ -510,6 +525,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) buildstacktype = /obj/item/stack/sheet/plastic buildstackamount = 2 item_chair = /obj/item/chair/plastic + fishing_modifier = -8 /obj/structure/chair/plastic/post_buckle_mob(mob/living/Mob) Mob.pixel_y += 2 diff --git a/code/game/objects/structures/beds_chairs/sofa.dm b/code/game/objects/structures/beds_chairs/sofa.dm index bf9a221929b..04bb0b1e25e 100644 --- a/code/game/objects/structures/beds_chairs/sofa.dm +++ b/code/game/objects/structures/beds_chairs/sofa.dm @@ -19,6 +19,7 @@ path/corner/color_name {\ icon = 'icons/obj/chairs_wide.dmi' buildstackamount = 1 item_chair = null + fishing_modifier = -4 var/mutable_appearance/armrest /obj/structure/chair/sofa/Initialize(mapload) diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index 5ae5b628808..bdc294f5366 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -26,3 +26,4 @@ . = ..() AddElement(/datum/element/earhealing) AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_EARS)) + AddComponent(/datum/component/adjust_fishing_difficulty, -1) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index c1d4cf0fc84..e5b5170b9ff 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -344,6 +344,7 @@ /obj/item/clothing/glasses/sunglasses/Initialize(mapload) . = ..() add_glasses_slapcraft_component() + AddComponent(/datum/component/adjust_fishing_difficulty, -1) /obj/item/clothing/glasses/sunglasses/proc/add_glasses_slapcraft_component() var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/hudsunsec, /datum/crafting_recipe/hudsunmed, /datum/crafting_recipe/hudsundiag, /datum/crafting_recipe/scienceglasses) @@ -445,9 +446,21 @@ glass_colour_type = /datum/client_colour/glass_colour/gray alternate_worn_layer = ABOVE_BODY_FRONT_HEAD_LAYER // NOVA EDIT - Just so it works until I make the change upstream -/obj/item/clothing/glasses/welding/attack_self(mob/user) +/obj/item/clothing/glasses/welding/Initialize(mapload) + . = ..() + if(!up) + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + +/obj/item/clothing/glasses/welding/attack_self(mob/living/user) adjust_visor(user) +/obj/item/clothing/glasses/welding/adjust_visor(mob/user) + . = ..() + if(up) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) + else + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + /obj/item/clothing/glasses/welding/update_icon_state() . = ..() icon_state = "[initial(icon_state)][up ? "up" : ""]" @@ -466,6 +479,10 @@ tint = INFINITY // You WILL Be blind, no matter what dog_fashion = /datum/dog_fashion/head +/obj/item/clothing/glasses/blindfold/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + /obj/item/clothing/glasses/trickblindfold name = "blindfold" desc = "A see-through blindfold perfect for cheating at games like pin the stun baton on the clown." @@ -503,6 +520,10 @@ flags_cover = GLASSESCOVERSEYES glass_colour_type = /datum/client_colour/glass_colour/red +/obj/item/clothing/glasses/thermal/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) + /obj/item/clothing/glasses/thermal/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) @@ -621,6 +642,10 @@ var/list/hudlist = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_SECURITY_ADVANCED, DATA_HUD_BOT_PATH) var/xray = FALSE +/obj/item/clothing/glasses/debug/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -15) + /obj/item/clothing/glasses/debug/equipped(mob/user, slot) . = ..() if(!(slot & ITEM_SLOT_EYES)) @@ -707,6 +732,10 @@ /// Hallucination datum currently being used for seeing mares var/datum/hallucination/stored_hallucination +/obj/item/clothing/glasses/nightmare_vision/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 13) + /obj/item/clothing/glasses/nightmare_vision/Destroy() QDEL_NULL(stored_hallucination) return ..() diff --git a/code/modules/clothing/gloves/bone.dm b/code/modules/clothing/gloves/bone.dm index 2c75e642ff6..761057054f9 100644 --- a/code/modules/clothing/gloves/bone.dm +++ b/code/modules/clothing/gloves/bone.dm @@ -12,6 +12,10 @@ resistance_flags = NONE armor_type = /datum/armor/gloves_bracer +/obj/item/clothing/gloves/bracer/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) + /datum/armor/gloves_bracer melee = 15 bullet = 25 diff --git a/code/modules/clothing/gloves/botany.dm b/code/modules/clothing/gloves/botany.dm index af94a6b7bb1..144477240b2 100644 --- a/code/modules/clothing/gloves/botany.dm +++ b/code/modules/clothing/gloves/botany.dm @@ -12,6 +12,10 @@ clothing_traits = list(TRAIT_PLANT_SAFE) armor_type = /datum/armor/gloves_botanic_leather +/obj/item/clothing/gloves/botanic_leather/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /datum/armor/gloves_botanic_leather bio = 50 fire = 70 diff --git a/code/modules/clothing/gloves/boxing.dm b/code/modules/clothing/gloves/boxing.dm index 021d895f69c..ab6e03ae493 100644 --- a/code/modules/clothing/gloves/boxing.dm +++ b/code/modules/clothing/gloves/boxing.dm @@ -19,6 +19,7 @@ ) AddComponent(/datum/component/martial_art_giver, style_to_give) + AddComponent(/datum/component/adjust_fishing_difficulty, 19) /obj/item/clothing/gloves/boxing/evil name = "evil boxing gloves" diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index cf2c2f333ba..c3b400d7c59 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -61,6 +61,7 @@ /obj/item/clothing/gloves/color/fingerless/Initialize(mapload) . = ..() var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/gripperoffbrand) + AddComponent(/datum/component/adjust_fishing_difficulty, -2) AddElement( /datum/element/slapcrafting,\ diff --git a/code/modules/clothing/gloves/combat.dm b/code/modules/clothing/gloves/combat.dm index efc5bd40b05..a2574c8d23e 100644 --- a/code/modules/clothing/gloves/combat.dm +++ b/code/modules/clothing/gloves/combat.dm @@ -25,8 +25,16 @@ greyscale_colors = null inhand_icon_state = null +/obj/item/clothing/gloves/combat/wizard/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) //something something wizard casting + /obj/item/clothing/gloves/combat/floortile name = "floortile camouflage gloves" desc = "Is it just me or is there a pair of gloves on the floor?" icon_state = "ftc_gloves" inhand_icon_state = "greyscale_gloves" + +/obj/item/clothing/gloves/combat/floortiletile/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) //tacticool diff --git a/code/modules/clothing/gloves/insulated.dm b/code/modules/clothing/gloves/insulated.dm index 19109d68b9c..b04637d4c52 100644 --- a/code/modules/clothing/gloves/insulated.dm +++ b/code/modules/clothing/gloves/insulated.dm @@ -15,13 +15,19 @@ cut_type = /obj/item/clothing/gloves/cut clothing_traits = list(TRAIT_CHUNKYFINGERS) +/obj/item/clothing/gloves/color/yellow/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 10) + /obj/item/clothing/gloves/color/yellow/apply_fantasy_bonuses(bonus) . = ..() if(bonus >= 10) detach_clothing_traits(TRAIT_CHUNKYFINGERS) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) /obj/item/clothing/gloves/color/yellow/remove_fantasy_bonuses(bonus) attach_clothing_traits(TRAIT_CHUNKYFINGERS) + AddComponent(/datum/component/adjust_fishing_difficulty, 10) return ..() /datum/armor/color_yellow @@ -116,6 +122,10 @@ greyscale_colors = null clothing_traits = list(TRAIT_FINGERPRINT_PASSTHROUGH) +/obj/item/clothing/gloves/cut/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/gloves/cut/heirloom desc = "The old gloves your great grandfather stole from Engineering, many moons ago. They've seen some tough times recently." @@ -131,3 +141,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE + +/obj/item/clothing/gloves/chief_engineer/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) diff --git a/code/modules/clothing/gloves/punch_mitts.dm b/code/modules/clothing/gloves/punch_mitts.dm index 07d93d5ab02..96848731a9c 100644 --- a/code/modules/clothing/gloves/punch_mitts.dm +++ b/code/modules/clothing/gloves/punch_mitts.dm @@ -11,7 +11,7 @@ /obj/item/clothing/gloves/fingerless/punch_mitts/Initialize(mapload) . = ..() - + AddComponent(/datum/component/adjust_fishing_difficulty, -4) AddComponent(/datum/component/martial_art_giver, /datum/martial_art/boxing/hunter) /datum/armor/gloves_mitts diff --git a/code/modules/clothing/gloves/special.dm b/code/modules/clothing/gloves/special.dm index b5c16ba4dc5..3e18a4ed2ad 100644 --- a/code/modules/clothing/gloves/special.dm +++ b/code/modules/clothing/gloves/special.dm @@ -14,6 +14,7 @@ . = ..() RegisterSignal(src, COMSIG_ITEM_EQUIPPED, PROC_REF(on_glove_equip)) RegisterSignal(src, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_glove_unequip)) + AddComponent(/datum/component/adjust_fishing_difficulty, 19) /// Called when the glove is equipped. Adds a component to the equipper and stores a weak reference to it. /obj/item/clothing/gloves/cargo_gauntlet/proc/on_glove_equip(datum/source, mob/equipper, slot) @@ -59,6 +60,7 @@ /obj/item/clothing/gloves/rapid/Initialize(mapload) . = ..() AddComponent(/datum/component/wearertargeting/punchcooldown) + AddComponent(/datum/component/adjust_fishing_difficulty, -7) /obj/item/clothing/gloves/radio name = "translation gloves" @@ -74,6 +76,10 @@ icon_state = "black" greyscale_colors = "#2f2e31" +/obj/item/clothing/gloves/race/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -7) + /obj/item/clothing/gloves/captain desc = "Regal blue gloves, with a nice gold trim, a diamond anti-shock coating, and an integrated thermal barrier. Swanky." name = "captain's gloves" @@ -90,6 +96,10 @@ resistance_flags = NONE clothing_traits = list(TRAIT_FAST_CUFFING) +/obj/item/clothing/gloves/captain/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) + /datum/armor/captain_gloves bio = 90 fire = 70 @@ -117,6 +127,10 @@ greyscale_colors = "#99eeff" clothing_traits = list(TRAIT_QUICKER_CARRY, TRAIT_FASTMED) +/obj/item/clothing/gloves/latex/nitrile/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) + /obj/item/clothing/gloves/latex/coroner name = "coroner's gloves" desc = "Black gloves made from latex with a superhydrophobic coating. Useful for picking bodies up instead of dragging blood behind." @@ -156,42 +170,50 @@ clothing_traits = list(TRAIT_QUICKER_CARRY, TRAIT_CHUNKYFINGERS) clothing_flags = THICKMATERIAL +/obj/item/clothing/gloves/atmos/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 6) + ///A pair of gloves that both allow the user to fish without the need of a held fishing rod and provides athletics experience. /obj/item/clothing/gloves/fishing name = "athletic fishing gloves" desc = "A pair of gloves to fish without a fishing rod but your raw athletics strength. It doubles as a good workout device. WARNING: May cause injuries when catching bigger fish." icon_state = "fishing_gloves" + ///The current fishing minigame datum the wearer is engaged in. + var/datum/fishing_challenge/challenge /obj/item/clothing/gloves/fishing/Initialize(mapload) . = ..() AddComponent(/datum/component/profound_fisher, new /obj/item/fishing_rod/mob_fisher/athletic(src)) + AddComponent(/datum/component/adjust_fishing_difficulty, -3) //on top of the extra that you get from the athletics skill. /obj/item/clothing/gloves/fishing/equipped(mob/user, slot) . = ..() if(slot == ITEM_SLOT_GLOVES) - RegisterSignal(user, SIGNAL_ADDTRAIT(TRAIT_ACTIVELY_FISHING), PROC_REF(begin_workout)) + RegisterSignal(user, COMSIG_MOB_BEGIN_FISHING_MINIGAME, PROC_REF(begin_workout)) /obj/item/clothing/gloves/fishing/dropped(mob/user) - UnregisterSignal(user, list(SIGNAL_ADDTRAIT(TRAIT_ACTIVELY_FISHING), SIGNAL_REMOVETRAIT(TRAIT_ACTIVELY_FISHING))) - STOP_PROCESSING(SSprocessing, src) + UnregisterSignal(user, COMSIG_MOB_BEGIN_FISHING_MINIGAME) + if(challenge) + stop_workout(user) return ..() -/obj/item/clothing/gloves/fishing/proc/begin_workout(datum/source) +/obj/item/clothing/gloves/fishing/proc/begin_workout(datum/source, datum/fishing_challenge/challenge) SIGNAL_HANDLER - RegisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_ACTIVELY_FISHING), PROC_REF(stop_workout)) + RegisterSignal(source, COMSIG_MOB_COMPLETE_FISHING, PROC_REF(stop_workout)) if(HAS_TRAIT(source, TRAIT_PROFOUND_FISHER)) //Only begin working out if we're fishing with these gloves and not some other fishing rod.. START_PROCESSING(SSprocessing, src) + src.challenge = challenge /obj/item/clothing/gloves/fishing/proc/stop_workout(datum/source) SIGNAL_HANDLER - UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_ACTIVELY_FISHING)) + UnregisterSignal(source, COMSIG_MOB_COMPLETE_FISHING) + challenge = null STOP_PROCESSING(SSprocessing, src) /obj/item/clothing/gloves/fishing/process(seconds_per_tick) var/mob/living/wearer = loc - var/list/trait_source = GET_TRAIT_SOURCES(wearer, TRAIT_ACTIVELY_FISHING) - var/datum/fishing_challenge/challenge = trait_source[1] - var/stamina_exhaustion = 2.5 + challenge.difficulty * 0.025 + var/stamina_exhaustion = 2 + challenge.difficulty * 0.02 var/is_heavy_gravity = wearer.has_gravity() > STANDARD_GRAVITY var/obj/item/organ/internal/cyberimp/chest/spine/potential_spine = wearer.get_organ_slot(ORGAN_SLOT_SPINE) if(istype(potential_spine)) @@ -227,7 +249,7 @@ return list() /obj/item/fishing_rod/mob_fisher/athletic/hook_hit(atom/atom_hit_by_hook_projectile, mob/user) - difficulty_modifier = -3 * user.mind?.get_skill_level(/datum/skill/athletics) + difficulty_modifier = -3 * (user.mind?.get_skill_level(/datum/skill/athletics) - 1) return ..() /obj/item/fishing_rod/mob_fisher/athletic/proc/noodling_is_dangerous(datum/source, atom/movable/reward, mob/living/user) diff --git a/code/modules/clothing/gloves/tacklers.dm b/code/modules/clothing/gloves/tacklers.dm index bbe7f5dba18..d45fa8d0a90 100644 --- a/code/modules/clothing/gloves/tacklers.dm +++ b/code/modules/clothing/gloves/tacklers.dm @@ -22,6 +22,12 @@ var/tackle_speed = 1 /// See: [/datum/component/tackler/var/skill_mod] var/skill_mod = 1 + ///How much these gloves affect fishing difficulty + var/fishing_modifier = -5 + +/obj/item/clothing/gloves/tackler/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) //fishing tackle equipment (ba dum tsh) /obj/item/clothing/gloves/tackler/Destroy() tackler = null @@ -55,6 +61,7 @@ tackle_speed = 2 min_distance = 2 skill_mod = -2 + fishing_modifier = -8 /obj/item/clothing/gloves/tackler/combat name = "gorilla gloves" @@ -106,9 +113,11 @@ base_knockdown = 1.75 SECONDS min_distance = 2 skill_mod = -1 + fishing_modifier = -3 /obj/item/clothing/gloves/tackler/football name = "football gloves" desc = "Gloves for football players! Teaches them how to tackle like a pro." icon_state = "tackle_gloves" inhand_icon_state = null + fishing_modifier = -3 diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 3cd88ffc8ed..9f7d01506f1 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -107,6 +107,10 @@ inhand_icon_state = null dog_fashion = /datum/dog_fashion/head/pirate +/obj/item/clothing/head/collectable/pirate/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/head/collectable/kitty name = "collectable kitty ears" desc = "The fur feels... a bit too realistic." @@ -129,6 +133,10 @@ icon_state = "wizard" dog_fashion = /datum/dog_fashion/head/blue_wizard +/obj/item/clothing/head/collectable/wizard/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -1) + /obj/item/clothing/head/collectable/hardhat name = "collectable hard hat" desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!" @@ -173,3 +181,7 @@ inhand_icon_state = "swatsyndie_helmet" clothing_flags = SNUG_FIT flags_inv = HIDEHAIR + +/obj/item/clothing/head/collectable/swat/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) diff --git a/code/modules/clothing/head/fedora.dm b/code/modules/clothing/head/fedora.dm index cf0d23ac37f..7bf295f7455 100644 --- a/code/modules/clothing/head/fedora.dm +++ b/code/modules/clothing/head/fedora.dm @@ -36,6 +36,10 @@ icon_state = "fedora_carpskin" inhand_icon_state = null +/obj/item/clothing/head/fedora/carpskin/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) + /obj/item/clothing/head/fedora/beige/press name = "press fedora" desc = "An beige fedora with a piece of paper saying \"PRESS\" stuck in its rim." diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 453ef782397..d1ab5124be4 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -238,6 +238,10 @@ dog_fashion = /datum/dog_fashion/head/pumpkin/unlit clothing_traits = list() +/obj/item/clothing/head/utility/hardhat/pumpkinhead/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 3) + /obj/item/clothing/head/utility/hardhat/pumpkinhead/set_light_on(new_value) . = ..() if(isnull(.)) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 2874a27b72b..b9b371d498c 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -201,6 +201,10 @@ visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED) +/obj/item/clothing/head/helmet/toggleable/riot/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) + /datum/armor/toggleable_riot melee = 50 bullet = 10 @@ -280,6 +284,10 @@ dog_fashion = null clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED) +/obj/item/clothing/head/helmet/swat/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 3) + /datum/armor/helmet_swat melee = 40 bullet = 30 @@ -429,6 +437,10 @@ dog_fashion = null clothing_traits = list(TRAIT_HEAD_INJURY_BLOCKED) +/obj/item/clothing/head/helmet/knight/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 3) + /datum/armor/helmet_knight melee = 50 bullet = 10 diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 5d5fc87d409..7b67cda761f 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -624,6 +624,10 @@ flags_inv = HIDEHAIR //Cover your head doctor! w_class = WEIGHT_CLASS_SMALL //surgery cap can be easily crumpled +/obj/item/clothing/head/utility/surgerycap/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /obj/item/clothing/head/utility/surgerycap/attack_self(mob/user) . = ..() if(.) @@ -666,6 +670,10 @@ icon_state = "headmirror" body_parts_covered = NONE +/obj/item/clothing/head/utility/head_mirror/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /obj/item/clothing/head/utility/head_mirror/examine(mob/user) . = ..() . += span_notice("In a properly lit room, you can use this to examine people's eyes, ears, and mouth closer.") diff --git a/code/modules/clothing/head/moth.dm b/code/modules/clothing/head/moth.dm index 324acaa13eb..abce11336f2 100644 --- a/code/modules/clothing/head/moth.dm +++ b/code/modules/clothing/head/moth.dm @@ -15,6 +15,7 @@ /obj/item/clothing/head/mothcap/original/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = 1.2, zoom_method = ZOOM_METHOD_ITEM_ACTION, item_action_type = /datum/action/item_action/hands_free/moth_googles) + AddComponent(/datum/component/adjust_fishing_difficulty, -2) /obj/item/clothing/head/mothcap/original/item_action_slot_check(slot, mob/user, datum/action/action) return (slot & ITEM_SLOT_HEAD) diff --git a/code/modules/clothing/head/pirate.dm b/code/modules/clothing/head/pirate.dm index 818478ccb7d..6d5d0a67f30 100644 --- a/code/modules/clothing/head/pirate.dm +++ b/code/modules/clothing/head/pirate.dm @@ -5,8 +5,9 @@ inhand_icon_state = null dog_fashion = /datum/dog_fashion/head/pirate -/obj/item/clothing/head/costume/pirate - var/datum/language/piratespeak/L = new +/obj/item/clothing/head/costume/pirate/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) /obj/item/clothing/head/costume/pirate/equipped(mob/user, slot) . = ..() diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index f8e7e80532f..62930574031 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -175,6 +175,7 @@ . = ..() AddComponent(/datum/component/speechmod, replacements = strings("crustacean_replacement.json", "crustacean")) //you asked for this. AddElement(/datum/element/skill_reward, /datum/skill/fishing) + AddComponent(/datum/component/adjust_fishing_difficulty, -4) #define PROPHAT_MOOD "prophat" diff --git a/code/modules/clothing/head/welding.dm b/code/modules/clothing/head/welding.dm index e3f014875dd..000448fd725 100644 --- a/code/modules/clothing/head/welding.dm +++ b/code/modules/clothing/head/welding.dm @@ -18,6 +18,11 @@ resistance_flags = FIRE_PROOF clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT +/obj/item/clothing/head/utility/welding/Initialize(mapload) + . = ..() + if(!up) + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + /datum/armor/utility_welding melee = 10 fire = 100 @@ -26,6 +31,13 @@ /obj/item/clothing/head/utility/welding/attack_self(mob/user) adjust_visor(user) +/obj/item/clothing/head/utility/welding/adjust_visor(mob/user) + . = ..() + if(up) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) + else + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + /obj/item/clothing/head/utility/welding/update_icon_state() . = ..() icon_state = "[initial(icon_state)][up ? "up" : ""]" diff --git a/code/modules/clothing/masks/animal_masks.dm b/code/modules/clothing/masks/animal_masks.dm index 05e5888168e..7b29519e12b 100644 --- a/code/modules/clothing/masks/animal_masks.dm +++ b/code/modules/clothing/masks/animal_masks.dm @@ -150,6 +150,18 @@ GLOBAL_LIST_INIT(cursed_animal_masks, list( animal_sounds_alt = list("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!") flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT +/obj/item/clothing/mask/animal/frog/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, cursed ? 2 : -2) + +/obj/item/clothing/mask/animal/frog/make_cursed() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) + +/obj/item/clothing/mask/animal/frog/clear_curse() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /obj/item/clothing/mask/animal/frog/cursed cursed = TRUE @@ -227,6 +239,18 @@ GLOBAL_LIST_INIT(cursed_animal_masks, list( inhand_icon_state = null animal_sounds = list("RAWR!","Rawr!","GRR!","Growl!") +/obj/item/clothing/mask/animal/small/bear/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, cursed ? 2 : -2) + +/obj/item/clothing/mask/animal/small/bear/make_cursed() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) + +/obj/item/clothing/mask/animal/small/bear/clear_curse() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /obj/item/clothing/mask/animal/small/bear/cursed cursed = TRUE @@ -275,5 +299,17 @@ GLOBAL_LIST_INIT(cursed_animal_masks, list( animal_sounds_alt = list("Eekum-bokum!", "Oomenacka!", "In mah head..... Zombi.... Zombi!") animal_sounds_alt_probability = 5 +/obj/item/clothing/mask/animal/small/tribal/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, cursed ? 4 : -4) + +/obj/item/clothing/mask/animal/small/tribal/make_cursed() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 4) + +/obj/item/clothing/mask/animal/small/tribal/clear_curse() + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) + /obj/item/clothing/mask/animal/small/tribal/cursed //adminspawn only. cursed = TRUE diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 2e75cebf5d9..46ad60e58de 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -24,6 +24,10 @@ w_class = WEIGHT_CLASS_SMALL actions_types = list(/datum/action/item_action/adjust) +/obj/item/clothing/mask/floortilebalaclava/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) //tacticool + /obj/item/clothing/mask/floortilebalaclava/attack_self(mob/user) adjust_visor(user) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index a88ec39a9d2..0ef2f19792b 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( armor_type = /datum/armor/mask_gas flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH | PEPPERPROOF resistance_flags = NONE + voice_filter = "lowpass=f=750,volume=2" ///Max numbers of installable filters var/max_filters = 1 ///List to keep track of each filter @@ -28,19 +29,19 @@ GLOBAL_LIST_INIT(clown_mask_options, list( var/has_fov = TRUE ///Cigarette in the mask var/obj/item/cigarette/cig - voice_filter = "lowpass=f=750,volume=2" + ///How much does this mask affect fishing difficulty + var/fishing_modifier = 2 /datum/armor/mask_gas bio = 100 -/obj/item/clothing/mask/gas/worn_overlays(mutable_appearance/standing, isinhands) - . = ..() - if(!isinhands && cig) - . += cig.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi') - /obj/item/clothing/mask/gas/Initialize(mapload) . = ..() init_fov() + + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) + if(!max_filters || !starting_filter_type) return @@ -49,6 +50,11 @@ GLOBAL_LIST_INIT(clown_mask_options, list( LAZYADD(gas_filters, inserted_filter) has_filter = TRUE +/obj/item/clothing/mask/gas/worn_overlays(mutable_appearance/standing, isinhands) + . = ..() + if(!isinhands && cig) + . += cig.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi') + /obj/item/clothing/mask/gas/Destroy() QDEL_LAZYLIST(gas_filters) return..() @@ -222,6 +228,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT resistance_flags = FIRE_PROOF clothing_flags = parent_type::clothing_flags | INTERNALS_ADJUST_EXEMPT + fishing_modifier = 8 /datum/armor/gas_welding melee = 10 @@ -236,6 +243,12 @@ GLOBAL_LIST_INIT(clown_mask_options, list( . = ..() if(.) playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) + if(!fishing_modifier) + return + if(up) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) + else + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) /obj/item/clothing/mask/gas/welding/update_icon_state() . = ..() @@ -266,6 +279,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( strip_delay = 60 w_class = WEIGHT_CLASS_SMALL has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" @@ -285,6 +299,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( has_fov = FALSE var/list/clownmask_designs = list() voice_filter = null // performer masks expect to be talked through + fishing_modifier = 0 /obj/item/clothing/mask/gas/clown_hat/plasmaman starting_filter_type = /obj/item/gas_filter/plasmaman @@ -327,6 +342,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/mime name = "mime mask" @@ -340,6 +356,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( actions_types = list(/datum/action/item_action/adjust) species_exception = list(/datum/species/golem) has_fov = FALSE + fishing_modifier = 0 var/list/mimemask_designs = list() /obj/item/clothing/mask/gas/mime/plasmaman @@ -398,6 +415,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/sexymime name = "sexy mime mask" @@ -409,6 +427,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FLAMMABLE species_exception = list(/datum/species/golem) has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/cyborg name = "cyborg visor" @@ -417,6 +436,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FLAMMABLE has_fov = FALSE flags_cover = MASKCOVERSEYES + fishing_modifier = 0 /obj/item/clothing/mask/gas/owl_mask name = "owl mask" @@ -427,6 +447,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSEYES resistance_flags = FLAMMABLE has_fov = FALSE + fishing_modifier = -1 /obj/item/clothing/mask/gas/carp name = "carp mask" @@ -435,6 +456,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( inhand_icon_state = null has_fov = FALSE flags_cover = MASKCOVERSEYES + fishing_modifier = -3 /obj/item/clothing/mask/gas/tiki_mask name = "tiki mask" @@ -448,6 +470,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( max_integrity = 100 actions_types = list(/datum/action/item_action/adjust) dog_fashion = null + fishing_modifier = -2 var/list/tikimask_designs = list() /obj/item/clothing/mask/gas/tiki_mask/Initialize(mapload) @@ -490,6 +513,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEFACIALHAIR|HIDEFACE|HIDEEYES|HIDEEARS|HIDEHAIR|HIDESNOUT has_fov = FALSE + fishing_modifier = -2 /obj/item/clothing/mask/gas/prop name = "prop gas mask" @@ -500,6 +524,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSMOUTH resistance_flags = FLAMMABLE has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/atmosprop name = "prop atmospheric gas mask" @@ -511,6 +536,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_cover = MASKCOVERSMOUTH resistance_flags = FLAMMABLE has_fov = FALSE + fishing_modifier = 0 /obj/item/clothing/mask/gas/driscoll name = "driscoll mask" @@ -519,3 +545,4 @@ GLOBAL_LIST_INIT(clown_mask_options, list( flags_inv = HIDEFACIALHAIR w_class = WEIGHT_CLASS_NORMAL inhand_icon_state = null + fishing_modifier = 0 diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index cbfbc166cbc..c5e538d4446 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list( visor_flags_cover = MASKCOVERSMOUTH tint = 0 has_fov = FALSE + fishing_modifier = 0 unique_death = 'sound/voice/sec_death.ogg' COOLDOWN_DECLARE(hailer_cooldown) ///Decides the phrases available for use; defines used are the last index of a category of available phrases @@ -86,6 +87,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list( visor_flags_inv = 0 flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES | PEPPERPROOF visor_flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES | PEPPERPROOF + fishing_modifier = 2 /obj/item/clothing/mask/gas/sechailer/swat/spacepol name = "spacepol mask" @@ -103,6 +105,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list( slot_flags = null aggressiveness = AGGR_GOOD_COP // Borgs are nicecurity! actions_types = list(/datum/action/item_action/halt) + fishing_modifier = 0 /obj/item/clothing/mask/gas/sechailer/screwdriver_act(mob/living/user, obj/item/I) . = ..() diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 839f3430cd9..c7cdb013a3b 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -213,6 +213,10 @@ desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." icon_state = "stethoscope" +/obj/item/clothing/neck/stethoscope/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /obj/item/clothing/neck/stethoscope/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] puts \the [src] to [user.p_their()] chest! It looks like [user.p_they()] won't hear much!")) return OXYLOSS diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm index 03f174aa43c..68a7b1bb0ae 100644 --- a/code/modules/clothing/shoes/boots.dm +++ b/code/modules/clothing/shoes/boots.dm @@ -72,6 +72,10 @@ icon_state = "ftc_boots" inhand_icon_state = null +/obj/item/clothing/shoes/jackboots/floortile/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) //tacticool + /obj/item/clothing/shoes/winterboots name = "winter boots" desc = "Boots lined with 'synthetic' animal fur." @@ -175,6 +179,10 @@ icon_state = "pirateboots" inhand_icon_state = null +/obj/item/clothing/shoes/pirate/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /obj/item/clothing/shoes/pirate/armored armor_type = /datum/armor/shoes_pirate strip_delay = 40 diff --git a/code/modules/clothing/shoes/clown.dm b/code/modules/clothing/shoes/clown.dm index 5d221d1f643..c999a242a19 100644 --- a/code/modules/clothing/shoes/clown.dm +++ b/code/modules/clothing/shoes/clown.dm @@ -14,7 +14,8 @@ create_storage(storage_type = /datum/storage/pockets/shoes/clown) LoadComponent(/datum/component/squeak, squeak_sound, 50, falloff_exponent = 20) //die off quick please - //AddElement(/datum/element/swabable, CELL_LINE_TABLE_CLOWN, CELL_VIRUS_TABLE_GENERIC, rand(2,3), 0) // NOVA EDIT - REMOVAL - NO CLOWN CYTOLOGY + AddElement(/datum/element/swabable, CELL_LINE_TABLE_CLOWN, CELL_VIRUS_TABLE_GENERIC, rand(2,3), 0) + AddComponent(/datum/component/adjust_fishing_difficulty, 3) //Goofy /obj/item/clothing/shoes/clown_shoes/equipped(mob/living/user, slot) . = ..() diff --git a/code/modules/clothing/shoes/costume.dm b/code/modules/clothing/shoes/costume.dm index bf8000d9a08..4f2287f40d2 100644 --- a/code/modules/clothing/shoes/costume.dm +++ b/code/modules/clothing/shoes/costume.dm @@ -45,6 +45,7 @@ /obj/item/clothing/shoes/bronze/Initialize(mapload) . = ..() AddComponent(/datum/component/squeak, list('sound/machines/clockcult/integration_cog_install.ogg' = 1, 'sound/magic/clockwork/fellowship_armory.ogg' = 1), 50, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + AddComponent(/datum/component/adjust_fishing_difficulty, 4) /obj/item/clothing/shoes/cookflops desc = "All this talk of antags, greytiding, and griefing... I just wanna grill for god's sake!" @@ -128,6 +129,7 @@ create_storage(storage_type = /datum/storage/pockets/shoes) LoadComponent(/datum/component/squeak, list('sound/effects/quack.ogg' = 1), 50, falloff_exponent = 20) + AddComponent(/datum/component/adjust_fishing_difficulty, -6) //deploy tactical duckling lure /obj/item/clothing/shoes/ducky_shoes/equipped(mob/living/user, slot) . = ..() diff --git a/code/modules/clothing/shoes/galoshes.dm b/code/modules/clothing/shoes/galoshes.dm index e743db6b742..d42b8ffddb3 100644 --- a/code/modules/clothing/shoes/galoshes.dm +++ b/code/modules/clothing/shoes/galoshes.dm @@ -12,11 +12,18 @@ can_be_bloody = FALSE custom_price = PAYCHECK_CREW * 3 can_be_tied = FALSE + ///How much these boots affect fishing difficulty + var/fishing_modifier = -3 + +/obj/item/clothing/shoes/galoshes/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) /obj/item/clothing/shoes/galoshes/dry name = "absorbent galoshes" desc = "A pair of purple rubber boots, designed to prevent slipping on wet surfaces while also drying them." icon_state = "galoshes_dry" + fishing_modifier = -6 /datum/armor/shoes_galoshes bio = 100 diff --git a/code/modules/clothing/shoes/laceup.dm b/code/modules/clothing/shoes/laceup.dm index 7ee348ea6c4..808bf22f508 100644 --- a/code/modules/clothing/shoes/laceup.dm +++ b/code/modules/clothing/shoes/laceup.dm @@ -3,3 +3,7 @@ desc = "The height of fashion, and they're pre-polished!" icon_state = "laceups" equip_delay_other = 50 + +/obj/item/clothing/shoes/laceup/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 3) //You aren't going to fish with these are you? diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 2ae13924ded..38d4770244a 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -20,18 +20,30 @@ var/slowdown_active = 2 /// A list of traits we apply when we get activated var/list/active_traits = list(TRAIT_NO_SLIP_WATER, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE, TRAIT_NEGATES_GRAVITY) + /// How much do these boots affect fishing when active + var/magpulse_fishing_modifier = 8 + /// How much do these boots affect fishing when not active + var/fishing_modifier = 4 /obj/item/clothing/shoes/magboots/Initialize(mapload) . = ..() AddElement(/datum/element/update_icon_updates_onmob) RegisterSignal(src, COMSIG_SPEED_POTION_APPLIED, PROC_REF(on_speed_potioned)) + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) /// Signal handler for [COMSIG_SPEED_POTION_APPLIED]. Speed potion removes the active slowdown /obj/item/clothing/shoes/magboots/proc/on_speed_potioned(datum/source) SIGNAL_HANDLER - slowdown_active = 0 // Don't need to touch the actual slowdown here, since the speed potion does it for us + slowdown_active = 0 + + if(magpulse && magpulse_fishing_modifier) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) + magpulse_fishing_modifier = fishing_modifier /obj/item/clothing/shoes/magboots/verb/toggle() set name = "Toggle Magboots" @@ -47,7 +59,15 @@ if(magpulse) attach_clothing_traits(active_traits) slowdown += slowdown_active + if(magpulse_fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, magpulse_fishing_modifier) + else if(magpulse_fishing_modifier != fishing_modifier) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) else + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) + else if(magpulse_fishing_modifier != fishing_modifier) + qdel(GetComponent(/datum/component/adjust_fishing_difficulty)) detach_clothing_traits(active_traits) slowdown = max(initial(slowdown), slowdown - slowdown_active) // Just in case, for speed pot shenanigans @@ -71,9 +91,13 @@ base_icon_state = "advmag" slowdown_active = SHOES_SLOWDOWN // ZERO active slowdown resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + magpulse_fishing_modifier = 3 + fishing_modifier = 0 /obj/item/clothing/shoes/magboots/syndie name = "blood-red magboots" desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders." icon_state = "syndiemag0" base_icon_state = "syndiemag" + magpulse_fishing_modifier = 6 + fishing_modifier = 3 diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index 2fc59abba8e..11d914178ce 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -25,6 +25,13 @@ resistance_flags = NONE dog_fashion = null slowdown = 0.5 + ///How much this helmet affects fishing difficulty + var/fishing_modifier = 3 + +/obj/item/clothing/head/helmet/space/Initialize(mapload) + . = ..() + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) /datum/armor/helmet_space bio = 100 @@ -70,6 +77,8 @@ var/thermal_on = FALSE /// If this is FALSE the batery status UI will be disabled. This is used for suits that don't use bateries like the changeling's flesh suit mutation. var/show_hud = TRUE + ///How much this suit affects fishing difficulty + var/fishing_modifier = 5 /datum/armor/suit_space bio = 100 @@ -81,6 +90,9 @@ if(ispath(cell)) cell = new cell(src) + if(fishing_modifier) + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) + /// Start Processing on the space suit when it is worn to heat the wearer /obj/item/clothing/suit/space/equipped(mob/living/user, slot) . = ..() diff --git a/code/modules/clothing/spacesuits/freedom.dm b/code/modules/clothing/spacesuits/freedom.dm index b0a08f4cc73..085b9c8deb7 100644 --- a/code/modules/clothing/spacesuits/freedom.dm +++ b/code/modules/clothing/spacesuits/freedom.dm @@ -9,6 +9,7 @@ strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF + fishing_modifier = 0 /datum/armor/space_freedom melee = 20 @@ -31,3 +32,4 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF slowdown = 0 + fishing_modifier = 0 diff --git a/code/modules/clothing/spacesuits/pirate.dm b/code/modules/clothing/spacesuits/pirate.dm index 0fecc83ca11..8ead0aeaa66 100644 --- a/code/modules/clothing/spacesuits/pirate.dm +++ b/code/modules/clothing/spacesuits/pirate.dm @@ -7,6 +7,7 @@ armor_type = /datum/armor/space_pirate strip_delay = 40 equip_delay_other = 20 + fishing_modifier = -2 /datum/armor/space_pirate melee = 30 @@ -31,6 +32,7 @@ armor_type = /datum/armor/space_pirate strip_delay = 40 equip_delay_other = 20 + fishing_modifier = -3 /obj/item/clothing/head/helmet/space/pirate/tophat name = "designer pirate helmet" diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 09c8f5e7d08..b19e1e0f238 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -8,6 +8,7 @@ resistance_flags = FIRE_PROOF icon_state = "plasmaman_suit" inhand_icon_state = "plasmaman_suit" + fishing_modifier = 0 var/next_extinguish = 0 var/extinguish_cooldown = 100 var/extinguishes_left = 10 @@ -57,6 +58,7 @@ light_power = 0.8 light_color = "#ffcc99" light_on = FALSE + fishing_modifier = 0 var/helmet_on = FALSE var/smile = FALSE var/smile_color = COLOR_RED diff --git a/code/modules/clothing/spacesuits/santa.dm b/code/modules/clothing/spacesuits/santa.dm index f6bd1657606..08f01cc1869 100644 --- a/code/modules/clothing/spacesuits/santa.dm +++ b/code/modules/clothing/spacesuits/santa.dm @@ -8,6 +8,7 @@ flags_cover = HEADCOVERSEYES dog_fashion = /datum/dog_fashion/head/santa slowdown = 0 + fishing_modifier = 0 /obj/item/clothing/head/helmet/space/santahat/beardless icon = 'icons/obj/clothing/head/costume.dmi' @@ -26,3 +27,4 @@ inhand_icon_state = "santa" slowdown = 0 allowed = list(/obj/item) //for stuffing exta special presents + fishing_modifier = 0 diff --git a/code/modules/clothing/spacesuits/specialops.dm b/code/modules/clothing/spacesuits/specialops.dm index caaa32cc24b..dbe02400aa6 100644 --- a/code/modules/clothing/spacesuits/specialops.dm +++ b/code/modules/clothing/spacesuits/specialops.dm @@ -13,6 +13,7 @@ strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF + fishing_modifier = 0 /datum/armor/space_beret melee = 80 @@ -41,6 +42,7 @@ strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF + fishing_modifier = 0 /datum/armor/space_officer melee = 80 diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index b95e08cdb0e..3c8d8e8a97f 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -318,6 +318,10 @@ equip_delay_other = 60 clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) +/obj/item/clothing/suit/armor/riot/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 5) + /datum/armor/armor_riot melee = 50 bullet = 10 @@ -437,6 +441,10 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS clothing_traits = list(TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) +/obj/item/clothing/suit/armor/swat/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 5) + //All of the armor below is mostly unused @@ -719,6 +727,10 @@ /obj/item/gun/ballistic/bow ) +/obj/item/clothing/suit/armor/vest/military/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 5) + /datum/armor/military melee = 45 bullet = 25 diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 8eba960cbe2..f443921c98d 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -18,6 +18,7 @@ . = ..() if(flags_inv & HIDEFACE) AddComponent(/datum/component/clothing_fov_visor, FOV_90_DEGREES) + AddComponent(/datum/component/adjust_fishing_difficulty, 6) /datum/armor/head_bio_hood bio = 100 @@ -42,6 +43,10 @@ equip_delay_other = 70 resistance_flags = ACID_PROOF +/obj/item/clothing/suit/bio_suit/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 6) + //Standard biosuit, orange stripe /datum/armor/suit_bio_suit bio = 100 diff --git a/code/modules/clothing/suits/costume.dm b/code/modules/clothing/suits/costume.dm index a460d746a71..db13329b920 100644 --- a/code/modules/clothing/suits/costume.dm +++ b/code/modules/clothing/suits/costume.dm @@ -261,6 +261,10 @@ allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/gun/ballistic/rifle/boltaction/harpoon) hoodtype = /obj/item/clothing/head/hooded/carp_hood +/obj/item/clothing/suit/hooded/carp_costume/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /obj/item/clothing/head/hooded/carp_hood name = "carp hood" desc = "A hood attached to a carp costume." @@ -272,6 +276,10 @@ min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT flags_inv = HIDEHAIR|HIDEEARS +/obj/item/clothing/head/hooded/carp_hood/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/head/hooded/carp_hood/equipped(mob/living/carbon/human/user, slot) ..() if (slot & ITEM_SLOT_HEAD) @@ -392,6 +400,10 @@ clothing_flags = THICKMATERIAL hoodtype = /obj/item/clothing/head/hooded/shark_hood +/obj/item/clothing/suit/hooded/shark_costume/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + /obj/item/clothing/head/hooded/shark_hood name = "shark hood" desc = "A hood attached to a shark costume." @@ -402,6 +414,10 @@ clothing_flags = THICKMATERIAL flags_inv = HIDEHAIR|HIDEEARS +/obj/item/clothing/head/hooded/shark_hood/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/suit/hooded/shork_costume // Oh God Why name = "shork costume" desc = "Why would you ever do this?" @@ -413,6 +429,10 @@ clothing_flags = THICKMATERIAL hoodtype = /obj/item/clothing/head/hooded/shork_hood +/obj/item/clothing/suit/hooded/shork_costume/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 2) + /obj/item/clothing/head/hooded/shork_hood name = "shork hood" desc = "A hood attached to a shork costume." @@ -423,6 +443,10 @@ clothing_flags = THICKMATERIAL flags_inv = HIDEHAIR|HIDEEARS +/obj/item/clothing/head/hooded/shork_hood/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 3) + /obj/item/clothing/suit/hooded/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? name = "bloated human suit" desc = "A horribly bloated suit made from human skins." @@ -587,6 +611,10 @@ flags_1 = IS_PLAYER_COLORABLE_1 species_exception = list(/datum/species/golem) +/obj/item/clothing/suit/costume/hawaiian/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/suit/costume/football_armor name = "football protective gear" desc = "Given to members of the football team!" diff --git a/code/modules/clothing/suits/ethereal.dm b/code/modules/clothing/suits/ethereal.dm index 6c53329a13e..1c86ca34094 100644 --- a/code/modules/clothing/suits/ethereal.dm +++ b/code/modules/clothing/suits/ethereal.dm @@ -14,6 +14,7 @@ /obj/item/clothing/suit/hooded/ethereal_raincoat/Initialize(mapload) . = ..() update_icon(UPDATE_OVERLAYS) + AddComponent(/datum/component/adjust_fishing_difficulty, -3) /obj/item/clothing/suit/hooded/ethereal_raincoat/worn_overlays(mutable_appearance/standing, isinhands, icon_file) . = ..() @@ -28,6 +29,11 @@ name = "trailwarden oilcoat" desc = "A masterfully handcrafted oilslick coat, supposedly makes for excellent camouflage among Sprout's vegetation. You can hear a faint electrical buzz emanating from the luminescent pattern." greyscale_colors = "#32a87d" + hoodtype = /obj/item/clothing/head/hooded/ethereal_rainhood/trailwarden + +/obj/item/clothing/suit/hooded/ethereal_raincoat/trailwarden/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -5) /obj/item/clothing/suit/hooded/ethereal_raincoat/trailwarden/equipped(mob/living/user, slot) . = ..() @@ -45,3 +51,9 @@ worn_icon = 'icons/mob/clothing/head/ethereal.dmi' body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEEARS|HIDEFACIALHAIR + +/obj/item/clothing/head/hooded/ethereal_rainhood/trailwarden + +/obj/item/clothing/head/hooded/ethereal_rainhood/trailwarden/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) diff --git a/code/modules/clothing/suits/ghostsheet.dm b/code/modules/clothing/suits/ghostsheet.dm index 65213fd176d..965adc9b7e2 100644 --- a/code/modules/clothing/suits/ghostsheet.dm +++ b/code/modules/clothing/suits/ghostsheet.dm @@ -16,6 +16,7 @@ . = ..() if(check_holidays(HALLOWEEN)) update_icon(UPDATE_OVERLAYS) + AddComponent(/datum/component/adjust_fishing_difficulty, 8) /obj/item/clothing/suit/costume/ghost_sheet/worn_overlays(mutable_appearance/standing, isinhands, icon_file) . = ..() diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 7e6bdde01cd..2ba150ab692 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -52,6 +52,10 @@ greyscale_colors = "#313c6e" flags_1 = IS_PLAYER_COLORABLE_1 +/obj/item/clothing/suit/apron/overalls/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) + //Captain /obj/item/clothing/suit/jacket/capjacket name = "captain's parade jacket" @@ -349,6 +353,10 @@ /obj/item/tank/internals/emergency_oxygen, ) +/obj/item/clothing/suit/apron/surgical/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) // FISH DOCTOR?! + //Curator /obj/item/clothing/suit/jacket/curator name = "treasure hunter's coat" diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index ff70bf60358..5453d048b0e 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -38,6 +38,10 @@ icon_state = "labcoat_cmo" inhand_icon_state = null +/obj/item/clothing/suit/toggle/labcoat/cmo/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /datum/armor/toggle_labcoat bio = 50 fire = 50 @@ -57,13 +61,9 @@ icon_state = "labcoat_paramedic" inhand_icon_state = null -//START NOVA EDIT ADDITION /obj/item/clothing/suit/toggle/labcoat/paramedic/Initialize(mapload) . = ..() - allowed += list( - /obj/item/storage/medkit, - ) -//END NOVA EDIT + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! /obj/item/clothing/suit/toggle/labcoat/mad name = "\proper The Mad's labcoat" diff --git a/code/modules/clothing/suits/moth.dm b/code/modules/clothing/suits/moth.dm index dd0a7f016ac..076a0dd0b3c 100644 --- a/code/modules/clothing/suits/moth.dm +++ b/code/modules/clothing/suits/moth.dm @@ -16,7 +16,7 @@ /obj/item/clothing/suit/mothcoat/original/Initialize(mapload) . = ..() - + AddComponent(/datum/component/adjust_fishing_difficulty, -3) create_storage(storage_type = /datum/storage/pockets) /obj/item/clothing/suit/mothcoat/winter diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 71833fe8fba..4d9fe5e0006 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -39,6 +39,10 @@ equip_delay_other = 60 resistance_flags = FIRE_PROOF +/obj/item/clothing/suit/utility/fire/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 7) + /datum/armor/utility_fire melee = 15 bullet = 5 @@ -104,6 +108,7 @@ . = ..() if(flags_inv & HIDEFACE) AddComponent(/datum/component/clothing_fov_visor, FOV_90_DEGREES) + AddComponent(/datum/component/adjust_fishing_difficulty, 8) /datum/armor/utility_bomb_hood melee = 20 @@ -133,6 +138,10 @@ equip_delay_other = 70 resistance_flags = NONE +/obj/item/clothing/suit/utility/bomb_suit/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 8) + /datum/armor/utility_bomb_suit melee = 20 laser = 20 @@ -179,6 +188,7 @@ . = ..() if(flags_inv & HIDEFACE) AddComponent(/datum/component/clothing_fov_visor, FOV_90_DEGREES) + AddComponent(/datum/component/adjust_fishing_difficulty, 7) /datum/armor/utility_radiation bio = 60 @@ -212,3 +222,4 @@ /obj/item/clothing/suit/utility/radiation/Initialize(mapload) . = ..() AddElement(/datum/element/radiation_protected_clothing) + AddComponent(/datum/component/adjust_fishing_difficulty, 7) diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 53026e974bf..aa29fa47a20 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -11,6 +11,12 @@ clothing_flags = SNUG_FIT | CASTING_CLOTHES resistance_flags = FIRE_PROOF | ACID_PROOF dog_fashion = /datum/dog_fashion/head/blue_wizard + ///How much this hat affects fishing difficulty + var/fishing_modifier = -4 + +/obj/item/clothing/head/wizard/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) //A wizard always practices his casting (ba dum tsh) /datum/armor/head_wizard melee = 30 @@ -48,6 +54,7 @@ armor_type = /datum/armor/none resistance_flags = FLAMMABLE dog_fashion = /datum/dog_fashion/head/blue_wizard + fishing_modifier = -1 /obj/item/clothing/head/wizard/chanterelle name = "chanterelle hat" @@ -114,6 +121,12 @@ equip_delay_other = 50 clothing_flags = CASTING_CLOTHES resistance_flags = FIRE_PROOF | ACID_PROOF + ///How much this robe affects fishing difficulty + var/fishing_modifier = -6 + +/obj/item/clothing/suit/wizrobe/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, fishing_modifier) //A wizard always practices his casting (ba dum tsh) /datum/armor/suit_wizrobe melee = 30 @@ -181,17 +194,20 @@ inhand_icon_state = "wizrobe" armor_type = /datum/armor/none resistance_flags = FLAMMABLE + fishing_modifier = -2 /obj/item/clothing/head/wizard/marisa/fake name = "witch hat" armor_type = /datum/armor/none resistance_flags = FLAMMABLE + fishing_modifier = -1 /obj/item/clothing/head/wizard/tape/fake name = "tape hat" desc = "A hat designed exclusively from duct tape. You can barely see." armor_type = /datum/armor/none resistance_flags = FLAMMABLE + fishing_modifier = -1 /obj/item/clothing/suit/wizrobe/marisa/fake name = "witch robe" @@ -200,12 +216,14 @@ inhand_icon_state = null armor_type = /datum/armor/none resistance_flags = FLAMMABLE + fishing_modifier = -2 /obj/item/clothing/suit/wizrobe/tape/fake name = "tape robe" desc = "An outfit designed exclusively from duct tape. It was hard to put on." armor_type = /datum/armor/none resistance_flags = FLAMMABLE + fishing_modifier = -2 /obj/item/clothing/suit/wizrobe/paper name = "papier-mache robe" // no non-latin characters! @@ -237,6 +255,7 @@ /obj/item/seeds, /obj/item/storage/bag/plants, ) + fishing_modifier = -4 /datum/armor/robe_durathread melee = 15 diff --git a/code/modules/clothing/under/jobs/civilian/curator.dm b/code/modules/clothing/under/jobs/civilian/curator.dm index 8f40e623d8a..f08657cee07 100644 --- a/code/modules/clothing/under/jobs/civilian/curator.dm +++ b/code/modules/clothing/under/jobs/civilian/curator.dm @@ -28,6 +28,10 @@ inhand_icon_state = null worn_icon = 'icons/mob/clothing/under/civilian.dmi' +/obj/item/clothing/under/rank/civilian/curator/treasure_hunter/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -3) + /obj/item/clothing/under/rank/civilian/curator/nasa name = "\improper NASA jumpsuit" desc = "It has a NASA logo on it and is made of space-proofed materials." diff --git a/code/modules/clothing/under/jobs/medical.dm b/code/modules/clothing/under/jobs/medical.dm index 1574b64bbf0..2dea3324082 100644 --- a/code/modules/clothing/under/jobs/medical.dm +++ b/code/modules/clothing/under/jobs/medical.dm @@ -44,6 +44,10 @@ icon_state = "scrubscmo" inhand_icon_state = "w_suit" +/obj/item/clothing/under/rank/medical/chief_medical_officer/scrubs/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /obj/item/clothing/under/rank/medical/chief_medical_officer/turtleneck name = "chief medical officer's turtleneck" desc = "A light blue turtleneck and tan khakis, for a chief medical officer with a superior sense of style." @@ -82,6 +86,10 @@ /obj/item/clothing/under/rank/medical/scrubs name = "medical scrubs" +/obj/item/clothing/under/rank/medical/scrubs/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /obj/item/clothing/under/rank/medical/scrubs/blue desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue." icon_state = "scrubsblue" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 81002bd8a9e..ad5e3976206 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -58,6 +58,10 @@ can_adjust = FALSE resistance_flags = FIRE_PROOF | ACID_PROOF +/obj/item/clothing/under/misc/adminsuit/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -15) + /datum/armor/clothing_under/adminsuit melee = 100 bullet = 100 diff --git a/code/modules/clothing/under/skirt_dress.dm b/code/modules/clothing/under/skirt_dress.dm index 9d9677f8ebd..3c3afa8b0db 100644 --- a/code/modules/clothing/under/skirt_dress.dm +++ b/code/modules/clothing/under/skirt_dress.dm @@ -40,6 +40,10 @@ body_parts_covered = CHEST|GROIN|LEGS flags_inv = HIDESHOES +/obj/item/clothing/under/dress/wedding_dress/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 4) //You aren't going to fish with this are you? + /obj/item/clothing/under/dress/eveninggown name = "evening gown" desc = "Fancy dress for space bar singers." @@ -50,6 +54,10 @@ flags_1 = IS_PLAYER_COLORABLE_1 greyscale_colors = "#e11f1f" +/obj/item/clothing/under/dress/eveninggown/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 4) //You aren't going to fish with this are you? + /obj/item/clothing/under/dress/skirt name = "cardigan skirt" desc = "A nice skirt with a cute cardigan, very fancy!" diff --git a/code/modules/clothing/under/suits.dm b/code/modules/clothing/under/suits.dm index 0dbf1880d7d..98f41f407ca 100644 --- a/code/modules/clothing/under/suits.dm +++ b/code/modules/clothing/under/suits.dm @@ -107,8 +107,16 @@ icon_state = "tuxedo" inhand_icon_state = null +/obj/item/clothing/under/suit/tuxedo/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, 4) //You aren't going to fish with this are you? + /obj/item/clothing/under/suit/carpskin name = "carpskin suit" desc = "An luxurious suit made with only the finest scales, perfect for conducting dodgy business deals." icon_state = "carpskin_suit" inhand_icon_state = null + +/obj/item/clothing/under/suit/carpskin/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index ff3061d3e59..e4653b1c9bd 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -34,6 +34,10 @@ can_adjust = FALSE supports_variations_flags = NONE +/obj/item/clothing/under/syndicate/bloodred/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //extra-tactical + /datum/armor/clothing_under/syndicate_bloodred melee = 10 bullet = 10 @@ -119,6 +123,10 @@ can_adjust = FALSE supports_variations_flags = NONE +/obj/item/clothing/under/syndicate/floortilecamo/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4) //tacticool + /obj/item/clothing/under/syndicate/soviet name = "Ratnik 5 tracksuit" desc = "Badly translated labels tell you to clean this in Vodka. Great for squatting in." @@ -160,6 +168,10 @@ supports_variations_flags = NONE armor_type = /datum/armor/clothing_under/syndicate_scrubs +/obj/item/clothing/under/syndicate/scrubs/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -2) //FISH DOCTOR?! + /datum/armor/clothing_under/syndicate_scrubs melee = 10 bio = 50 diff --git a/code/modules/fishing/aquarium/fish_analyzer.dm b/code/modules/fishing/aquarium/fish_analyzer.dm index 764626fddbf..c899c0c3abc 100644 --- a/code/modules/fishing/aquarium/fish_analyzer.dm +++ b/code/modules/fishing/aquarium/fish_analyzer.dm @@ -41,7 +41,7 @@ register_item_context() update_appearance() - + AddComponent(/datum/component/adjust_fishing_difficulty, -3, ITEM_SLOT_HANDS) /obj/item/fish_analyzer/examine(mob/user) . = ..() diff --git a/code/modules/fishing/fish_catalog.dm b/code/modules/fishing/fish_catalog.dm index 6e0216dcb8c..4f329861ff9 100644 --- a/code/modules/fishing/fish_catalog.dm +++ b/code/modules/fishing/fish_catalog.dm @@ -6,6 +6,10 @@ custom_price = PAYCHECK_CREW * 2 starting_content = "Lot of fish stuff" //book wrappers could use cleaning so this is not necessary +/obj/item/book/manual/fish_catalog/Initialize(mapload) + . = ..() + AddComponent(/datum/component/adjust_fishing_difficulty, -4, ITEM_SLOT_HANDS) + /obj/item/book/manual/fish_catalog/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/fishing/fish_movement.dm b/code/modules/fishing/fish_movement.dm index a328903617f..b288161b192 100644 --- a/code/modules/fishing/fish_movement.dm +++ b/code/modules/fishing/fish_movement.dm @@ -53,6 +53,10 @@ else long_jump_chance *= master.difficulty +/datum/fish_movement/proc/reset_difficulty_values() + short_jump_chance = initial(short_jump_chance) + long_jump_chance = initial(long_jump_chance) + ///The main proc, called by minigame every SSfishing tick while it's in the 'active' phase. /datum/fish_movement/proc/move_fish(seconds_per_tick) times_fired++ @@ -190,6 +194,12 @@ plunging_speed += round(plunging_speed * master.difficulty * 0.03) fish_idle_velocity += plunging_speed //so it can be safely subtracted if the fish starts at the bottom. +/datum/fish_movement/plunger/reset_difficulty_values() + . = ..() + if(is_plunging) + fish_idle_velocity -= plunging_speed + plunging_speed = initial(plunging_speed) + /datum/fish_movement/plunger/move_fish(seconds_per_tick) var/fish_area = FISHING_MINIGAME_AREA - master.fish_height if(is_plunging) diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index e2b4523448b..7fb33da74ff 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -288,6 +288,8 @@ inhand_icon_state = "artistic_toolbox" material_flags = NONE custom_price = PAYCHECK_CREW * 3 + ///How much holding this affects fishing difficulty + var/fishing_modifier = -2 /obj/item/storage/toolbox/fishing/Initialize(mapload) . = ..() @@ -296,6 +298,7 @@ /obj/item/fishing_rod, )) atom_storage.exception_hold = exception_cache + AddComponent(/datum/component/adjust_fishing_difficulty, -2, ITEM_SLOT_HANDS) /obj/item/storage/toolbox/fishing/PopulateContents() new /obj/item/bait_can/worm(src) @@ -326,6 +329,7 @@ desc = "Contains EVERYTHING (almost) you need for your fishing trip." icon_state = "gold" inhand_icon_state = "toolbox_gold" + fishing_modifier = -7 /obj/item/storage/toolbox/fishing/master/PopulateContents() new /obj/item/fishing_rod/telescopic/master(src) diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm index 0eb2d9846ab..073158b8fdc 100644 --- a/code/modules/fishing/fishing_minigame.dm +++ b/code/modules/fishing/fishing_minigame.dm @@ -32,6 +32,8 @@ ///The standard pixel height of the fish (minus a pixel on each direction for the sake of a better looking sprite) #define MINIGAME_FISH_HEIGHT 4 +GLOBAL_LIST_EMPTY(fishing_challenges_by_user) + /datum/fishing_challenge /// When the ui minigame phase started var/start_time @@ -120,8 +122,10 @@ RegisterSignal(comp.fish_source, COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE, PROC_REF(interrupt_challenge)) comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_ROLL_REWARD, TYPE_PROC_REF(/datum/fish_source, roll_reward_minigame)) comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, TYPE_PROC_REF(/datum/fish_source, calculate_difficulty_minigame)) - comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_COMPLETED, TYPE_PROC_REF(/datum/fish_source, on_challenge_completed)) + comp.fish_source.RegisterSignal(user, COMSIG_MOB_COMPLETE_FISHING, TYPE_PROC_REF(/datum/fish_source, on_challenge_completed)) background = comp.fish_source.background + SEND_SIGNAL(user, COMSIG_MOB_BEGIN_FISHING, src) + GLOB.fishing_challenges_by_user[user] = src /// Enable special parameters if(rod.line) @@ -148,6 +152,7 @@ completion_loss += user.mind?.get_skill_modifier(/datum/skill/fishing, SKILL_VALUE_MODIFIER)/5 /datum/fishing_challenge/Destroy(force) + GLOB.fishing_challenges_by_user -= user if(!completed) complete(win = FALSE) if(fishing_line) @@ -192,7 +197,6 @@ active_effects = bitfield_to_list(special_effects & FISHING_MINIGAME_ACTIVE_EFFECTS) // If fishing line breaks los / rod gets dropped / deleted RegisterSignal(used_rod, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_attack_self)) - ADD_TRAIT(user, TRAIT_GONE_FISHING, WEAKREF(src)) user.add_mood_event("fishing", /datum/mood_event/fishing) RegisterSignal(user, COMSIG_MOB_CLICKON, PROC_REF(handle_click)) start_baiting_phase() @@ -308,8 +312,6 @@ if(phase == MINIGAME_PHASE) remove_minigame_hud() if(!QDELETED(user)) - UnregisterSignal(user, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING)) - user.remove_traits(list(TRAIT_GONE_FISHING, TRAIT_ACTIVELY_FISHING), WEAKREF(src)) if(start_time) var/seconds_spent = (world.time - start_time) * 0.1 if(!(special_effects & FISHING_MINIGAME_RULE_NO_EXP)) @@ -319,7 +321,7 @@ if(win) if(reward_path != FISHING_DUD) playsound(location, 'sound/effects/bigsplash.ogg', 100) - SEND_SIGNAL(src, COMSIG_FISHING_CHALLENGE_COMPLETED, user, win) + SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, win) if(!QDELETED(src)) qdel(src) @@ -419,16 +421,41 @@ var/damage = CEILING((world.time - start_time)/10 * FISH_DAMAGE_PER_SECOND, 1) reward.adjust_health(reward.health - damage) -///Get the difficulty and other variables, than start the minigame -/datum/fishing_challenge/proc/start_minigame_phase(auto_reel = FALSE) +/datum/fishing_challenge/proc/get_difficulty() var/list/difficulty_holder = list(0) SEND_SIGNAL(src, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, reward_path, used_rod, user, difficulty_holder) difficulty = difficulty_holder[1] //If you manage to be so well-equipped and skilled to completely crush the difficulty, just skip to the reward. if(difficulty <= 0) complete(TRUE) - return + return FALSE difficulty = clamp(round(difficulty), FISHING_MINIMUM_DIFFICULTY, 100) + return TRUE + +/datum/fishing_challenge/proc/update_difficulty() + if(phase != MINIGAME_PHASE) + return + var/old_difficulty = difficulty + //early return if the difficulty is the same or we crush the minigame all the way to 0 difficulty + if(!get_difficulty() || difficulty == old_difficulty) + return + bait_height = initial(bait_height) + experience_multiplier -= difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT + mover.reset_difficulty_values() + adjust_to_difficulty() + +/datum/fishing_challenge/proc/adjust_to_difficulty() + mover.adjust_to_difficulty() + bait_height -= round(difficulty * BAIT_HEIGHT_DIFFICULTY_MALUS) + bait_pixel_height = round(MINIGAME_BAIT_HEIGHT * (bait_height/initial(bait_height)), 1) + experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT + fishing_hud.hud_bait.adjust_to_difficulty(src) + +///Get the difficulty and other variables, than start the minigame +/datum/fishing_challenge/proc/start_minigame_phase(auto_reel = FALSE) + SEND_SIGNAL(user, COMSIG_MOB_BEGIN_FISHING_MINIGAME, src) + if(!get_difficulty()) //we totalized 0 or less difficulty, instant win. + return if(difficulty > FISHING_DEFAULT_DIFFICULTY) completion -= MAX_FISH_COMPLETION_MALUS * (difficulty * 0.01) @@ -449,11 +476,6 @@ else mover = new /datum/fish_movement(src) - mover.adjust_to_difficulty() - - bait_height -= round(difficulty * BAIT_HEIGHT_DIFFICULTY_MALUS) - bait_pixel_height = round(MINIGAME_BAIT_HEIGHT * (bait_height/initial(bait_height)), 1) - if(auto_reel) completion *= 1.3 else @@ -471,11 +493,14 @@ fish_position = rand(0, (FISHING_MINIGAME_AREA - fish_height) * 0.8) var/diff_dist = 100 + difficulty bait_position = clamp(round(fish_position + rand(-diff_dist, diff_dist) - bait_height * 0.5), 0, FISHING_MINIGAME_AREA - bait_height) + if(!prepare_minigame_hud()) get_stack_trace("couldn't prepare minigame hud for a fishing challenge.") //just to be sure. This shouldn't happen. qdel(src) return - ADD_TRAIT(user, TRAIT_ACTIVELY_FISHING, WEAKREF(src)) + + adjust_to_difficulty() + phase = MINIGAME_PHASE deltimer(next_phase_timer) if((FISHING_MINIGAME_RULE_KILL in special_effects) && ispath(reward_path,/obj/item/fish)) @@ -483,7 +508,6 @@ var/wait_time = (initial(fish.health) / FISH_DAMAGE_PER_SECOND) SECONDS addtimer(CALLBACK(src, PROC_REF(win_anyway)), wait_time, TIMER_DELETE_ME) start_time = world.time - experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT ///Throws a stack with prefixed text. /datum/fishing_challenge/proc/get_stack_trace(init_text) @@ -709,18 +733,24 @@ icon = 'icons/hud/fishing_hud.dmi' icon_state = "bait" vis_flags = VIS_INHERIT_ID + ///The stored value we used to squish the bar based on the difficulty + var/current_vertical_transform /atom/movable/screen/hud_bait/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge) . = ..() if(!challenge || challenge.bait_pixel_height == MINIGAME_BAIT_HEIGHT) return - var/static/icon_height - if(!icon_height) - var/list/icon_dimensions = get_icon_dimensions(icon) - icon_height = icon_dimensions["height"] - var/height_percent_diff = challenge.bait_pixel_height/MINIGAME_BAIT_HEIGHT - transform = transform.Scale(1, height_percent_diff) - pixel_z = -icon_height * (1 - height_percent_diff) * 0.5 + adjust_to_difficulty(challenge) + +/atom/movable/screen/hud_bait/proc/adjust_to_difficulty(datum/fishing_challenge/challenge) + if(current_vertical_transform) + transform = transform.Scale(1, 1/current_vertical_transform) + pixel_z = 0 + var/list/icon_dimensions = get_icon_dimensions(icon) + var/icon_height = icon_dimensions["height"] + current_vertical_transform = challenge.bait_pixel_height/MINIGAME_BAIT_HEIGHT + transform = transform.Scale(1, current_vertical_transform) + pixel_z = -icon_height * (1 - current_vertical_transform) * 0.5 /atom/movable/screen/hud_fish icon = 'icons/hud/fishing_hud.dmi' diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 7ee15cead66..f18637e3b35 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -79,7 +79,7 @@ /obj/item/fishing_rod/add_item_context(obj/item/source, list/context, atom/target, mob/living/user) . = ..() - var/gone_fishing = HAS_TRAIT(user, TRAIT_GONE_FISHING) + var/gone_fishing = GLOB.fishing_challenges_by_user[user] if(currently_hooked || gone_fishing) context[SCREENTIP_CONTEXT_LMB] = (gone_fishing && spin_frequency) ? "Spin" : "Reel in" if(!gone_fishing) @@ -411,7 +411,7 @@ /// Ideally this will be replaced with generic slotted storage datum + display /obj/item/fishing_rod/proc/use_slot(slot, mob/user, obj/item/new_item) - if(fishing_line || HAS_TRAIT(user, TRAIT_GONE_FISHING)) + if(fishing_line || GLOB.fishing_challenges_by_user[user]) return var/obj/item/current_item switch(slot) @@ -545,7 +545,7 @@ if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE)) return //the fishing minigame uses the attack_self signal to let the user end it early without having to drop the rod. - if(HAS_TRAIT(user, TRAIT_GONE_FISHING)) + if(GLOB.fishing_challenges_by_user[user]) return COMPONENT_BLOCK_TRANSFORM ///Gives feedback to the user, makes it show up inhand, toggles whether it can be used for fishing. diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 51ff20db513..815f3c34d23 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -222,21 +222,21 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) SEND_SIGNAL(src, COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE, reason) /** - * Proc called when the COMSIG_FISHING_CHALLENGE_COMPLETED signal is sent. + * Proc called when the COMSIG_MOB_COMPLETE_FISHING signal is sent. * Check if we've succeeded. If so, write into memory and dispense the reward. */ -/datum/fish_source/proc/on_challenge_completed(datum/fishing_challenge/source, mob/user, success) +/datum/fish_source/proc/on_challenge_completed(mob/user, datum/fishing_challenge/challenge, success) SIGNAL_HANDLER SHOULD_CALL_PARENT(TRUE) + UnregisterSignal(user, COMSIG_MOB_COMPLETE_FISHING) if(!success) return - var/obj/item/fish/caught = source.reward_path - user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = initial(caught.name)) - var/turf/fishing_spot = get_turf(source.float) - var/atom/movable/reward = dispense_reward(source.reward_path, user, fishing_spot) - if(source.used_rod) - SEND_SIGNAL(source.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user) - source.used_rod.consume_bait(reward) + var/turf/fishing_spot = get_turf(challenge.float) + var/atom/movable/reward = dispense_reward(challenge.reward_path, user, fishing_spot) + if(reward) + user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = reward.name) + SEND_SIGNAL(challenge.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user) + challenge.used_rod.consume_bait(reward) /// Gives out the reward if possible /datum/fish_source/proc/dispense_reward(reward_path, mob/fisherman, turf/fishing_spot) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 34f3de0cfa0..2a2d29bb08f 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -958,7 +958,7 @@ /obj/item/mod/module/fishing_glove name = "MOD fishing glove module" - desc = "A MOD module that takes in an external fishing rod to enable the user to fish without having to hold one." + desc = "A MOD module that takes in an external fishing rod to enable the user to fish without having to hold one, while also making it slightly easier." icon_state = "fishing_glove" complexity = 1 overlay_state_inactive = "fishing_glove" @@ -1013,17 +1013,20 @@ var/obj/item/gloves = mod?.get_part_from_slot(ITEM_SLOT_GLOVES) if(gloves && !QDELETED(mod)) qdel(gloves.GetComponent(/datum/component/profound_fisher)) + return ..() /obj/item/mod/module/fishing_glove/on_suit_activation() - if(!equipped) - return var/obj/item/gloves = mod.get_part_from_slot(ITEM_SLOT_GLOVES) - if(gloves) + if(!gloves) + return + gloves.AddComponent(/datum/component/adjust_fishing_difficulty, 5) + if(equipped) gloves.AddComponent(/datum/component/profound_fisher, equipped) /obj/item/mod/module/fishing_glove/on_suit_deactivation(deleting = FALSE) var/obj/item/gloves = mod.get_part_from_slot(ITEM_SLOT_GLOVES) if(gloves && !deleting) + qdel(gloves.GetComponent(/datum/component/adjust_fishing_difficulty)) qdel(gloves.GetComponent(/datum/component/profound_fisher)) /obj/item/mod/module/shock_absorber diff --git a/modular_nova/master_files/code/modules/clothing/shoes/clown.dm b/modular_nova/master_files/code/modules/clothing/shoes/clown.dm new file mode 100644 index 00000000000..248c38d8652 --- /dev/null +++ b/modular_nova/master_files/code/modules/clothing/shoes/clown.dm @@ -0,0 +1,5 @@ +// NO CLOWN CYTOLOGY +/obj/item/clothing/shoes/clown_shoes/Initialize(mapload) + . = ..() + + RemoveElement(/datum/element/swabable, CELL_LINE_TABLE_CLOWN, CELL_VIRUS_TABLE_GENERIC, rand(2,3), 0) diff --git a/modular_nova/master_files/code/modules/clothing/suits/labcoat.dm b/modular_nova/master_files/code/modules/clothing/suits/labcoat.dm index 710482f72f4..3813ed086a5 100644 --- a/modular_nova/master_files/code/modules/clothing/suits/labcoat.dm +++ b/modular_nova/master_files/code/modules/clothing/suits/labcoat.dm @@ -1,3 +1,9 @@ +/obj/item/clothing/suit/toggle/labcoat/paramedic/Initialize(mapload) + . = ..() + allowed += list( + /obj/item/storage/medkit, + ) + /obj/item/clothing/suit/toggle/labcoat supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index 31d18f10196..ce8f601d375 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -43,4 +43,5 @@ You can get an experiscanner from science to perform fish scanning experiments, Fish is, of course, edible. Is it safe to eat raw? Well, if you've strong stomach, otherwise your best option is to cook it for a at least half a spessman minute if you don't want to catch nasty diseases. After researching the Advanced Fishing Technology Node, you can print special fishing gloves that let you fish without having to carry around a fishing rod. There's one pair that even trains athletics on top of fishing.You can get an experiscanner from science to perform fish scanning experiments, which can unlock more modules for the fishing portal, as well as fishing technology nodes (better equipment) for research. If you have enough credits, you can buy a set of fishing lures from cargo. Each lure allows you to catch different species of fish and won't get consumed, however they need to be spun at intervals to work. -This may sound silly, but squids and their ink sacs can be used to temporarily blind foes. \ No newline at end of file +Various clothing and handheld items, as well as chairs you sit on, can make fishing easier (or sometimes harder). A trained fisherman can tell what can help and what won't, so keep an eye out. +This may sound silly, but (live) squids and their ink sacs can be used as weapons to temporarily blind foes. \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index f787b994f51..39d8edca26e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1133,6 +1133,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\acid.dm" #include "code\datums\components\action_item_overlay.dm" +#include "code\datums\components\adjust_fishing_difficulty.dm" #include "code\datums\components\admin_popup.dm" #include "code\datums\components\aggro_emote.dm" #include "code\datums\components\ai_has_target_timer.dm" @@ -6738,6 +6739,7 @@ #include "modular_nova\master_files\code\modules\clothing\outfits\standard.dm" #include "modular_nova\master_files\code\modules\clothing\shoes\bananashoes.dm" #include "modular_nova\master_files\code\modules\clothing\shoes\boots.dm" +#include "modular_nova\master_files\code\modules\clothing\shoes\clown.dm" #include "modular_nova\master_files\code\modules\clothing\shoes\costume.dm" #include "modular_nova\master_files\code\modules\clothing\shoes\sneakers.dm" #include "modular_nova\master_files\code\modules\clothing\shoes\wheelys.dm" From 970d06a559bc327daee126209b70249cdb28418f Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:33:43 +0000 Subject: [PATCH 109/142] Automatic changelog for PR #86646 [ci skip] --- html/changelogs/AutoChangeLog-pr-86646.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86646.yml diff --git a/html/changelogs/AutoChangeLog-pr-86646.yml b/html/changelogs/AutoChangeLog-pr-86646.yml new file mode 100644 index 00000000000..5d118f5833f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86646.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "Your current clothes and what chair you sit on can now influence the difficulty of fishing minigames. Having a bare minimum of fishing skill will let you distinguish which objects can help and which won't, so keep an eye out. Holding fishing toolboxes, fish analyzers or fish catalogs can also help." \ No newline at end of file From db42cb3549ae062f4cce2a62eb5d21bbc8acd596 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Tue, 17 Sep 2024 19:11:07 -0400 Subject: [PATCH 110/142] Fix required status checks (#86739) TL;DR GitHub is trash https://emmer.dev/blog/skippable-github-status-checks-aren-t-really-required/ --- .github/workflows/ci_suite.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index 92c1bb5dd72..680374ba37e 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -289,9 +289,12 @@ jobs: max-required-client-version: ${{needs.collect_data.outputs.max_required_byond_client}} completion_gate: # Serves as a non-moving target for branch rulesets + if: always() && !cancelled() name: Completion Gate needs: [ test_windows, compare_screenshots, compile_all_maps, run_linters ] runs-on: ubuntu-latest steps: - - name: Mandatory Empty Step - run: exit 0 + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} From 53c60696b31111205cc8a6fb80054525c91f435f Mon Sep 17 00:00:00 2001 From: Jerry <55355646+Jewelry-x@users.noreply.github.com> Date: Wed, 18 Sep 2024 02:27:49 +0300 Subject: [PATCH 111/142] Fix lack of blob reagent description (#86715) ## About The Pull Request This PR addresses the lack of descriptions for blob reagents. Previously, the description for these reagents stated: "shouldn't exist and you should adminhelp immediately." This has been changed to automatically generate a basic description when a reagent's name exists. The confusion caused by the previous description is exemplified in issue #85363 (does not fix the issue itself). For example, if the reagent is named *Blazing Oil*, the new description will read: "Blazing Oil is the reagent created by that type of blob.". See the example below: ![image](https://github.com/user-attachments/assets/ab7c10cf-9306-404d-a232-b16115dab894) If the reagent name is *Unknown*, the description will revert to the original message, prompting players to adminhelp. ![image](https://github.com/user-attachments/assets/09036d34-9c69-4688-90d6-9b1f2a7a4722) In addition, two specific blob chemicals used to inject players, *Regenerative Materia* and *Cryogenic Poison*, will now include more detailed descriptions, specifying their purposes. ![image](https://github.com/user-attachments/assets/7299b679-f55e-491c-95c8-07fecb9a075c) ![image](https://github.com/user-attachments/assets/4737b748-5409-4e34-b420-0a46df654b80) ## Why It's Good For The Game This change makes it easier for players to understand the origin of blob chemicals, reducing confusion when they are detected. ## Changelog :cl: fix: fixes description for blob reagents /:cl: --- code/modules/antagonists/blob/blobstrains/_reagent.dm | 11 ++++++++++- .../antagonists/blob/blobstrains/cryogenic_poison.dm | 2 +- .../blob/blobstrains/regenerative_materia.dm | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/code/modules/antagonists/blob/blobstrains/_reagent.dm b/code/modules/antagonists/blob/blobstrains/_reagent.dm index 2d7f4c5d34e..65a50621b17 100644 --- a/code/modules/antagonists/blob/blobstrains/_reagent.dm +++ b/code/modules/antagonists/blob/blobstrains/_reagent.dm @@ -26,12 +26,21 @@ // These can only be applied by blobs. They are what (reagent) blobs are made out of. /datum/reagent/blob name = "Unknown" - description = "shouldn't exist and you should adminhelp immediately." + description = "" color = COLOR_WHITE taste_description = "bad code and slime" chemical_flags = NONE penetrates_skin = NONE + +/datum/reagent/blob/New() + ..() + + if(name == "Unknown") + description = "shouldn't exist and you should adminhelp immediately." + else if(description == "") + description = "[name] is the reagent created by that type of blob." + /// Used by blob reagents to calculate the reaction volume they should use when exposing mobs. /datum/reagent/blob/proc/return_mob_expose_reac_volume(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) if(exposed_mob.stat == DEAD || HAS_TRAIT(exposed_mob, TRAIT_BLOB_ALLY)) diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm index a18d802ff7d..acb4d96c23a 100644 --- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm +++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm @@ -12,7 +12,7 @@ /datum/reagent/blob/cryogenic_poison name = "Cryogenic Poison" - description = "will inject targets with a freezing poison that does high damage over time." + description = "A freezing poison that does high damage over time. Cryogenic poison blobs inject this into their victims." color = "#8BA6E9" taste_description = "brain freeze" diff --git a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm index a62895ae6c4..d9010a96537 100644 --- a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm +++ b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm @@ -12,6 +12,7 @@ /datum/reagent/blob/regenerative_materia name = "Regenerative Materia" + description = "Chemical that inflicts toxin damage and makes the target believe they are fully healed. Regenerative materia blobs inject this into their victims." taste_description = "heaven" color = "#A88FB7" From 243b8fd72dd3514368d8a9a1bc5064616aed69a3 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Wed, 18 Sep 2024 05:02:51 +0530 Subject: [PATCH 112/142] Borgs can perform organ manipulation surgery again (#86707) ## About The Pull Request - Fixes #86676 ## Changelog :cl: fix: borgs can perform organ manipulation surgery again /:cl: --- code/modules/surgery/organ_manipulation.dm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 24083246816..0496d836958 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -213,13 +213,24 @@ if(isnull(chosen_organ)) return SURGERY_STEP_FAIL target_organ = chosen_organ - if(user && target && user.Adjacent(target) && user.get_active_held_item() == tool) + + if(user && target && user.Adjacent(target)) + //tool check + var/obj/item/held_tool = user.get_active_held_item() + if(held_tool) + held_tool = held_tool.get_proxy_attacker_for(target, user) + if(held_tool != tool) + return SURGERY_STEP_FAIL + + //organ check target_organ = organs[target_organ] if(!target_organ) return SURGERY_STEP_FAIL if(target_organ.organ_flags & ORGAN_UNREMOVABLE) to_chat(user, span_warning("[target_organ] is too well connected to take out!")) return SURGERY_STEP_FAIL + + //start operation display_results( user, target, From 5fd57f6dc11c9ae84dbfc14f4d34c76e9cbc51c8 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 23:34:34 +0000 Subject: [PATCH 113/142] Automatic changelog for PR #86715 [ci skip] --- html/changelogs/AutoChangeLog-pr-86715.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86715.yml diff --git a/html/changelogs/AutoChangeLog-pr-86715.yml b/html/changelogs/AutoChangeLog-pr-86715.yml new file mode 100644 index 00000000000..aff07427f70 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86715.yml @@ -0,0 +1,4 @@ +author: "Jewelry-x" +delete-after: True +changes: + - bugfix: "fixes description for blob reagents" \ No newline at end of file From dede9d8a313ff3f7cf7c430eb8feafca60e5edd6 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 23:35:00 +0000 Subject: [PATCH 114/142] Automatic changelog for PR #86707 [ci skip] --- html/changelogs/AutoChangeLog-pr-86707.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86707.yml diff --git a/html/changelogs/AutoChangeLog-pr-86707.yml b/html/changelogs/AutoChangeLog-pr-86707.yml new file mode 100644 index 00000000000..079d078642b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86707.yml @@ -0,0 +1,4 @@ +author: "SyncIt21" +delete-after: True +changes: + - bugfix: "borgs can perform organ manipulation surgery again" \ No newline at end of file From 99c71b2c1499d17663d8a9018fd41996387feac4 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 18 Sep 2024 01:36:06 +0200 Subject: [PATCH 115/142] quickfix for a CI failure that went through because enabling auto-merge seems to ignore CI (#86740) ## About The Pull Request Unused var removed. ## Why It's Good For The Game I was told to do it. ## Changelog N/A --- code/datums/components/adjust_fishing_difficulty.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/datums/components/adjust_fishing_difficulty.dm b/code/datums/components/adjust_fishing_difficulty.dm index abb7c768653..b2f5f71a757 100644 --- a/code/datums/components/adjust_fishing_difficulty.dm +++ b/code/datums/components/adjust_fishing_difficulty.dm @@ -62,7 +62,6 @@ SIGNAL_HANDLER if(!HAS_MIND_TRAIT(user, TRAIT_EXAMINE_FISH)) return - var/percent = HAS_MIND_TRAIT(user, TRAIT_EXAMINE_DEEPER_FISH) ? "[modifier]% " : "" add_examine_line(user, examine_text, "Buckling to [source.p_them()]") /datum/component/adjust_fishing_difficulty/proc/add_examine_line(mob/user, list/examine_text, method) From 7022d1e68afffce0d3d0dc717af18c8306102b78 Mon Sep 17 00:00:00 2001 From: Goat <126099705+Goat-Real@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:16:04 -0600 Subject: [PATCH 116/142] Allows lockers & crates with no electronics to be renamed (#86717) ## About The Pull Request Adds a `secure` check to `ifnull(id_card)`, this allows crates without airlock electronics or card readers to be renamed by anyone. Also removes the 'personal' in the TGUI as it doesn't make sense anymore. ## Why It's Good For The Game Allows any random crate to be renamed and re described. Communal lockers, like departmental lockers, cannot be renamed because that would be RUDE. fix #85628 ## Changelog :cl: Goat fix: lockers and crates with no access requirements can now be renamed by anyone /:cl: --- code/game/objects/structures/crates_lockers/closets.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 7370c69da30..902eef6da17 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -823,19 +823,19 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) balloon_alert(user, "unlock first!") return - if(isnull(id_card)) + if(isnull(id_card) && secure) balloon_alert(user, "not yours to rename!") return var/name_set = FALSE var/desc_set = FALSE - var/str = tgui_input_text(user, "Personal Locker Name", "Locker Name") + var/str = tgui_input_text(user, "Locker Name", "Locker Name") if(!isnull(str)) name = str name_set = TRUE - str = tgui_input_text(user, "Personal Locker Description", "Locker Description") + str = tgui_input_text(user, "Locker Description", "Locker Description") if(!isnull(str)) desc = str desc_set = TRUE From b154853b870bb436b5cc7a1c3bf2135b45b285dd Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 04:17:38 +0000 Subject: [PATCH 117/142] Automatic changelog for PR #86717 [ci skip] --- html/changelogs/AutoChangeLog-pr-86717.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86717.yml diff --git a/html/changelogs/AutoChangeLog-pr-86717.yml b/html/changelogs/AutoChangeLog-pr-86717.yml new file mode 100644 index 00000000000..83b5bd8747c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86717.yml @@ -0,0 +1,4 @@ +author: "Goat" +delete-after: True +changes: + - bugfix: "lockers and crates with no access requirements can now be renamed by anyone" \ No newline at end of file From 44e7d74c638bc96f2656436730a7247fc7dce92d Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:48:41 +0200 Subject: [PATCH 118/142] Post-godmode refactor cleanup (#86718) ## About The Pull Request Adds some flags that went missing after #86596 Closes #86709 ## Changelog :cl: fix: Snow bears are no longer impervious to all sources of damage fix: Cameras, living floors and ghost of poly no longer can be pushed around /:cl: --- code/modules/mob/camera/camera.dm | 1 + code/modules/mob/living/basic/pets/parrot/poly.dm | 1 + .../modules/mob/living/basic/ruin_defender/living_floor.dm | 1 + code/modules/mob/living/basic/space_fauna/bear/_bear.dm | 7 ++++--- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index 2dc5db8fc02..eb0d787f64b 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -7,6 +7,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT invisibility = INVISIBILITY_ABSTRACT // No one can see us sight = SEE_SELF + status_flags = NONE /// Toggles if the camera can move on shuttles var/move_on_shuttle = FALSE /// Toggles if the camera can use emotes diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index 737ea2079b0..f825788decd 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -193,6 +193,7 @@ color = "#FFFFFF77" sentience_type = SENTIENCE_BOSS //This is so players can't mindswap into ghost poly to become a literal god incorporeal_move = INCORPOREAL_MOVE_BASIC + status_flags = NONE butcher_results = list(/obj/item/ectoplasm = 1) ai_controller = /datum/ai_controller/basic_controller/parrot/ghost speech_probability_rate = 1 diff --git a/code/modules/mob/living/basic/ruin_defender/living_floor.dm b/code/modules/mob/living/basic/ruin_defender/living_floor.dm index c84e602659b..ce4fbc53f51 100644 --- a/code/modules/mob/living/basic/ruin_defender/living_floor.dm +++ b/code/modules/mob/living/basic/ruin_defender/living_floor.dm @@ -26,6 +26,7 @@ icon_living = "floor" mob_size = MOB_SIZE_HUGE mob_biotypes = MOB_SPECIAL + status_flags = NONE death_message = "" unsuitable_atmos_damage = 0 minimum_survivable_temperature = 0 diff --git a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm index 9080e040f51..d13df298064 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm @@ -42,7 +42,7 @@ /mob/living/basic/bear/Initialize(mapload) . = ..() - add_traits(list(TRAIT_SPACEWALK, TRAIT_FENCE_CLIMBER), INNATE_TRAIT) + add_traits(list(TRAIT_SPACEWALK, TRAIT_FENCE_CLIMBER, TRAIT_SNOWSTORM_IMMUNE), INNATE_TRAIT) AddElement(/datum/element/ai_retaliate) AddComponent(/datum/component/tree_climber, climbing_distance = 15) AddElement(/datum/element/swabable, CELL_LINE_TABLE_BEAR, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) @@ -90,15 +90,16 @@ maxHealth = 250 health = 250 faction = list(FACTION_NEUTRAL) + status_flags = CANPUSH /mob/living/basic/bear/snow/ancient name = "ancient polar bear" desc = "A grizzled old polar bear, its hide thick enough to make it impervious to almost all weapons." gold_core_spawnable = NO_SPAWN -/mob/living/basic/bear/snow/Initialize(mapload) +/mob/living/basic/bear/snow/ancient/Initialize(mapload) . = ..() - add_traits(list(TRAIT_GODMODE, TRAIT_SNOWSTORM_IMMUNE), INNATE_TRAIT) + ADD_TRAIT(src, TRAIT_GODMODE, INNATE_TRAIT) /mob/living/basic/bear/russian name = "combat bear" From ab08f345b9dd76397618ed7ad5a9b839b7844a6a Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:16:39 +0000 Subject: [PATCH 119/142] Automatic changelog for PR #86718 [ci skip] --- html/changelogs/AutoChangeLog-pr-86718.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86718.yml diff --git a/html/changelogs/AutoChangeLog-pr-86718.yml b/html/changelogs/AutoChangeLog-pr-86718.yml new file mode 100644 index 00000000000..51b42dc415d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86718.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Snow bears are no longer impervious to all sources of damage" + - bugfix: "Cameras, living floors and ghost of poly no longer can be pushed around" \ No newline at end of file From 8177969052440e0fdd093dc0ec4cad7aebdad005 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:29:43 +0200 Subject: [PATCH 120/142] Collars can no longer be used to null a pet's name (#86719) ## About The Pull Request Closes #86716 ## Changelog :cl: fix: Collars can no longer be used to null a pet's name /:cl: --- code/datums/elements/pet_collar.dm | 2 +- code/modules/clothing/neck/_neck.dm | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/code/datums/elements/pet_collar.dm b/code/datums/elements/pet_collar.dm index 5c49de2eceb..f98767629e7 100644 --- a/code/datums/elements/pet_collar.dm +++ b/code/datums/elements/pet_collar.dm @@ -54,7 +54,7 @@ /datum/element/wears_collar/proc/on_content_enter(mob/living/source, obj/item/clothing/neck/petcollar/new_collar) SIGNAL_HANDLER - if(!istype(new_collar)) + if(!istype(new_collar) || !new_collar.tagname) return source.fully_replace_character_name(null, "\proper [new_collar.tagname]") diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index c7cdb013a3b..7e16bd3bdab 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -456,6 +456,10 @@ /obj/item/clothing/neck/petcollar/attack_self(mob/user) tagname = sanitize_name(tgui_input_text(user, "Would you like to change the name on the tag?", "Pet Naming", "Spot", MAX_NAME_LEN)) + if (!tagname || !length(tagname)) + name = initial(name) + tagname = null + return name = "[initial(name)] - [tagname]" ////////////// From 11c70ba2d42b70ae1b42e2599ee708b9c7d47b9c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:30:04 +0000 Subject: [PATCH 121/142] Automatic changelog for PR #86719 [ci skip] --- html/changelogs/AutoChangeLog-pr-86719.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86719.yml diff --git a/html/changelogs/AutoChangeLog-pr-86719.yml b/html/changelogs/AutoChangeLog-pr-86719.yml new file mode 100644 index 00000000000..6a372edf98d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86719.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Collars can no longer be used to null a pet's name" \ No newline at end of file From 97888e4c570367c248850583433120631c778db4 Mon Sep 17 00:00:00 2001 From: Kocma-san <112967882+Kocma-san@users.noreply.github.com> Date: Wed, 18 Sep 2024 20:24:57 +0700 Subject: [PATCH 122/142] small fixes to disposal pipes at meta, delta and icebox station (#86664) ## About The Pull Request Just removed/corrected disposal pipes on a few maps
deltastation ![image](https://github.com/user-attachments/assets/da2e1d74-7a03-4d1c-abcc-75d7725fa49b) ![image](https://github.com/user-attachments/assets/d8620fc9-afcf-4c1d-9fdb-8e5adfb5f38a) ![image](https://github.com/user-attachments/assets/1b6dcdd5-2061-4be8-a2ce-818352800645)
metastation ![image](https://github.com/user-attachments/assets/521a1fd4-3d09-4ce9-8c05-5c5ad47370d3)
icebox ![image](https://github.com/user-attachments/assets/d22e665a-f0cd-423f-a683-4c5629204831)
## Why It's Good For The Game yes ## Changelog :cl: fix: fixed disposal pipes on metastation, deltastation and icebox /:cl: --- .../map_files/Deltastation/DeltaStation2.dmm | 36 +++---------------- .../map_files/IceBoxStation/IceBoxStation.dmm | 8 +---- _maps/map_files/MetaStation/MetaStation.dmm | 3 -- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 9a7f5ee7689..da57feb2781 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -3236,15 +3236,15 @@ /area/station/ai_monitored/command/storage/eva) "aNM" = ( /obj/structure/cable, -/obj/structure/disposalpipe/junction{ - dir = 4 - }, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, /turf/open/floor/iron, /area/station/maintenance/department/chapel) "aNP" = ( @@ -12212,9 +12212,6 @@ "cXb" = ( /obj/structure/cable, /obj/effect/turf_decal/delivery, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/duct, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ @@ -30878,7 +30875,6 @@ /turf/open/misc/sandy_dirt, /area/station/security/prison/garden) "hHo" = ( -/obj/structure/disposalpipe/trunk, /obj/machinery/chem_heater/withbuffer, /obj/effect/turf_decal/bot_red, /obj/effect/turf_decal/stripes/line{ @@ -32868,9 +32864,6 @@ "ifr" = ( /obj/structure/cable, /obj/effect/turf_decal/delivery, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/duct, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -33704,9 +33697,6 @@ /area/station/hallway/primary/central/fore) "irx" = ( /obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, @@ -44588,13 +44578,13 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "ldl" = ( -/obj/structure/disposalpipe/segment, /obj/machinery/disposal/bin, /obj/effect/turf_decal/bot, /obj/effect/turf_decal/stripes/line{ dir = 6 }, /obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/structure/disposalpipe/trunk, /turf/open/floor/iron/dark, /area/station/medical/pharmacy) "ldm" = ( @@ -45390,9 +45380,6 @@ /area/station/engineering/atmos/storage/gas) "lni" = ( /obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/landmark/generic_maintenance_landmark, @@ -52937,9 +52924,6 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 }, @@ -72156,13 +72140,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/theater/abandoned) -"rZL" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/grille, -/turf/closed/wall/r_wall, -/area/station/engineering/atmos) "rZU" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -96089,9 +96066,6 @@ dir = 4 }, /obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/duct, @@ -117146,7 +117120,7 @@ pxN yfC pxN pxN -rZL +pxN pxN pxN qYo diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index e58006155f9..45a072c6152 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -2371,12 +2371,6 @@ /obj/structure/fluff/shower_drain, /turf/open/floor/iron/freezer, /area/station/commons/toilet) -"aJj" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/closed/wall, -/area/station/service/library) "aJm" = ( /obj/structure/cable, /obj/machinery/door/window/left/directional/east{ @@ -257788,7 +257782,7 @@ qMm hUD pyJ lPh -aJj +hUD hUD ebb cYE diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index df5644bf245..4da82bc90fb 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -47468,9 +47468,6 @@ department = "Mining"; name = "Mining Requests Console" }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/open/floor/iron, /area/station/cargo/miningoffice) "qPs" = ( From adf556278ad49e1b764c248c3c5b1b1465fba530 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:25:19 +0000 Subject: [PATCH 123/142] Automatic changelog for PR #86664 [ci skip] --- html/changelogs/AutoChangeLog-pr-86664.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86664.yml diff --git a/html/changelogs/AutoChangeLog-pr-86664.yml b/html/changelogs/AutoChangeLog-pr-86664.yml new file mode 100644 index 00000000000..4470bc0d76e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86664.yml @@ -0,0 +1,4 @@ +author: "Kocma-san" +delete-after: True +changes: + - bugfix: "fixed disposal pipes on metastation, deltastation and icebox" \ No newline at end of file From 37d5a69e1f379fb3602da3e1fef8ebc9fc8b8a07 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:14:04 +0200 Subject: [PATCH 124/142] You can now link fishing portal generators to other fishing spots. (#86291) ## About The Pull Request You can now interact with the fishing portal generator with a multitool to load it in the buffer and subsequently link fishing spots to it by tapping them with the same multitool. The maximum number of fishing spots that can be linked at once depends on the tier of the matter bins of the machinery. Normally, while you can link fishing spots from other z-levels, they can only be activated if they're on the same z-level as the machinery (or if both are on station for multi-z stations). This limitation can be bypassed by upgrading the machinery with a tier 3 or higher capacitator. While it's possible, I'm not spriting new fishing portal overlays and icons for the radial menu for every fish source out there (yet). The code is enough work for now. This also comes with a unit test, because there is no such thing as too many unit tests for fishing. ## Why It's Good For The Game Fish portal generators are designed to let players fish a different bunch of things while being able to be moved wherever you like, unlike a lake or an ocean, with all the comfort of being able to able to catch fish from distant locations. Allowing players to link other fishing spots to it fits its design. It also means that you can go out and explore, find more fishing spots and then return to the station without having to detach yourself from the ongoing round for several more minutes. ## Changelog :cl: add: You can now link fishing portal generators to other fishing spots with a multitool. The number of fishing spots that can be linked at once and whether the link can be activated from different z levels depends on the tier of the stock parts it's built with. /:cl: --------- Co-authored-by: Emmett Gaines --- code/__DEFINES/dcs/signals/signals_object.dm | 2 + code/__DEFINES/traits/declarations.dm | 2 + code/_globalvars/traits/_traits.dm | 3 +- code/datums/components/fishing_spot.dm | 8 + code/datums/elements/lazy_fishing_spot.dm | 10 + code/game/objects/items/devices/multitool.dm | 11 +- .../modules/fishing/fishing_portal_machine.dm | 206 +++++++++++++++++- code/modules/fishing/sources/_fish_source.dm | 4 + code/modules/fishing/sources/source_types.dm | 11 +- code/modules/unit_tests/fish_unit_tests.dm | 48 ++++ icons/hud/radial_fishing.dmi | Bin 1242 -> 1439 bytes strings/fishing_tips.txt | 2 + 12 files changed, 291 insertions(+), 16 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 651f630db09..1b167de3354 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -194,6 +194,8 @@ #define COMSIG_TOOL_IN_USE "tool_in_use" ///from base of [/obj/item/proc/tool_start_check]: (mob/living/user) #define COMSIG_TOOL_START_USE "tool_start_use" +/// From /obj/item/multitool/remove_buffer(): (buffer) +#define COMSIG_MULTITOOL_REMOVE_BUFFER "multitool_remove_buffer" ///from [/obj/item/proc/disableEmbedding]: #define COMSIG_ITEM_DISABLE_EMBED "item_disable_embed" ///from [/obj/effect/mine/proc/triggermine]: diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 4d6a39e64e1..ba4690b564d 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -239,6 +239,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_EXAMINE_DEEPER_FISH "examine_deeper_fish" ///Trait given to turfs or objects that can be fished from #define TRAIT_FISHING_SPOT "fishing_spot" +///This trait prevents the fishing spot from being linked to the fish-porter when a multitool is being used. +#define TRAIT_UNLINKABLE_FISHING_SPOT "unlinkable_fishing_spot" ///Trait given to mobs that can fish without a rod #define TRAIT_PROFOUND_FISHER "profound_fisher" /// If an atom has this trait, then you can toss a bottle with a message in it. diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 7103c0d3d34..0da91d9e2db 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_DO_NOT_SPLASH" = TRAIT_DO_NOT_SPLASH, "TRAIT_DRIED" = TRAIT_DRIED, "TRAIT_DRYABLE" = TRAIT_DRYABLE, + "TRAIT_FISHING_SPOT" = TRAIT_FISHING_SPOT, "TRAIT_FOOD_CHEF_MADE" = TRAIT_FOOD_CHEF_MADE, "TRAIT_FOOD_FRIED" = TRAIT_FOOD_FRIED, "TRAIT_QUALITY_FOOD_INGREDIENT" = TRAIT_QUALITY_FOOD_INGREDIENT, @@ -30,6 +31,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPINNING" = TRAIT_SPINNING, "TRAIT_STICKERED" = TRAIT_STICKERED, "TRAIT_UNHITTABLE_BY_PROJECTILES" = TRAIT_UNHITTABLE_BY_PROJECTILES, + "TRAIT_UNLINKABLE_FISHING_SPOT" = TRAIT_UNLINKABLE_FISHING_SPOT, ), /atom/movable = list( "TRAIT_ACTIVE_STORAGE" = TRAIT_ACTIVE_STORAGE, @@ -682,7 +684,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CONTAINMENT_FIELD" = TRAIT_CONTAINMENT_FIELD, "TRAIT_ELEVATED_TURF" = TRAIT_ELEVATED_TURF, "TRAIT_FIREDOOR_STOP" = TRAIT_FIREDOOR_STOP, - "TRAIT_FISHING_SPOT" = TRAIT_FISHING_SPOT, "TRAIT_HYPERSPACE_STOPPED" = TRAIT_HYPERSPACE_STOPPED, "TRAIT_IMMERSE_STOPPED" = TRAIT_IMMERSE_STOPPED, "TRAIT_LAVA_STOPPED" = TRAIT_LAVA_STOPPED, diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 5f0fd143444..982b0da2df7 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -20,9 +20,11 @@ RegisterSignal(parent, COMSIG_NPC_FISHING, PROC_REF(return_fishing_spot)) RegisterSignal(parent, COMSIG_ATOM_EX_ACT, PROC_REF(explosive_fishing)) RegisterSignal(parent, COMSIG_FISH_RELEASED_INTO, PROC_REF(fish_released)) + RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(link_to_fish_porter)) ADD_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) /datum/component/fishing_spot/Destroy() + REMOVE_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) fish_source.on_fishing_spot_del(src) fish_source = null REMOVE_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src)) @@ -84,6 +86,12 @@ SIGNAL_HANDLER fish_source.spawn_reward_from_explosion(location, severity) +/datum/component/fishing_spot/proc/link_to_fish_porter(atom/source, mob/user, obj/item/multitool/tool) + SIGNAL_HANDLER + if(istype(tool.buffer, /obj/machinery/fishing_portal_generator)) + var/obj/machinery/fishing_portal_generator/portal = tool.buffer + return portal.link_fishing_spot(fish_source, source, user) + /datum/component/fishing_spot/proc/fish_released(datum/source, obj/item/fish/fish, mob/living/releaser) SIGNAL_HANDLER fish_source.readd_fish(fish, releaser) diff --git a/code/datums/elements/lazy_fishing_spot.dm b/code/datums/elements/lazy_fishing_spot.dm index 1066f0179ea..67edcea2e88 100644 --- a/code/datums/elements/lazy_fishing_spot.dm +++ b/code/datums/elements/lazy_fishing_spot.dm @@ -21,6 +21,7 @@ RegisterSignal(target, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examined_more)) RegisterSignal(target, COMSIG_ATOM_EX_ACT, PROC_REF(explosive_fishing)) RegisterSignal(target, COMSIG_FISH_RELEASED_INTO, PROC_REF(fish_released)) + RegisterSignal(target, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(link_to_fish_porter)) /datum/element/lazy_fishing_spot/Detach(datum/target) UnregisterSignal(target, list( @@ -30,6 +31,7 @@ COMSIG_ATOM_EXAMINE, COMSIG_ATOM_EXAMINE_MORE, COMSIG_ATOM_EX_ACT, + COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), )) REMOVE_TRAIT(target, TRAIT_FISHING_SPOT, REF(src)) return ..() @@ -69,6 +71,14 @@ /datum/element/lazy_fishing_spot/proc/return_glob_fishing_spot(datum/source, list/fish_spot_container) fish_spot_container[NPC_FISHING_SPOT] = GLOB.preset_fish_sources[configuration] +/datum/element/lazy_fishing_spot/proc/link_to_fish_porter(atom/source, mob/user, obj/item/multitool/tool) + SIGNAL_HANDLER + if(!istype(tool.buffer, /obj/machinery/fishing_portal_generator)) + return + var/datum/fish_source/fish_source = GLOB.preset_fish_sources[configuration] + var/obj/machinery/fishing_portal_generator/portal = tool.buffer + return portal.link_fishing_spot(fish_source, source, user) + /datum/element/lazy_fishing_spot/proc/fish_released(datum/source, obj/item/fish/fish, mob/living/releaser) SIGNAL_HANDLER var/datum/fish_source/fish_source = GLOB.preset_fish_sources[configuration] diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index f949f08676e..c0111cd5333 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -35,6 +35,11 @@ var/apc_scanner = TRUE COOLDOWN_DECLARE(next_apc_scan) +/obj/item/multitool/Destroy() + if(buffer) + remove_buffer(buffer) + return ..() + /obj/item/multitool/examine(mob/user) . = ..() . += span_notice("Its buffer [buffer ? "contains [buffer]." : "is empty."]") @@ -70,9 +75,10 @@ /obj/item/multitool/proc/set_buffer(datum/buffer) if(src.buffer) UnregisterSignal(src.buffer, COMSIG_QDELETING) + remove_buffer(src.buffer) src.buffer = buffer if(!QDELETED(buffer)) - RegisterSignal(buffer, COMSIG_QDELETING, PROC_REF(on_buffer_del)) + RegisterSignal(buffer, COMSIG_QDELETING, PROC_REF(remove_buffer)) /** * Called when the buffer's stored object is deleted @@ -80,8 +86,9 @@ * This proc does not clear the buffer of the multitool, it is here to * handle the deletion of the object the buffer references */ -/obj/item/multitool/proc/on_buffer_del(datum/source) +/obj/item/multitool/proc/remove_buffer(datum/source) SIGNAL_HANDLER + SEND_SIGNAL(src, COMSIG_MULTITOOL_REMOVE_BUFFER, source) buffer = null // Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby. diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm index 9444d1368e3..f322bf92c78 100644 --- a/code/modules/fishing/fishing_portal_machine.dm +++ b/code/modules/fishing/fishing_portal_machine.dm @@ -11,6 +11,46 @@ ///The current fishing spot loaded in var/datum/component/fishing_spot/active + ///A list of fishing spot it's linked to with a multitool. + var/list/linked_fishing_spots + ///The maximum number of fishing spots it can be linked to + var/max_fishing_spots = 1 + ///If true, the fishing portal can stay connected to a linked fishing spot even on different z-levels + var/long_range_link = FALSE + +/obj/machinery/fishing_portal_generator/Initialize(mapload) + . = ..() + var/static/list/tool_screentips = list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Link", + SCREENTIP_CONTEXT_RMB = "Unlink fishing spots" + ), + ) + AddElement(/datum/element/contextual_screentip_tools, tool_screentips) + ADD_TRAIT(src, TRAIT_UNLINKABLE_FISHING_SPOT, INNATE_TRAIT) + +/obj/machinery/fishing_portal_generator/Destroy() + deactivate() + linked_fishing_spots = null + return ..() + +///Higher tier parts let you link to more fishing spots at once and eventually let you connect through different zlevels. +/obj/machinery/fishing_portal_generator/RefreshParts() + . = ..() + max_fishing_spots = 0 + long_range_link = FALSE + for(var/datum/stock_part/matter_bin/matter_bin in component_parts) + max_fishing_spots += matter_bin.tier * 0.5 + max_fishing_spots = ROUND_UP(max_fishing_spots) + for(var/datum/stock_part/capacitor/capacitor in component_parts) + if(capacitor.tier >= 3) + long_range_link = TRUE + if(!long_range_link) + check_fishing_spot_z() + if(length(linked_fishing_spots) > max_fishing_spots) + if(active) + deactivate() + linked_fishing_spots.len = max_fishing_spots /obj/machinery/fishing_portal_generator/on_set_panel_open() update_appearance() @@ -21,9 +61,94 @@ default_unfasten_wrench(user, tool) return ITEM_INTERACT_SUCCESS +/obj/machinery/fishing_portal_generator/multitool_act(mob/living/user, obj/item/multitool/tool) + if(machine_stat & NOPOWER) + balloon_alert(user, "no power!") + return ITEM_INTERACT_BLOCKING + var/unlink = tool.buffer == src + tool.set_buffer(unlink ? null : src) + balloon_alert(user, "fish-porter [unlink ? "un" : ""]linked") + if(!unlink) + tool.item_flags |= ITEM_HAS_CONTEXTUAL_SCREENTIPS + RegisterSignal(tool, COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, PROC_REF(multitool_context)) + RegisterSignal(tool, COMSIG_MULTITOOL_REMOVE_BUFFER, PROC_REF(multitool_unbuffered)) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/fishing_portal_generator/multitool_act_secondary(mob/living/user, obj/item/tool) + if(machine_stat & NOPOWER) + balloon_alert(user, "no power!") + return ITEM_INTERACT_BLOCKING + if(!length(linked_fishing_spots)) + balloon_alert(user, "nothing to unlink!") + return ITEM_INTERACT_BLOCKING + var/list/fishing_list = list() + var/id = 1 + for(var/atom/spot as anything in linked_fishing_spots) + var/choice_name = "[spot.name] ([id])" + fishing_list[choice_name] = spot + id++ + var/list/choices = list() + for(var/radial_name in fishing_list) + var/datum/fish_source/source = fishing_list[radial_name] + var/mutable_appearance/appearance = mutable_appearance('icons/hud/radial_fishing.dmi', source.radial_state) + appearance.add_overlay('icons/hud/radial_fishing.dmi', "minus_sign") + choices[radial_name] = appearance + + var/choice = show_radial_menu(user, src, choices, radius = 38, custom_check = CALLBACK(src, TYPE_PROC_REF(/atom, can_interact), user), tooltips = TRUE) + if(!choice) + return + var/atom/spot = fishing_list[choice] + if(QDELETED(spot) || !(spot in linked_fishing_spots) || !can_interact(user)) + return + unlink_fishing_spot(spot) + balloon_alert(user, "fishing spot unlinked") + +/obj/machinery/fishing_portal_generator/proc/multitool_context(obj/item/source, list/context, atom/target, mob/living/user) + SIGNAL_HANDLER + if(HAS_TRAIT(target, TRAIT_FISHING_SPOT) && !HAS_TRAIT(target, TRAIT_UNLINKABLE_FISHING_SPOT)) + context[SCREENTIP_CONTEXT_LMB] = "Link to fish-porter" + return CONTEXTUAL_SCREENTIP_SET + return NONE + +/obj/machinery/fishing_portal_generator/proc/multitool_unbuffered(datum/source, datum/buffer) + SIGNAL_HANDLER + UnregisterSignal(source, list(COMSIG_ITEM_REQUESTING_CONTEXT_FOR_TARGET, COMSIG_MULTITOOL_REMOVE_BUFFER)) + +///Called when using a multitool on any other fishing source. +/obj/machinery/fishing_portal_generator/proc/link_fishing_spot(datum/fish_source/source, atom/spot, mob/living/user) + if(istype(spot, /obj/machinery/fishing_portal_generator)) //Don't link it to itself or other fishing portals. + return + if(length(linked_fishing_spots) >= max_fishing_spots) + spot.balloon_alert(user, "cannot link more!") + return ITEM_INTERACT_BLOCKING + for(var/other_spot in linked_fishing_spots) + var/datum/fish_source/stored = linked_fishing_spots[other_spot] + if(stored == source) + spot.balloon_alert(user, "already linked!") + playsound(src, 'sound/machines/buzz-sigh.ogg', 15, FALSE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + return ITEM_INTERACT_BLOCKING + if(HAS_TRAIT(spot, TRAIT_UNLINKABLE_FISHING_SPOT)) + spot.balloon_alert(user, "unlinkable fishing spot!") + playsound(src, 'sound/machines/buzz-sigh.ogg', 15, FALSE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + return ITEM_INTERACT_BLOCKING + LAZYSET(linked_fishing_spots, spot, source) + RegisterSignal(spot, SIGNAL_REMOVETRAIT(TRAIT_FISHING_SPOT), PROC_REF(unlink_fishing_spot)) + spot.balloon_alert(user, "fishing spot linked") + playsound(spot, 'sound/machines/ping.ogg', 15, TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/fishing_portal_generator/proc/unlink_fishing_spot(atom/spot) + SIGNAL_HANDLER + var/datum/fish_source/source = linked_fishing_spots[spot] + if(active?.fish_source == source) + deactivate() + LAZYREMOVE(linked_fishing_spots, spot) + UnregisterSignal(spot, SIGNAL_REMOVETRAIT(TRAIT_FISHING_SPOT)) + /obj/machinery/fishing_portal_generator/examine(mob/user) . = ..() - . += span_notice("You can unlock further portal settings by completing fish scanning experiments.") + . += span_notice("You can unlock further portal settings by completing fish scanning experiments, \ + or by connecting it to other fishing spots with a multitool.") /obj/machinery/fishing_portal_generator/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) @@ -47,21 +172,78 @@ if(!active) return . += "portal_on" - var/datum/fish_source/portal/portal = active.fish_source + var/datum/fish_source/portal = active.fish_source . += portal.overlay_state . += emissive_appearance(icon, "portal_emissive", src) -/obj/machinery/fishing_portal_generator/proc/activate(datum/fish_source/selected_source) +/obj/machinery/fishing_portal_generator/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) + . = ..() + check_fishing_spot_z() + +/obj/machinery/fishing_portal_generator/proc/check_fishing_spot_z() + if(!active || long_range_link || istype(active.fish_source, /datum/fish_source/portal)) + return + var/turf/new_turf = get_turf(src) + if(!new_turf) + deactivate() + return + for(var/atom/spot as anything in linked_fishing_spots) + if(linked_fishing_spots[spot] != active.fish_source) + continue + var/turf/turf = get_turf(spot) + if(turf.z != new_turf.z && !(is_station_level(turf.z) && is_station_level(new_turf.z))) + deactivate() + +/obj/machinery/fishing_portal_generator/proc/activate(datum/fish_source/selected_source, mob/user) + if(QDELETED(selected_source)) + return + if(machine_stat & NOPOWER) + balloon_alert(user, "no power!") + return ITEM_INTERACT_BLOCKING + if(!istype(selected_source, /datum/fish_source/portal)) //likely from a linked fishing spot + var/abort = TRUE + for(var/atom/spot as anything in linked_fishing_spots) + if(linked_fishing_spots[spot] != selected_source) + continue + if(long_range_link) + abort = FALSE + var/turf/spot_turf = get_turf(spot) + var/turf/turf = get_turf(src) + if(turf.z == spot_turf.z || (is_station_level(turf.z) && is_station_level(spot_turf.z))) + abort = FALSE + if(!abort) + RegisterSignal(spot, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_fishing_spot_z_level_changed)) + break + if(abort) + balloon_alert(user, "cannot reach linked!") + return + active = AddComponent(/datum/component/fishing_spot, selected_source) ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) - use_power = ACTIVE_POWER_USE + if(use_power != NO_POWER_USE) + use_power = ACTIVE_POWER_USE update_icon() /obj/machinery/fishing_portal_generator/proc/deactivate() + if(!active) + return + if(!istype(active.fish_source, /datum/fish_source/portal)) + for(var/atom/spot as anything in linked_fishing_spots) + if(linked_fishing_spots[spot] == active.fish_source) + UnregisterSignal(spot, COMSIG_MOVABLE_Z_CHANGED) QDEL_NULL(active) - use_power = IDLE_POWER_USE + REMOVE_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) - update_icon() + if(!QDELETED(src)) + if(use_power != NO_POWER_USE) + use_power = IDLE_POWER_USE + update_icon() + +/obj/machinery/fishing_portal_generator/proc/on_fishing_spot_z_level_changed(atom/spot, turf/old_turf, turf/new_turf, same_z_layer) + SIGNAL_HANDLER + var/turf/turf = get_turf(src) + if(turf.z != new_turf.z && !(is_station_level(turf.z) && is_station_level(new_turf.z))) + deactivate() /obj/machinery/fishing_portal_generator/on_set_is_operational(old_value) if(old_value) @@ -90,18 +272,24 @@ var/datum/fish_source/portal/reward = GLOB.preset_fish_sources[experiment.fish_source_reward] available_fish_sources[reward.radial_name] = reward + var/id = 1 + for(var/atom/spot as anything in linked_fishing_spots) + var/choice_name = "[spot.name] ([id])" + available_fish_sources[choice_name] = linked_fishing_spots[spot] + id++ + if(length(available_fish_sources) == 1) - activate(default) + activate(default, user) return var/list/choices = list() for(var/radial_name in available_fish_sources) - var/datum/fish_source/portal/source = available_fish_sources[radial_name] + var/datum/fish_source/source = available_fish_sources[radial_name] choices[radial_name] = image(icon = 'icons/hud/radial_fishing.dmi', icon_state = source.radial_state) var/choice = show_radial_menu(user, src, choices, radius = 38, custom_check = CALLBACK(src, TYPE_PROC_REF(/atom, can_interact), user), tooltips = TRUE) if(!choice || !can_interact(user)) return - activate(available_fish_sources[choice]) + activate(available_fish_sources[choice], user) /obj/machinery/fishing_portal_generator/emagged obj_flags = parent_type::obj_flags | EMAGGED diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 815f3c34d23..38455068ce2 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -82,6 +82,10 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) var/explosive_malus = FALSE /// If explosive_malus is true, this will be used to keep track of the turfs where an explosion happened for when we'll spawn the loot. var/list/exploded_turfs + ///When linked to a fishing portal, this will be the icon_state of this option in the radial menu + var/radial_state = "default" + ///When selected by the fishing portal, this will be the icon_state of the overlay shown on the machine. + var/overlay_state = "portal_aquarium" /// Mindless mobs that can fish will never pull up items on this list var/static/list/profound_fisher_blacklist = typecacheof(list( /mob/living/basic/mining/lobstrosity, diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index 95eb10a04aa..ef2cdf87989 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -106,12 +106,9 @@ /obj/item/fish/goldfish/three_eyes = 3, ) catalog_description = "Aquarium dimension (Fishing portal generator)" + radial_state = "fish_tank" ///The name of this option shown in the radial menu on the fishing portal generator var/radial_name = "Aquarium" - ///The icon state shown for this option in the radial menu - var/radial_state = "fish_tank" - ///The icon state of the overlay shown on the machine when active. - var/overlay_state = "portal_aquarium" /datum/fish_source/portal/beach fish_table = list( @@ -404,6 +401,12 @@ ) fishing_difficulty = FISHING_EASY_DIFFICULTY +/datum/fish_source/holographic/on_fishing_spot_init(datum/component/fishing_spot/spot) + ADD_TRAIT(spot.parent, TRAIT_UNLINKABLE_FISHING_SPOT, REF(src)) //You would have to be inside the holodeck anyway... + +/datum/fish_source/holographic/on_fishing_spot_del(datum/component/fishing_spot/spot) + REMOVE_TRAIT(spot.parent, TRAIT_UNLINKABLE_FISHING_SPOT, REF(src)) + /datum/fish_source/holographic/generate_wiki_contents(datum/autowiki/fish_sources/wiki) var/obj/item/fish/prototype = /obj/item/fish/holo/checkered return LIST_VALUE_WRAP_LISTS(list( diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index 91d0c006522..809bf60d230 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -190,6 +190,54 @@ . = ..() probability = 0 //works around the global list initialization skipping abstract/impossible evolutions. +///A test that checks that fishing portals can be linked and function as expected +/datum/unit_test/fish_portal_gen_linking + +/datum/unit_test/fish_portal_gen_linking/Run() + var/mob/living/carbon/human/consistent/user = allocate(/mob/living/carbon/human/consistent) + var/obj/machinery/fishing_portal_generator/portal = allocate(/obj/machinery/fishing_portal_generator/no_power) + var/obj/structure/toilet/unit_test/fishing_spot = new(get_turf(user)) //This is deleted during the test + var/obj/structure/moisture_trap/extra_spot = allocate(/obj/structure/moisture_trap) + var/obj/machinery/hydroponics/constructable/inaccessible = allocate(/obj/machinery/hydroponics/constructable) + ADD_TRAIT(inaccessible, TRAIT_UNLINKABLE_FISHING_SPOT, INNATE_TRAIT) + var/obj/item/multitool/tool = allocate(/obj/item/multitool) + var/datum/fish_source/toilet/fish_source = GLOB.preset_fish_sources[/datum/fish_source/toilet] + + portal.max_fishing_spots = 1 //We've no scrying orb to know if it'll be buffed or nerfed this in the future. We only have space for one here. + portal.activate(fish_source, user) + TEST_ASSERT(!portal.active, "[portal] was activated with a fish source from an unlinked fishing spot") + portal.multitool_act(user, tool) + TEST_ASSERT_EQUAL(tool.buffer, portal, "[portal] wasn't set as buffer for [tool]") + tool.melee_attack_chain(user, fishing_spot) + TEST_ASSERT_EQUAL(LAZYACCESS(portal.linked_fishing_spots, fishing_spot), fish_source, "We tried linking [portal] to the fishing spot but didn't succeed.") + portal.activate(fish_source, user) + TEST_ASSERT(portal.active?.fish_source == fish_source, "[portal] can't acces a fish source from a linked fishing spot") + //Let's move the fishing spot away. This is fine as long as the portal moves to another z level, away from the toilet + var/turf/other_z_turf = pick(GLOB.newplayer_start) + portal.forceMove(other_z_turf) + TEST_ASSERT(!portal.active, "[portal] (not upgraded) is still active though the fishing spot is on another z-level.[portal.z == fishing_spot.z ? " Actually they're still on the same level!" : ""]") + portal.long_range_link = TRUE + portal.activate(fish_source, user) + TEST_ASSERT(portal.active?.fish_source == fish_source, "[portal] can't acces a fish source from a linked fishing spot on a different z-level despite being upgraded") + fishing_spot.forceMove(other_z_turf) + portal.forceMove(get_turf(user)) + TEST_ASSERT(portal.active?.fish_source == fish_source, "[portal] (upgraded) deactivated while changing z-level") + tool.melee_attack_chain(user, extra_spot) + TEST_ASSERT_EQUAL(length(portal.linked_fishing_spots), 1, "We managed to link to another fishing spot when there's only space for one") + TEST_ASSERT_EQUAL(LAZYACCESS(portal.linked_fishing_spots, fishing_spot), fish_source, "linking to another fishing spot fouled up the other linked spots") + QDEL_NULL(fishing_spot) + TEST_ASSERT(!portal.active, "[portal] is still linked to the fish source of the deleted fishing spot it's associated to") + tool.melee_attack_chain(user, inaccessible) + TEST_ASSERT(!length(portal.linked_fishing_spots), "We managed to link to an unlinkable fishing spot") + +/obj/machinery/fishing_portal_generator/no_power + use_power = NO_POWER_USE + +/obj/structure/toilet/unit_test/Initialize(mapload) + . = ..() + if(!HAS_TRAIT(src, TRAIT_FISHING_SPOT)) //Ensure this toilet has a fishing spot because only maploaded ones have it. + AddElement(/datum/element/lazy_fishing_spot, /datum/fish_source/toilet) + // we want no default spawns in this unit test /datum/chasm_detritus/restricted/bodies/no_defaults default_contents_chance = 0 diff --git a/icons/hud/radial_fishing.dmi b/icons/hud/radial_fishing.dmi index 65fd55176b7c82eebfb1e59fd2bc666339329be3..6870698fbe689eb1c607bd7578aad0e3f9eefde4 100644 GIT binary patch delta 1321 zcmV+^1=jl737-p)BmtI@C1-zdSAF9x0HdeEczm1R;ONWD*?Kr@vjzb5^Ygk{Zf$Xr z^S3maQ+NN&GtrGU;i56paW7w!8#@3100DGTPE!Ct=GbNc006^!R9JLGWpiV4X>fFD zZ*Bkpc$|%q%?iRW5QNXoQv|(>e^)P}NDul7VcTq*rA<<^iQ?NEEO>vDc$-;1*kNWV zkLOE$lc#Gf9vGOslLxt9twr@D9Zfd7t*8uAZ{ln?Lc}Z=9kEdn+^`Uproj2O5mgt! z;;g^q1fx|ALTid>AAE9J89!o?WrW5T!NMkvSC6|9#aena&UCQ(A^qKDsoRo&mNg_qX000B%Nklz0}@ z6om;6-l(l84m#BtTSlg!Ain?0^_+xYASbA>T{&Ft4U|GHXA2If1f7`yB zz}gJv9sonZ=U^~sLlBQQ-SL7#`&I-7F+dc|2onA;FM|P4TKIoEjxFUl4q+exLJt!F zpo#);bs}6NFh9+P!-2p&NI?J5XmpDJ{zJIN29E*?|Iv*Y3V)F=?ILSx5gEYP9*@T+ z0QwINBWG+fnF>t^1cL(b@w?#fxV9N!@<-!osrp^l3cFl%2n_+SsRT@>Jd)aN3IGvg z5g@ll0Gpuuw?cpXNA*5+n$cBeY&M%AU`ExDq5Jnz$j|`J4@KHkL;F%h15Fisj+p2< zssbAP5up({V8Z`%08wS9DFB=!qeenC0;*3zHoDu?S|kWp3Sqz)CZD^Trdrcl2M?(P zx|hroSzMkA_qpK~Rzhh1+qy9V<(78-y?XWPCH3URgfV|lsLgVF$6^Tf3zWAc2;%%M z&hWIoU&y@TFQkYVn0lz74i0{)m2VhTv!4I%8_7453?U_0`W5X|TE z{d!GJWmc?lWj7IkLTJCM1N;$Y39|p;uGf2gHDbb^1E}4A)g!1s4`sH+91DODtcU=- zB0~YW-!M6HA-$8g*TvM`@Ad1LA=yUWf+|D9_ys{CR<7=^uBNyzkgqr;!nC7pk+E7) zMYMlplVX}^f2;eREU)!1D7|_;U%wPR2k^U89T0}$=Mw>8csN8+cf!}7QePGSIEtb} zd}t&j_W%@C{14Ib7{+l^mXcF?2Z2-wV?SEfXB;;rsS6;EkCuqT3`nxmxh)~&0o(-S ztpU(O+`lP9Nd|!S1WqwE(Io+01OUI@(@lR50g_XeWv3hgIecwh>(E$%6n(QiKjUYI zG=))UxRS!q^X!C-E@cQK<4jI5JMgb-nIq#&PR^$s)Xl$PK~3^3JD;Hjc{jqRF#z7A z=e&Ijp~BEqWbS`SFWm?YGnp?Fsg*)EWt{+q5+tWQ6}~A)ih1pt`r?W fFxI$NuYab$fyslZD}|$g00000NkvXXu0mjf;PzC6 delta 1122 zcmV-o1fBbz3)%^gBmsDlC1-!Yz`&!Y!gzd}-{9!W%-Qwx^KEgGybpbf00001bW%=J z06^y0W&i*HwR%)obVOxyV{&P5bZKvH004NLjgY+#f-n??=k_TY*o}Xyi@_KMd4=Xe zFSLQS*jqHdy^SPprf%n)e8b6Ciu2`KH=?@L{DFatcj6?Dn=NNgqoRLK<*?^WqZxEu z3q^>SV$mDYGJ+cm&Xft1wjF1E0E=t>k~2(Jwg{chqC@bDQ&Rg0vn(OB9%7!Gp+gyb zH{u`g%PAwt!I(c_4Z&mvhf3ZTq?qhU3*o1bQe2wqHtNtAU zIQIAbPZMCtU_Ju?5`G3ju!Nux$QWpV z(w7McFvS6+zD0OMF#R+{QJ^qiB#?g`$Il4pAK^6!z6$94<0pSHbp9$|)F}Mh=i9Tcw0S02V-wKSlpA^``+-{$#xEHNNXn;Z%wbVI~0BYCy7;k&JFL z0EA$RfVrInKtk?6I>{fy`^;&^R~cZp+Yw;L)ey-2XD?z{fbf?gYpRibFQ$REhP^~2 zc8-RC8Gk}p1POmgj5S~1#k)xk*OM31Olixhg^SS0RAi>JmCSK2qpe_;{ZK@0lX^t zPXRK9;_ZL;n+;Go^59^102#gxGz6R#LB%Kp6Tzd(NErKfDS8Uf2Qx{q8r2}!fD7u~ z^vB-=fZr2@$Uc}N%iCazAOR-f9W{)=k2``8*OUcxE8$ECmv=*#;XF9U1rbD+W!K}8 zo669waeX&2fKFt883T%#vV__HNRP*>y&8eCmjHimH-K>jlp)RzW=G4Bfo5mfXYMZ91+u9YOYU}2HuiDm8mMR?k-Scj3 z>nK)9IP|-x;&271-2$+Oq`#{SX^Oih`da{J73c{~06837XyAqRPXGV_07*qoM6N<$f`Z}@X#fBK diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index ce8f601d375..6b25cc5e539 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -15,6 +15,8 @@ You may find worms by digging through sand, ash and snow. You can revive fish by using a Lazarus Injector on them. However, using Strange Reagent would be a smarter option here. You can feed fish outside of an aquarium by tapping them with a can of fish feed. More fishing rods and fish cases can be printed at the autolathe. +You can link the fish portal generator to other fishing spots with a multitool. The maximum amount of fishing spots that can be linked and whether or not the link works on different z-levels depends on the quality of the machinery components. +The actual name of the fishing portal generator is 'fish-porter 3000'. They're totally the same thing however. Seeking alternative ways to catch fish without bothering to do it yourself? Explosives can be thrown at fishing spots to get several (dead) fishes in a pinch. You can raise lobstrosities from chasm chrabs. However, lobstrosities can only be tamed with spare limbs or lavaloop fish while still young. Lavaloop fish make for dangerous yet somewhat effective throwing weapons against big fauna. From 6a441adb1ee4e17b5468ba66a6bd6d209d218c14 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:14:25 +0000 Subject: [PATCH 125/142] Automatic changelog for PR #86291 [ci skip] --- html/changelogs/AutoChangeLog-pr-86291.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86291.yml diff --git a/html/changelogs/AutoChangeLog-pr-86291.yml b/html/changelogs/AutoChangeLog-pr-86291.yml new file mode 100644 index 00000000000..2b785cedc1c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86291.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "You can now link fishing portal generators to other fishing spots with a multitool. The number of fishing spots that can be linked at once and whether the link can be activated from different z levels depends on the tier of the stock parts it's built with." \ No newline at end of file From 13789c58be8d90adc67c27ed9ee76af7e32ef162 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:33:47 +0200 Subject: [PATCH 126/142] Vore victims no longer get digested instantly when you evolve (#86722) ## About The Pull Request Partially handles #86685 Moving all organs/contents is a pretty bad idea and I'm not sure if there's a cleaner way to do it for the first point in the issue. ## Changelog :cl: fix: Vore victims no longer get digested instantly when you evolve /:cl: --- code/modules/mob/living/carbon/alien/adult/queen.dm | 7 +++---- code/modules/mob/living/carbon/alien/alien.dm | 5 +++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/adult/queen.dm b/code/modules/mob/living/carbon/alien/adult/queen.dm index 4387f7db3ec..a925b4c5460 100644 --- a/code/modules/mob/living/carbon/alien/adult/queen.dm +++ b/code/modules/mob/living/carbon/alien/adult/queen.dm @@ -168,10 +168,9 @@ span_noticealien("The queen has granted you a promotion to Praetorian!"), ) - var/mob/living/carbon/alien/adult/royal/praetorian/new_prae = new(to_promote.loc) - to_promote.mind.transfer_to(new_prae) - - qdel(to_promote) + var/mob/living/carbon/alien/lucky_winner = to_promote + var/mob/living/carbon/alien/adult/royal/praetorian/new_prae = new(lucky_winner.loc) + lucky_winner.alien_evolve(new_prae) qdel(src) return TRUE diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index f9d4c7c03cd..3c738b2fd77 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -125,6 +125,11 @@ Des: Removes all infected images from the alien. mind.name = new_xeno.real_name mind.transfer_to(new_xeno) + var/obj/item/organ/internal/stomach/alien/melting_pot = get_organ_slot(ORGAN_SLOT_STOMACH) + var/obj/item/organ/internal/stomach/alien/frying_pan = new_xeno.get_organ_slot(ORGAN_SLOT_STOMACH) + if(istype(melting_pot) && istype(frying_pan)) + for (var/atom/movable/poor_sod as anything in melting_pot.stomach_contents) + frying_pan.consume_thing(poor_sod) qdel(src) /// Changes the name of the xeno we are evolving into in order to keep the same numerical identifier the old xeno had. From 917a4340349c005942a015c45be13d83893d10c2 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:34:08 +0000 Subject: [PATCH 127/142] Automatic changelog for PR #86722 [ci skip] --- html/changelogs/AutoChangeLog-pr-86722.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86722.yml diff --git a/html/changelogs/AutoChangeLog-pr-86722.yml b/html/changelogs/AutoChangeLog-pr-86722.yml new file mode 100644 index 00000000000..d4ed238ce34 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86722.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Vore victims no longer get digested instantly when you evolve" \ No newline at end of file From ade4ce81d70f92784862772f5c5a22b99ef8fbd9 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:13:19 +0200 Subject: [PATCH 128/142] You can try to pet fish while holding them too (careful around aggressive ones) (#86594) ## About The Pull Request Earlier this day, I have found myelf adding a check to the fish petting proc Ben added recently along with his aquarium UI rework, so I've thought it'd be good if players could do it regardless of aquariums. I've also added a couple lines to check if it's a safe environment and the fish isn't dead, because petting a dead or drowning fish shouldn't solicit much of a cute reaction. Furthermore, petting aggressive fish comes with a coin flip where you get your hand bitten half of the times. I think it's a pretty much reasonable interaction. Also, petting chasm crabs lowers their anger slightly, which determines the behavior of the juvenile lobstrosity they grow to be. ## Why It's Good For The Game Polishing a fish feature added by another contributor. ## Changelog :cl: add: You can pet fish while holding them. Be wary of petting aggressive fish. /:cl: --- code/__DEFINES/dcs/signals/signals_fish.dm | 2 - code/datums/components/aquarium_content.dm | 6 -- .../mood_events/generic_positive_events.dm | 11 ++++ code/modules/fishing/fish/_fish.dm | 60 +++++++++++++++++-- code/modules/fishing/fish/types/mining.dm | 5 ++ 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index 45f90e9b9b2..9b614f92454 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -26,8 +26,6 @@ #define COMSIG_GENERATE_REAGENTS_TO_ADD "generate_reagents_to_add" ///From /obj/item/fish/feed: (fed_reagents, fed_reagent_type) #define COMSIG_FISH_FED "fish_on_fed" -///from /obj/item/fish/pet_fish -#define COMSIG_FISH_PETTED "fish_petted" ///From /obj/item/fish/update_size_and_weight: (new_size, new_weight) #define COMSIG_FISH_UPDATE_SIZE_AND_WEIGHT "fish_update_size_and_weight" ///From /obj/item/fish/update_fish_force: (weight_rank, bonus_malus) diff --git a/code/datums/components/aquarium_content.dm b/code/datums/components/aquarium_content.dm index 69ab47b87dc..d956b39928a 100644 --- a/code/datums/components/aquarium_content.dm +++ b/code/datums/components/aquarium_content.dm @@ -53,7 +53,6 @@ ADD_TRAIT(parent, TRAIT_FISH_CASE_COMPATIBILE, REF(src)) RegisterSignal(parent, COMSIG_TRY_INSERTING_IN_AQUARIUM, PROC_REF(is_ready_to_insert)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(enter_aquarium)) - RegisterSignal(parent, COMSIG_FISH_PETTED, PROC_REF(on_fish_petted)) if(isfish(parent)) RegisterSignal(parent, COMSIG_FISH_STATUS_CHANGED, PROC_REF(on_fish_status_changed)) @@ -168,11 +167,6 @@ current_aquarium.free_layer(vc_obj.layer) vc_obj.layer = current_aquarium.request_layer(vc_obj.layer_mode) -/datum/component/aquarium_content/proc/on_fish_petted() - SIGNAL_HANDLER - - new /obj/effect/temp_visual/heart(get_turf(parent)) - /datum/component/aquarium_content/proc/on_removed(obj/structure/aquarium/source, atom/movable/gone, direction) SIGNAL_HANDLER if(parent != gone) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 6ca1ecc0e6e..3ec4264b125 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -350,6 +350,17 @@ else description = "Returned to the burden of the deep. But is this truly a mercy, [fish.name]? There will always be bigger fish..." +/datum/mood_event/fish_petting + description = "It felt nice to pet the fish." + mood_change = 2 + timeout = 2 MINUTES + +/datum/mood_event/fish_petting/add_effects(obj/item/fish/fish, morbid) + if(!morbid) + description = "It felt nice to pet \the [fish]." + else + description = "I caress \the [fish] as [fish.p_they()] squirms under my touch, blissfully unaware of how cruel this world is." + /datum/mood_event/kobun description = "You are all loved by the Universe. I’m not alone, and you aren’t either." mood_change = 14 diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 2831d2c166b..494d74c5ef7 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -175,14 +175,27 @@ update_size_and_weight() register_evolutions() + register_context() register_item_context() -/obj/item/fish/add_context(atom/source, list/context, obj/item/held_item, mob/user) +/obj/item/fish/add_item_context(atom/source, list/context, obj/item/held_item, mob/user) if(HAS_TRAIT(source, TRAIT_CATCH_AND_RELEASE)) context[SCREENTIP_CONTEXT_RMB] = "Release" return CONTEXTUAL_SCREENTIP_SET return NONE +/obj/item/fish/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(src == held_item) + context[SCREENTIP_CONTEXT_LMB] = "Pet" + return CONTEXTUAL_SCREENTIP_SET + if(istype(held_item, /obj/item/fish_feed)) + context[SCREENTIP_CONTEXT_LMB] = "Feed" + return CONTEXTUAL_SCREENTIP_SET + if(istype(held_item, /obj/item/fish_analyzer)) + context[SCREENTIP_CONTEXT_LMB] = "Scan" + return CONTEXTUAL_SCREENTIP_SET + return NONE + /obj/item/fish/interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers) if(!HAS_TRAIT(interacting_with, TRAIT_CATCH_AND_RELEASE)) return NONE @@ -1163,16 +1176,53 @@ happiness_value -= 1 return clamp(happiness_value, FISH_SAD, FISH_VERY_HAPPY) +/obj/item/fish/attack_self(mob/living/user) + . = ..() + pet_fish(user) + /obj/item/fish/proc/pet_fish(mob/living/user) + var/in_aquarium = isaquarium(loc) + if(status == FISH_DEAD) + to_chat(user, span_warning("You try to pet [src], but [p_theyre()] motionless!")) + return FALSE + if(!proper_environment()) + to_chat(user, span_warning("You try to pet [src], but [p_theyre()] not feeling well!")) + return FALSE if(fish_flags & FISH_FLAG_PETTED) - to_chat(user, span_warning("[src] runs away from your finger as you dip it into the water!")) - return + if(in_aquarium) + to_chat(user, span_warning("[src] runs away from your finger as you dip it into the water!")) + else + to_chat(user, span_warning("You try to pet [src] but [p_they()] squirms away!")) + return FALSE if(HAS_TRAIT(src, TRAIT_FISH_ELECTROGENESIS) && GET_FISH_ELECTROGENESIS(src) > 15 MEGA JOULES) user.electrocute_act(5, src) //was it all worth it? fish_flags |= FISH_FLAG_PETTED - SEND_SIGNAL(src, COMSIG_FISH_PETTED) - to_chat(user, span_notice("[src] dances around!")) + new /obj/effect/temp_visual/heart(get_turf(src)) + if((/datum/fish_trait/aggressive in fish_traits) && prob(50)) + if(!in_aquarium) + user.visible_message( + span_warning("[src] dances around before biting [user]!"), + span_warning("[src] dances around before biting you!"), + vision_distance = DEFAULT_MESSAGE_RANGE - 3, + ) + else + user.visible_message( + span_warning("[src] bites [user]'s hand!"), + span_warning("You pet [src] as you hold it, only for [p_them()] to happily bite back!"), + vision_distance = DEFAULT_MESSAGE_RANGE - 3, + ) + var/body_zone = pick(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM) + user.apply_damage((force * 0.2) + w_class * 2, BRUTE, body_zone, user.run_armor_check(body_zone, MELEE)) + playsound(src,'sound/weapons/bite.ogg', 45, TRUE, -1) + else + if(in_aquarium) + to_chat(user, span_notice("[src] dances around!")) + else + to_chat(user, span_notice("You pet [src] as you hold it.")) + user.add_mood_event("petted_fish", /datum/mood_event/fish_petting, src, HAS_MIND_TRAIT(user, TRAIT_MORBID)) + playsound(src, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1) addtimer(CALLBACK(src, PROC_REF(undo_petted)), 30 SECONDS) + return TRUE /obj/item/fish/proc/undo_petted() fish_flags &= ~FISH_FLAG_PETTED diff --git a/code/modules/fishing/fish/types/mining.dm b/code/modules/fishing/fish/types/mining.dm index f70e557fdc8..0b29143dd5b 100644 --- a/code/modules/fishing/fish/types/mining.dm +++ b/code/modules/fishing/fish/types/mining.dm @@ -64,6 +64,11 @@ AddComponent(/datum/component/fish_growth, lob_type, initial(growth_rate) * multiplier) +/obj/item/fish/chasm_crab/pet_fish(mob/living/user) + . = ..() + if(.) + anger -= min(anger, 6.5) + /obj/item/fish/chasm_crab/proc/growth_checks(datum/source, seconds_per_tick) SIGNAL_HANDLER var/hunger = CLAMP01((world.time - last_feeding) / feeding_frequency) From 6ca1443ca6f5d1f76c64bbdcdefe98e0f93cb66c Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 20:13:44 +0000 Subject: [PATCH 129/142] Automatic changelog for PR #86594 [ci skip] --- html/changelogs/AutoChangeLog-pr-86594.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86594.yml diff --git a/html/changelogs/AutoChangeLog-pr-86594.yml b/html/changelogs/AutoChangeLog-pr-86594.yml new file mode 100644 index 00000000000..44df430caff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86594.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - rscadd: "You can pet fish while holding them. Be wary of petting aggressive fish." \ No newline at end of file From 06b16a0799181898153646515779a1ad0a22ec1d Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:16:36 +0200 Subject: [PATCH 130/142] Small refactor on station trait lobby buttons. (#86624) ## About The Pull Request So, I've been looking into manually loading job traits today, and it seems the buttons don't appear until you reconnect. Upon further investigations, it turns out that the code doesn't support showing lobby buttons outside of SSstation init. To add injury only up to three buttons can be displayed for some stupid reason (the lack of code for x offsets), plus the buttons aren't relocated when one is removed, thus possibly leaving behind an empty gap. This PR fixes all of that, while removing some crumbs of shitcode from new players' HUDs and making sure to remove datum traits and references are removed when the trait is deleted (usually never the case outside VV). ![immagine](https://github.com/user-attachments/assets/c7e0c481-df7c-41fc-a98c-bee15f0d9ce7) ## Why It's Good For The Game Lobby buttons should ALWAYS be shown to the player if the relative trait is loaded, the only exception being the conditions set by the trait itself (for job traits is the job age and whether the game has started or not), while the offsets of the lobby buttons should stay synced with how many are being displayed to the new player at any given time, so if a button is deleted, the others are relocated to avoid having leaving an empty gap behind. Beside, this is necessary for the lobby button for the playable pun pun to show up during Monkey Day. ## Changelog N/A, all backend. --- code/_onclick/hud/hud.dm | 5 ++ code/_onclick/hud/new_player.dm | 72 +++++++++++++------ .../subsystem/processing/station.dm | 3 +- code/datums/station_traits/_station_trait.dm | 24 ++++--- code/datums/station_traits/job_traits.dm | 13 +++- code/modules/holiday/holidays.dm | 4 -- 6 files changed, 82 insertions(+), 39 deletions(-) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index aea12726038..f6581f0379a 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -450,6 +450,11 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( return update_robot_modules_display() +/datum/hud/new_player/show_hud(version = 0, mob/viewmob) + . = ..() + if(.) + show_station_trait_buttons() + /datum/hud/proc/hidden_inventory_update() return diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm index b9448d66453..2d4b22c4c1b 100644 --- a/code/_onclick/hud/new_player.dm +++ b/code/_onclick/hud/new_player.dm @@ -6,6 +6,7 @@ /datum/hud/new_player ///Whether the menu is currently on the client's screen or not var/menu_hud_status = TRUE + var/list/shown_station_trait_buttons /datum/hud/new_player/New(mob/owner) . = ..() @@ -26,31 +27,58 @@ if (!lobbyscreen.always_shown) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_COLLAPSED, TYPE_PROC_REF(/atom/movable/screen/lobby, collapse_button)) lobbyscreen.RegisterSignal(src, COMSIG_HUD_LOBBY_EXPANDED, TYPE_PROC_REF(/atom/movable/screen/lobby, expand_button)) - if (istype(lobbyscreen, /atom/movable/screen/lobby/button)) - var/atom/movable/screen/lobby/button/lobby_button = lobbyscreen - lobby_button.owner = REF(owner) - add_station_trait_buttons() -/// Display buttons for relevant station traits -/datum/hud/new_player/proc/add_station_trait_buttons() +/// Load and then display the buttons for relevant station traits +/datum/hud/new_player/proc/show_station_trait_buttons() if (!mymob?.client || mymob.client.interviewee || !length(GLOB.lobby_station_traits)) return - var/buttons_created = 0 - var/y_offset = 397 - var/y_button_offset = 27 for (var/datum/station_trait/trait as anything in GLOB.lobby_station_traits) - if (!trait.can_display_lobby_button(mymob.client)) + if (QDELETED(trait) || !trait.can_display_lobby_button(mymob.client)) + remove_station_trait_button(trait) + continue + if(LAZYACCESS(shown_station_trait_buttons, trait)) continue var/atom/movable/screen/lobby/button/sign_up/sign_up_button = new(our_hud = src) - sign_up_button.SlowInit() - sign_up_button.owner = REF(mymob) - sign_up_button.screen_loc = offset_to_screen_loc(233, y_offset, mymob.client.view) - y_offset += y_button_offset - static_inventory += sign_up_button trait.setup_lobby_button(sign_up_button) - buttons_created++ - if (buttons_created >= MAX_STATION_TRAIT_BUTTONS_VERTICAL) - return + static_inventory |= sign_up_button + LAZYSET(shown_station_trait_buttons, trait, sign_up_button) + RegisterSignal(trait, COMSIG_QDELETING, PROC_REF(remove_station_trait_button)) + + place_station_trait_buttons() + +/// Display the buttosn for relevant station traits. +/datum/hud/new_player/proc/place_station_trait_buttons() + if(hud_version != HUD_STYLE_STANDARD || !mymob?.client) + return + + var/y_offset = 397 + var/x_offset = 233 + var/y_button_offset = 27 + var/x_button_offset = -27 + var/iteration = 0 + for(var/trait in shown_station_trait_buttons) + var/atom/movable/screen/lobby/button/sign_up/sign_up_button = shown_station_trait_buttons[trait] + iteration++ + sign_up_button.screen_loc = offset_to_screen_loc(x_offset, y_offset, mymob.client.view) + mymob.client.screen |= sign_up_button + if (iteration >= MAX_STATION_TRAIT_BUTTONS_VERTICAL) + iteration = 0 + y_offset = 397 + x_offset += x_button_offset + else + y_offset += y_button_offset + +/// Remove a station trait button, then re-order the rest. +/datum/hud/new_player/proc/remove_station_trait_button(datum/station_trait/trait) + SIGNAL_HANDLER + var/atom/movable/screen/lobby/button/sign_up/button = LAZYACCESS(shown_station_trait_buttons, trait) + if(!button) + return + LAZYREMOVE(shown_station_trait_buttons, trait) + UnregisterSignal(trait, COMSIG_QDELETING) + static_inventory -= button + qdel(button) + place_station_trait_buttons() /atom/movable/screen/lobby plane = SPLASHSCREEN_PLANE @@ -94,11 +122,9 @@ var/enabled = TRUE ///Is the button currently being hovered over with the mouse? var/highlighted = FALSE - /// The ref of the mob that owns this button. Only the owner can click on it. - var/owner /atom/movable/screen/lobby/button/Click(location, control, params) - if(owner != REF(usr)) + if(usr != get_mob()) return if(!usr.client || usr.client.interviewee) @@ -114,7 +140,7 @@ return TRUE /atom/movable/screen/lobby/button/MouseEntered(location,control,params) - if(owner != REF(usr)) + if(usr != get_mob()) return if(!usr.client || usr.client.interviewee) @@ -125,7 +151,7 @@ update_appearance(UPDATE_ICON) /atom/movable/screen/lobby/button/MouseExited() - if(owner != REF(usr)) + if(usr != get_mob()) return if(!usr.client || usr.client.interviewee) diff --git a/code/controllers/subsystem/processing/station.dm b/code/controllers/subsystem/processing/station.dm index 3cbdcbac18c..c58840cfa7a 100644 --- a/code/controllers/subsystem/processing/station.dm +++ b/code/controllers/subsystem/processing/station.dm @@ -181,5 +181,4 @@ PROCESSING_SUBSYSTEM_DEF(station) var/datum/hud/new_player/observer_hud = player.hud_used if (!istype(observer_hud)) continue - observer_hud.add_station_trait_buttons() - observer_hud.show_hud(observer_hud.hud_version) + observer_hud.show_station_trait_buttons() diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm index faced37eb3a..ddd8bc20a91 100644 --- a/code/datums/station_traits/_station_trait.dm +++ b/code/datums/station_traits/_station_trait.dm @@ -35,8 +35,8 @@ GLOBAL_LIST_EMPTY(lobby_station_traits) var/dynamic_threat_id /// If ran during dynamic, do we reduce the total threat? Will be overridden by config if set var/threat_reduction = 0 - /// Which ruleset flags to allow dynamic to use. null to disregard - var/dynamic_category = null + /// Which ruleset flags to allow dynamic to use. NONE to disregard + var/dynamic_category = NONE /// Trait should not be instantiated in a round if its type matches this type var/abstract_type = /datum/station_trait @@ -51,15 +51,19 @@ GLOBAL_LIST_EMPTY(lobby_station_traits) GLOB.dynamic_ruleset_categories = dynamic_category if(sign_up_button) GLOB.lobby_station_traits += src + if(SSstation.initialized) + SSstation.display_lobby_traits() if(trait_processes) START_PROCESSING(SSstation, src) if(trait_to_give) ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT) /datum/station_trait/Destroy() - SSstation.station_traits -= src - GLOB.dynamic_station_traits.Remove(src) destroy_lobby_buttons() + SSstation.station_traits -= src + GLOB.lobby_station_traits -= src + GLOB.dynamic_station_traits -= src + REMOVE_TRAIT(SSstation, trait_to_give, STATION_TRAIT) return ..() /// Returns the type of info the centcom report has on this trait, if any. @@ -125,13 +129,15 @@ GLOBAL_LIST_EMPTY(lobby_station_traits) /// Remove all of our active lobby buttons /datum/station_trait/proc/destroy_lobby_buttons() for (var/atom/movable/screen/button as anything in lobby_buttons) - var/mob/hud_owner = button.get_mob() - qdel(button) + var/mob/dead/new_player/hud_owner = button.get_mob() if (QDELETED(hud_owner)) + qdel(button) + continue + var/datum/hud/new_player/using_hud = hud_owner.hud_used + if(!using_hud) + qdel(button) continue - var/datum/hud/using_hud = hud_owner.hud_used - using_hud?.show_hud(using_hud?.hud_version) - lobby_buttons = list() + using_hud.remove_station_trait_button(src) /// Called when overriding a pulsar star command report message. /datum/station_trait/proc/get_pulsar_message() diff --git a/code/datums/station_traits/job_traits.dm b/code/datums/station_traits/job_traits.dm index 4d41ee37861..b23a694cfde 100644 --- a/code/datums/station_traits/job_traits.dm +++ b/code/datums/station_traits/job_traits.dm @@ -41,6 +41,10 @@ else LAZYADD(lobby_candidates, user) +/datum/station_trait/job/on_lobby_button_destroyed(atom/movable/screen/lobby/button/sign_up/lobby_button) + . = ..() + LAZYREMOVE(lobby_candidates, lobby_button.get_mob()) + /datum/station_trait/job/on_lobby_button_update_icon(atom/movable/screen/lobby/button/sign_up/lobby_button, updates) if (LAZYFIND(lobby_candidates, lobby_button.get_mob())) lobby_button.base_icon_state = "signup_on" @@ -80,7 +84,7 @@ /datum/station_trait/job/cargorilla name = "Cargo Gorilla" button_desc = "Sign up to become the Cargo Gorilla, a peaceful shepherd of boxes." - weight = 1 + weight = 0 show_in_report = FALSE // Selective attention test. Did you spot the gorilla? can_roll_antag = CAN_ROLL_NEVER job_to_add = /datum/job/cargo_gorilla @@ -252,6 +256,13 @@ can_roll_antag = CAN_ROLL_ALWAYS job_to_add = /datum/job/pun_pun +/datum/station_trait/job/pun_pun/New() + . = ..() + if(!SSticker.HasRoundStarted() || !GLOB.the_one_and_only_punpun) //Make sure we don't have two Pun Puns if loaded before the start of the round. + return + new /obj/effect/landmark/start/pun_pun(GLOB.the_one_and_only_punpun.loc) + qdel(GLOB.the_one_and_only_punpun) + /datum/station_trait/job/pun_pun/on_lobby_button_update_overlays(atom/movable/screen/lobby/button/sign_up/lobby_button, list/overlays) . = ..() overlays += LAZYFIND(lobby_candidates, lobby_button.get_mob()) ? "pun_pun_on" : "pun_pun_off" diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 1dae6ad93a4..897b5da3064 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -703,10 +703,6 @@ /datum/holiday/monkey/celebrate() . = ..() SSstation.setup_trait(/datum/station_trait/job/pun_pun) - //SSevents should initialize before SSatoms but who knows if it'll ever change. - if(GLOB.the_one_and_only_punpun) - new /obj/effect/landmark/start/pun_pun(GLOB.the_one_and_only_punpun.loc) - qdel(GLOB.the_one_and_only_punpun) /datum/holiday/doomsday name = "Mayan Doomsday Anniversary" From bce4a0c1b2c1dc3a362e1a05d30dcba86ff32acb Mon Sep 17 00:00:00 2001 From: Da Cool Boss <142358580+DaCoolBoss@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:17:56 +0100 Subject: [PATCH 131/142] Minor rewording in mouse description (#86729) ## About The Pull Request Description states they eat uninsulated cable. This has been changed to say they love eating *insulated* electrical cables. ## Why It's Good For The Game All cables in the game are insulated, so this keeps things consistant. It's also more realistic, mice don't bite into electrical cables to get at the wires inside - they do it because gnawing the soft rubber or plastic insulation sharpens and maintains their teeth. ## Changelog :cl: spellcheck: Mice now love the taste of insulated electrical cables, not uninsulated ones. /:cl: --- code/modules/mob/living/basic/vermin/mouse.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index 7361e4be7b3..5b8aad138fe 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -1,6 +1,6 @@ /mob/living/basic/mouse name = "mouse" - desc = "This cute little guy just loves the taste of uninsulated electrical cables. Isn't he adorable?" + desc = "This cute little guy just loves the taste of insulated electrical cables. Isn't he adorable?" icon_state = "mouse_gray" icon_living = "mouse_gray" icon_dead = "mouse_gray_dead" From ebf6adf61c436e942bc20ebf80f13034cd2218b7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:18:19 +0000 Subject: [PATCH 132/142] Automatic changelog for PR #86729 [ci skip] --- html/changelogs/AutoChangeLog-pr-86729.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86729.yml diff --git a/html/changelogs/AutoChangeLog-pr-86729.yml b/html/changelogs/AutoChangeLog-pr-86729.yml new file mode 100644 index 00000000000..3710ed5dba8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86729.yml @@ -0,0 +1,4 @@ +author: "DaCoolBoss" +delete-after: True +changes: + - spellcheck: "Mice now love the taste of insulated electrical cables, not uninsulated ones." \ No newline at end of file From e56eb33597d7967d46bef9945af35eda7a00d7a3 Mon Sep 17 00:00:00 2001 From: Jerry <55355646+Jewelry-x@users.noreply.github.com> Date: Thu, 19 Sep 2024 00:20:30 +0300 Subject: [PATCH 133/142] Fix typos and make blob panel easier to read and more organized. (#86724) ## About The Pull Request Fixes some typos in the blob panel and makes it more organized. ## Why It's Good For The Game Players can more easily read and understand what the blob can do through the antag panel. ## Changelog :cl: qol: made blob antag panel easier to read and more organized spellcheck: fixed a few typos in the blob panel /:cl: --- .../tgui/interfaces/AntagInfoBlob.tsx | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx b/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx index 61fffb3766e..518fc4721d9 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBlob.tsx @@ -51,7 +51,7 @@ const Overview = (props) => { You haven't revealed your true form yet! - You must be succumb to the infection. Find somewhere safe and pop! + You must succumb to the infection. Find somewhere safe and pop! ); @@ -111,15 +111,22 @@ const Basics = (props) => { You will be able to manually place your blob core by pressing the - Place Blob Core button in the bottom right corner of the screen. + Place Blob Core button in the bottom right corner of the screen.{' '} +
+
+ If you are the blob infection, you can place the core where you are + standing by pressing the pop button on the top left corner of the + screen.
In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense. - Click = Expand Blob | Middle Mouse Click = Rally Spores | Ctrl Click = - Create Shield Blob | Alt Click = Remove Blob + Click = Expand Blob
+ Middle Mouse Click = Rally Spores
+ Ctrl Click = Create Shield Blob
+ Alt Click = Remove Blob
Attempting to talk will send a message to all other overminds, @@ -135,9 +142,9 @@ const Minions = (props) => { - Defenders that can be produced from factories for a cost, and are hard - to kill, powerful, and moderately smart. The factory used to create - one will become fragile and briefly unable to produce spores. + This unit can be produced from factories for a cost. They are hard to + kill, powerful, and moderately smart. The factory used to create one + will become fragile and briefly unable to produce spores. Produced automatically from factories, these are weak, but can be @@ -154,18 +161,21 @@ const Structures = (props) => { Normal Blobs will expand your reach and can be upgraded into special - blobs that perform certain functions. + blobs that perform certain functions. Bear in mind that expanding into + space has an 80% chance of failing!
You can upgrade normal blobs into the following types of blob: - - Strong and expensive blobs which take more damage. In additon, they - are fireproof and can block air, use these to protect yourself from - station fires. Upgrading them again will result in a reflective blob, - capable of reflecting most projectiles at the cost of the strong - blob's extra health. + + Strong blobs are expensive but take more damage. In additon, they are + fireproof and can block air, use these to protect yourself from + station fires. + + + Upgrading strong blobs creates reflective blobs, capable of reflecting + most projectiles at the cost of the strong blob's extra health. Blobs which produce more resources for you, build as many of these as From 7e3498a2119ed1ddeb5edff58318d1dc477b5251 Mon Sep 17 00:00:00 2001 From: Jerry <55355646+Jewelry-x@users.noreply.github.com> Date: Thu, 19 Sep 2024 00:20:44 +0300 Subject: [PATCH 134/142] Implement fix for hydroponics tray allowing autogrow while no power (#86723) ## About The Pull Request Fixes #83539. The code was structured in such a way that the check for power usage did not work correctly, and this allowed for someone to double press ctrl click on the hydroponics tray while there is no power, turning it on forever regardless. ## Why It's Good For The Game Fixes a bug that allows autogrow to be turned on with no power. ## Changelog :cl: fix: fixed a bug that allows autogrow to be turned on with no power. /:cl: --- code/modules/hydroponics/hydroponics.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index e23b1cac5de..eb08717a061 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -1090,10 +1090,14 @@ /obj/machinery/hydroponics/click_ctrl(mob/user) if(!anchored) return NONE + + update_use_power(ACTIVE_POWER_USE) + if(!powered()) to_chat(user, span_warning("[name] has no power.")) update_use_power(NO_POWER_USE) return CLICK_ACTION_BLOCKING + set_self_sustaining(!self_sustaining) to_chat(user, span_notice("You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].")) return CLICK_ACTION_SUCCESS From 5e0ac9eaadccb4eff1aef55f24362cedb0fdcb9e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:21:06 +0000 Subject: [PATCH 135/142] Automatic changelog for PR #86724 [ci skip] --- html/changelogs/AutoChangeLog-pr-86724.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86724.yml diff --git a/html/changelogs/AutoChangeLog-pr-86724.yml b/html/changelogs/AutoChangeLog-pr-86724.yml new file mode 100644 index 00000000000..34feba1ac75 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86724.yml @@ -0,0 +1,5 @@ +author: "Jewelry-x" +delete-after: True +changes: + - qol: "made blob antag panel easier to read and more organized" + - spellcheck: "fixed a few typos in the blob panel" \ No newline at end of file From 278ba9be5d641f04ac2acc5a1ba220d1fb5f9bf7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:21:10 +0000 Subject: [PATCH 136/142] Automatic changelog for PR #86723 [ci skip] --- html/changelogs/AutoChangeLog-pr-86723.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86723.yml diff --git a/html/changelogs/AutoChangeLog-pr-86723.yml b/html/changelogs/AutoChangeLog-pr-86723.yml new file mode 100644 index 00000000000..4adb877f2af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86723.yml @@ -0,0 +1,4 @@ +author: "Jewelry-x" +delete-after: True +changes: + - bugfix: "fixed a bug that allows autogrow to be turned on with no power." \ No newline at end of file From 42f651350f5be7546da9a915da064abca63c041b Mon Sep 17 00:00:00 2001 From: Da Cool Boss <142358580+DaCoolBoss@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:21:18 +0100 Subject: [PATCH 137/142] Typo fix in lead (reagent) description. (#86730) ## About The Pull Request "metalltic" is now "metallic" ## Why It's Good For The Game This description is visible in game so it shouldn't have typos. ## Changelog :cl: spellcheck: Fixed typos in lead's description. /:cl: --- code/modules/reagents/chemistry/reagents/other_reagents.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 79f43da2807..dd395787c95 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2971,7 +2971,7 @@ //This is intended to a be a scarce reagent to gate certain drugs and toxins with. Do not put in a synthesizer. Renewable sources of this reagent should be inefficient. /datum/reagent/lead name = "Lead" - description = "A dull metalltic element with a low melting point." + description = "A dull metallic element with a low melting point." taste_description = "metal" reagent_state = SOLID color = "#80919d" From 76666284cd9ee298e3b9ffab169256ddba7b8fc1 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:21:38 +0000 Subject: [PATCH 138/142] Automatic changelog for PR #86730 [ci skip] --- html/changelogs/AutoChangeLog-pr-86730.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86730.yml diff --git a/html/changelogs/AutoChangeLog-pr-86730.yml b/html/changelogs/AutoChangeLog-pr-86730.yml new file mode 100644 index 00000000000..000944ae44c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86730.yml @@ -0,0 +1,4 @@ +author: "DaCoolBoss" +delete-after: True +changes: + - spellcheck: "Fixed typos in lead's description." \ No newline at end of file From 257e4223f3949d7630e55e5a2fdfec949773b20e Mon Sep 17 00:00:00 2001 From: Joshua Kidder <49173900+Metekillot@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:38:07 -0400 Subject: [PATCH 139/142] Fixes xenos being able to pick up items that they shouldn't by most means, expands itempicky component functionality (#86714) ## About The Pull Request Xenos can apparently use shenanigans such as https://github.com/tgstation/tgstation/issues/86703 to put some items in their hand, and there are likely methods like this dotted around the codebase. However, the signal to put something in their hand is called consistently across any process that would cause them to pick up or otherwise have something to put in their hand, so instead I added /datum/component/itempicky to xenos. While I was in there, I expanded the functionality of itempicky; it can run a callback to determine a condition that needs to be met now. ## Why It's Good For The Game Fixes https://github.com/tgstation/tgstation/issues/86703 Expands a component's usefulness ## Changelog :cl: Bisar fix: Xenomorph restrictions on items they can pick up have had their determining logic made more _robust_. code: The itempicky component (restricts what can be picked up via a whitelist) can now, optionally, have a callback fed to it to determine cases of bypassing that whitelist. /:cl: --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> # Conflicts: # code/modules/mob/living/carbon/alien/special/facehugger.dm --- code/datums/components/itempicky.dm | 13 +++++++++++-- code/game/objects/items.dm | 2 +- code/game/objects/items/stickers.dm | 2 +- code/game/objects/items/toys.dm | 1 - code/modules/basketball/basketball.dm | 1 - code/modules/mob/living/carbon/alien/alien.dm | 15 ++++++++++++--- .../mob/living/carbon/alien/special/facehugger.dm | 6 ------ .../modular_computers/computers/item/pda.dm | 2 +- .../mob/living/carbon/special/facehugger.dm | 5 +++++ tgstation.dme | 1 + 10 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 modular_nova/master_files/code/modules/mob/living/carbon/special/facehugger.dm diff --git a/code/datums/components/itempicky.dm b/code/datums/components/itempicky.dm index 74fbdff1caa..bda8b1ae138 100644 --- a/code/datums/components/itempicky.dm +++ b/code/datums/components/itempicky.dm @@ -5,13 +5,21 @@ var/whitelist /// Message shown if you try to pick up an item not in the whitelist var/message = "You don't like %TARGET, why would you hold it?" + /// An optional callback we check for overriding our whitelist + var/datum/callback/tertiary_condition = null -/datum/component/itempicky/Initialize(whitelist, message) +/datum/component/itempicky/Initialize(whitelist, message, tertiary_condition) if(!ismob(parent)) return COMPONENT_INCOMPATIBLE src.whitelist = whitelist if(message) src.message = message + if(tertiary_condition) + src.tertiary_condition = tertiary_condition + +/datum/component/itempicky/Destroy(force) + tertiary_condition = null + return ..() /datum/component/itempicky/RegisterWithParent() RegisterSignal(parent, COMSIG_LIVING_TRY_PUT_IN_HAND, PROC_REF(particularly)) @@ -30,6 +38,7 @@ /datum/component/itempicky/proc/particularly(datum/source, obj/item/pickingup) SIGNAL_HANDLER - if(!is_type_in_typecache(pickingup, whitelist)) + // if we were passed the output of a callback, check against that + if(!tertiary_condition?.Invoke() && !is_type_in_typecache(pickingup, whitelist)) to_chat(source, span_warning("[replacetext(message, "%TARGET", pickingup)]")) return COMPONENT_LIVING_CANT_PUT_IN_HAND diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index fed40fdde62..9c5a9a2c9f7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -657,7 +657,7 @@ /obj/item/attack_alien(mob/user, list/modifiers) var/mob/living/carbon/alien/ayy = user - if(!user.can_hold_items(src)) + if(!ayy.can_hold_items(src)) if(src in ayy.contents) // To stop Aliens having items stuck in their pockets ayy.dropItemToGround(src) to_chat(user, span_warning("Your claws aren't capable of such fine manipulation!")) diff --git a/code/game/objects/items/stickers.dm b/code/game/objects/items/stickers.dm index 447e2022473..99247493795 100644 --- a/code/game/objects/items/stickers.dm +++ b/code/game/objects/items/stickers.dm @@ -25,7 +25,7 @@ throw_range = 3 pressure_resistance = 0 - item_flags = NOBLUDGEON | XENOMORPH_HOLDABLE //funny ~Jimmyl + item_flags = NOBLUDGEON w_class = WEIGHT_CLASS_TINY /// `list` or `null`, contains possible alternate `icon_states`. diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 1c82bffbf7c..097fa6d0c3e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1134,7 +1134,6 @@ name = "xenomorph action figure" desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use." w_class = WEIGHT_CLASS_SMALL - item_flags = XENOMORPH_HOLDABLE var/cooldown = 0 /obj/item/toy/toy_xeno/attack_self(mob/user) diff --git a/code/modules/basketball/basketball.dm b/code/modules/basketball/basketball.dm index 35579dc4482..c69c2fd1f78 100644 --- a/code/modules/basketball/basketball.dm +++ b/code/modules/basketball/basketball.dm @@ -8,7 +8,6 @@ inhand_icon_state = "basketball" desc = "Here's your chance, do your dance at the Space Jam." w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets - item_flags = XENOMORPH_HOLDABLE // playing ball against a xeno is rigged since they cannot be disarmed /// The person dribbling the basketball var/mob/living/wielder /// So the basketball doesn't make sound every step diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 3c738b2fd77..19238da4ebe 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -23,6 +23,13 @@ unique_name = TRUE var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?") + var/static/list/xeno_allowed_items = typecacheof(list( + /obj/item/clothing/mask/facehugger, + /obj/item/toy/basketball, // playing ball against a xeno is rigged since they cannot be disarmed, their game is out of this world + /obj/item/toy/toy_xeno, + /obj/item/sticker, //funny ~Jimmyl + /obj/item/toy/plush/rouny, + )) /mob/living/carbon/alien/Initialize(mapload) add_verb(src, /mob/living/proc/mob_sleep) @@ -37,6 +44,11 @@ . = ..() if(alien_speed) update_alien_speed() + LoadComponent( \ + /datum/component/itempicky, \ + xeno_allowed_items, \ + span_alien("Your claws lack the dexterity to hold %TARGET."), \ + CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_has_trait), src, TRAIT_ADVANCEDTOOLUSER)) /mob/living/carbon/alien/create_internal_organs() organs += new /obj/item/organ/internal/brain/alien @@ -148,9 +160,6 @@ Des: Removes all infected images from the alien. set_name() -/mob/living/carbon/alien/can_hold_items(obj/item/I) - return (I && (I.item_flags & XENOMORPH_HOLDABLE || ISADVANCEDTOOLUSER(src)) && ..()) - /mob/living/carbon/alien/on_lying_down(new_lying_angle) . = ..() update_icons() diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 90f3aea930f..6cab997ec5d 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -23,12 +23,6 @@ flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH layer = MOB_LAYER max_integrity = 100 - item_flags = XENOMORPH_HOLDABLE - // NOVA EDIT ADDITION START: job-restricted examine text - special_desc_requirement = EXAMINE_CHECK_JOB - special_desc_jobs = list("Scientist, Research Director") - special_desc = "This alien is an extremely dangerous life form capable of creating a xenomorph. You would know well not to approach without full body biological protection." - // NOVA EDIT ADDITION END slowdown = 2 var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index 172b4d1ad2b..172b786aaea 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -182,7 +182,7 @@ /obj/item/modular_computer/pda/proc/remove_pen(mob/user) - if(issilicon(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) //TK doesn't work even with this removed but here for readability + if(issilicon(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH | NEED_DEXTERITY)) //TK doesn't work even with this removed but here for readability return if(inserted_item) diff --git a/modular_nova/master_files/code/modules/mob/living/carbon/special/facehugger.dm b/modular_nova/master_files/code/modules/mob/living/carbon/special/facehugger.dm new file mode 100644 index 00000000000..ba88456973f --- /dev/null +++ b/modular_nova/master_files/code/modules/mob/living/carbon/special/facehugger.dm @@ -0,0 +1,5 @@ +// job-restricted examine text +/obj/item/clothing/mask/facehugger + special_desc_requirement = EXAMINE_CHECK_JOB + special_desc_jobs = list("Scientist, Research Director") + special_desc = "This alien is an extremely dangerous life form capable of creating a xenomorph. You would know well not to approach without full body biological protection." diff --git a/tgstation.dme b/tgstation.dme index 39d8edca26e..a9bc8454c0b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6856,6 +6856,7 @@ #include "modular_nova\master_files\code\modules\mob\living\carbon\human\species_type\podpeople.dm" #include "modular_nova\master_files\code\modules\mob\living\carbon\human\species_type\skeletons.dm" #include "modular_nova\master_files\code\modules\mob\living\carbon\human\species_type\snail.dm" +#include "modular_nova\master_files\code\modules\mob\living\carbon\special\facehugger.dm" #include "modular_nova\master_files\code\modules\mob\living\human\species.dm" #include "modular_nova\master_files\code\modules\mob\living\human\species_types\ethereal.dm" #include "modular_nova\master_files\code\modules\mob\living\human\species_types\flypeople.dm" From 399493e8d1e432ad94bd0cc5685690105b333b65 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:40:47 +0000 Subject: [PATCH 140/142] Automatic changelog for PR #86714 [ci skip] --- html/changelogs/AutoChangeLog-pr-86714.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-86714.yml diff --git a/html/changelogs/AutoChangeLog-pr-86714.yml b/html/changelogs/AutoChangeLog-pr-86714.yml new file mode 100644 index 00000000000..9d6f0a31877 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-86714.yml @@ -0,0 +1,5 @@ +author: "Bisar" +delete-after: True +changes: + - bugfix: "Xenomorph restrictions on items they can pick up have had their determining logic made more _robust_." + - code_imp: "The itempicky component (restricts what can be picked up via a whitelist) can now, optionally, have a callback fed to it to determine cases of bypassing that whitelist." \ No newline at end of file From 8819875cd6fb91cbd501f53d2e84de36c250d654 Mon Sep 17 00:00:00 2001 From: Iajret Date: Sat, 21 Sep 2024 12:31:13 +0300 Subject: [PATCH 141/142] checks From 77811200c2fddeb69069087934f29b7e5217b177 Mon Sep 17 00:00:00 2001 From: Iajret Date: Sat, 21 Sep 2024 12:45:42 +0300 Subject: [PATCH 142/142] gay vulpes fix --- tff_modular/modules/custom_smites/floor_clown.dm | 3 +-- tff_modular/modules/custom_smites/floor_gay_vulpes.dm | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tff_modular/modules/custom_smites/floor_clown.dm b/tff_modular/modules/custom_smites/floor_clown.dm index 32a93cba028..585040fb0da 100644 --- a/tff_modular/modules/custom_smites/floor_clown.dm +++ b/tff_modular/modules/custom_smites/floor_clown.dm @@ -91,11 +91,10 @@ /mob/living/carbon/human/floor_clown/Initialize() . = ..() - status_flags = GODMODE mobility_flags = NONE GLOB.move_manager.stop_looping(src) density = 0 - ADD_TRAIT(src, TRAIT_NO_TELEPORT, SMITE_TRAIT) + src.add_traits(list(TRAIT_GODMODE, TRAIT_NO_TELEPORT), SMITE_TRAIT) equipOutfit(/datum/outfit/consumed_clown) set_jitter(60 SECONDS) diff --git a/tff_modular/modules/custom_smites/floor_gay_vulpes.dm b/tff_modular/modules/custom_smites/floor_gay_vulpes.dm index 8101e439642..6452c691534 100644 --- a/tff_modular/modules/custom_smites/floor_gay_vulpes.dm +++ b/tff_modular/modules/custom_smites/floor_gay_vulpes.dm @@ -122,11 +122,10 @@ /mob/living/carbon/human/species/vulpkanin/gib_vulp/Initialize() . = ..() - status_flags = GODMODE mobility_flags = NONE GLOB.move_manager.stop_looping(src) density = 0 - ADD_TRAIT(src, TRAIT_NO_TELEPORT, SMITE_TRAIT) + src.add_traits(list(TRAIT_GODMODE, TRAIT_NO_TELEPORT), SMITE_TRAIT) set_active_language(/datum/language/common) equipOutfit(/datum/outfit/job/assistant)