From 04a67230b4c551f02dcb622290ff25d7101eba33 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Sat, 18 Jan 2025 13:25:39 +0000 Subject: [PATCH 01/23] Grillable foods grill in hot air (#88914) ## About The Pull Request This PR makes is so that if the air is hot enough to trigger a fire door to close, grillable foods left out in the open will grill themselves. I picked the minimum grilling temperature essentially at random because I don't know what heat units are or should be, but the define `FIRE_MINIMUM_TEMPERATURE_TO_EXIST` sounded about right. IMPORTANT NOTE: **All foods are grillable by default** and become "burned mess" after about 30 seconds. If this seems like too much of a grief vector (a significant fire in the kitchen may cause all food to grill itself into oblivion) I can make this optional rather than a default-enabled thing on all food. IDK whether or not this matters, because all food is also flammable. Food will only grill based on air temperature if it is set out on an open tile (including while on a table), not while in your hands or backpack or pockets or a closet or inside an oven or (oddly enough) while on a grill. ## Why It's Good For The Game it increases my emulsion if eggs can fry on a hot sidewalk ## Changelog :cl: add: Eggs (and all other edible food) left in a hot place will fry. /:cl: --- code/datums/components/grillable.dm | 80 +++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/code/datums/components/grillable.dm b/code/datums/components/grillable.dm index f584808a1f3bd..3b3ef047c833f 100644 --- a/code/datums/components/grillable.dm +++ b/code/datums/components/grillable.dm @@ -1,3 +1,5 @@ +#define IDEAL_GRILLING_TEMPERATURE 200 + T0C + /datum/component/grillable dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS // So you can change grill results with various cookstuffs ///Result atom type of grilling this object @@ -14,6 +16,12 @@ var/who_placed_us /// Reagents that should be added to the result var/list/added_reagents + /// Open turf we were last placed on, to check temperature + var/turf/open/listening_turf + /// Are we grilling right now? + var/is_grilling = FALSE + /// What's our current air temperature? + var/current_temperature = 0 /datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite, list/added_reagents) . = ..() @@ -32,14 +40,20 @@ RegisterSignal(parent, COMSIG_ITEM_GRILL_TURNED_OFF, PROC_REF(on_grill_turned_off)) RegisterSignal(parent, COMSIG_ITEM_GRILL_PROCESS, PROC_REF(on_grill)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_location_changed)) + on_location_changed(parent) /datum/component/grillable/UnregisterFromParent() + if (listening_turf) + UnregisterSignal(listening_turf, COMSIG_TURF_EXPOSE) + UnregisterSignal(parent, list( COMSIG_ATOM_EXAMINE, COMSIG_ITEM_GRILL_TURNED_ON, COMSIG_ITEM_GRILL_TURNED_OFF, COMSIG_ITEM_GRILL_PROCESS, COMSIG_ITEM_GRILL_PLACED, + COMSIG_MOVABLE_MOVED )) // Inherit the new values passed to the component @@ -55,6 +69,32 @@ if(use_large_steam_sprite) src.use_large_steam_sprite = use_large_steam_sprite +/datum/component/grillable/Destroy(force) + . = ..() + STOP_PROCESSING(SSmachines, src) + listening_turf = null + +/// Signal proc for [COMSIG_MOVABLE_MOVED], our location has changed and we should register for temperature information +/datum/component/grillable/proc/on_location_changed(atom/source) + SIGNAL_HANDLER + + if (is_grilling) + on_grill_turned_off(source) + STOP_PROCESSING(SSmachines, src) + + if (listening_turf) + UnregisterSignal(listening_turf, COMSIG_TURF_EXPOSE) + + if (isnull(source)) + return + + var/turf/open/current_turf = source.loc + if (!isopenturf(current_turf)) + return + listening_turf = current_turf + RegisterSignal(current_turf, COMSIG_TURF_EXPOSE, PROC_REF(on_turf_atmos_changed)) + on_turf_atmos_changed(current_turf, current_turf.air, current_turf.air?.temperature || 0) + /// Signal proc for [COMSIG_ITEM_GRILL_PLACED], item is placed on the grill. /datum/component/grillable/proc/on_grill_placed(datum/source, mob/griller) SIGNAL_HANDLER @@ -62,12 +102,11 @@ if(griller && griller.mind) who_placed_us = REF(griller.mind) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - /// Signal proc for [COMSIG_ITEM_GRILL_TURNED_ON], starts the grilling process. /datum/component/grillable/proc/on_grill_turned_on(datum/source) RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(add_grilled_item_overlay)) + is_grilling = TRUE var/atom/atom_parent = parent atom_parent.update_appearance() @@ -75,6 +114,7 @@ /datum/component/grillable/proc/on_grill_turned_off(datum/source) UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS) + is_grilling = FALSE var/atom/atom_parent = parent atom_parent.update_appearance() @@ -138,15 +178,37 @@ else examine_list += span_danger("[parent] should probably not be put on the grill.") -///Ran when an object moves from the grill -/datum/component/grillable/proc/on_moved(atom/source, atom/OldLoc, Dir, Forced) +/datum/component/grillable/proc/add_grilled_item_overlay(datum/source, list/overlays) SIGNAL_HANDLER - UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS) - UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) - source.update_appearance() + overlays += mutable_appearance('icons/effects/steam.dmi', "[use_large_steam_sprite ? "steam_triple" : "steam_single"]", ABOVE_OBJ_LAYER) -/datum/component/grillable/proc/add_grilled_item_overlay(datum/source, list/overlays) +/// Signal proc for [COMSIG_TURF_EXPOSE], atmosphere might be hot enough for grilling. +/datum/component/grillable/proc/on_turf_atmos_changed(turf/open/source, datum/gas_mixture/air, exposed_temperature) SIGNAL_HANDLER - overlays += mutable_appearance('icons/effects/steam.dmi', "[use_large_steam_sprite ? "steam_triple" : "steam_single"]", ABOVE_OBJ_LAYER) + if (!is_grilling) + if (exposed_temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + return + on_grill_turned_on(source) + START_PROCESSING(SSmachines, src) + current_temperature = exposed_temperature + else + if (exposed_temperature >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + current_temperature = exposed_temperature + return + on_grill_turned_off(source) + STOP_PROCESSING(SSmachines, src) + +// Grill while exposed to hot air +/datum/component/grillable/process(seconds_per_tick) + var/atom/atom_parent = parent + + // Grill faster as we approach 200 degrees celsius + var/check_temperature = clamp(current_temperature, FIRE_MINIMUM_TEMPERATURE_TO_EXIST, IDEAL_GRILLING_TEMPERATURE) + var/temp_scale = (check_temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST) / (IDEAL_GRILLING_TEMPERATURE - FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + var/speed_modifier = LERP(0.5, 1, temp_scale) + + on_grill(parent, atom_parent.loc, seconds_per_tick * speed_modifier) + +#undef IDEAL_GRILLING_TEMPERATURE From 63f42818b8e0321674d389ebd844a0b57abcffa7 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 13:25:59 +0000 Subject: [PATCH 02/23] Automatic changelog for PR #88914 [ci skip] --- html/changelogs/AutoChangeLog-pr-88914.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88914.yml diff --git a/html/changelogs/AutoChangeLog-pr-88914.yml b/html/changelogs/AutoChangeLog-pr-88914.yml new file mode 100644 index 0000000000000..8bea08ce11599 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88914.yml @@ -0,0 +1,4 @@ +author: "Jacquerel" +delete-after: True +changes: + - rscadd: "Eggs (and all other edible food) left in a hot place will fry." \ No newline at end of file From 4f14df11b624f673470a3398a0c6781df2e40071 Mon Sep 17 00:00:00 2001 From: Chowder-McArthor <166885501+Chowder-McArthor@users.noreply.github.com> Date: Sat, 18 Jan 2025 13:22:07 -0800 Subject: [PATCH 03/23] Redo of the Geyser Code: Second Attempt (#89111) ## About The Pull Request Makes it so strange geysers now say their name when scanned. ## Why It's Good For The Game Should help make geysers actually worthwhile now that it's easier to tell what they produce. ## Changelog :cl: qol: Strange geysers now say in their name what they produce. /:cl: --- code/game/objects/structures/lavaland/geyser.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm index 9a546e8154d9f..fa0fd02e21cec 100644 --- a/code/game/objects/structures/lavaland/geyser.dm +++ b/code/game/objects/structures/lavaland/geyser.dm @@ -106,11 +106,12 @@ /obj/structure/geyser/random point_value = 500 - true_name = "strange geyser" - discovery_message = "It's a strange geyser! How does any of this even work?" //it doesnt /obj/structure/geyser/random/Initialize(mapload) reagent_id = get_random_reagent_id() + var/datum/reagent/Random_Reagent = reagent_id + true_name = "[initial(Random_Reagent.name)] geyser" + discovery_message = "It's a [initial(Random_Reagent.name)] geyser! How does any of this even work?" //it doesnt return ..() From d1e3444dd7e947b692e6b94bd954bf37ad020451 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 21:22:46 +0000 Subject: [PATCH 04/23] Automatic changelog for PR #89111 [ci skip] --- html/changelogs/AutoChangeLog-pr-89111.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89111.yml diff --git a/html/changelogs/AutoChangeLog-pr-89111.yml b/html/changelogs/AutoChangeLog-pr-89111.yml new file mode 100644 index 0000000000000..d44499f99f2fa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89111.yml @@ -0,0 +1,4 @@ +author: "Chowder-McArthor" +delete-after: True +changes: + - qol: "Strange geysers now say in their name what they produce." \ No newline at end of file From 8c721d11f9abb79503d22cdb3ce4efc1c451ea5c Mon Sep 17 00:00:00 2001 From: Lucy Date: Sat, 18 Jan 2025 16:58:23 -0500 Subject: [PATCH 05/23] Small and tiny mobs no longer trigger the squeak component (#89100) ## About The Pull Request This prevents mobs with `MOB_SIZE_SMALL` or `MOB_SIZE_TINY` from triggering squeak sounds on crossed. Simple enough. Also made the cooldown use the cooldown macros. ## Why It's Good For The Game Small or tiny mobs are, well, tiny, and wouldn't really be able to trigger the same kinda reaction. Also sound spam is universally bad, and this gets rid of another method of sound spam. ## Changelog :cl: qol: Small and tiny mobs no longer trigger squeaking objects when walking over them. /:cl: --- code/datums/components/squeak.dm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm index ca1bb82ace785..ec900943997f1 100644 --- a/code/datums/components/squeak.dm +++ b/code/datums/components/squeak.dm @@ -11,8 +11,8 @@ var/step_delay = 1 // This is to stop squeak spam from inhand usage - var/last_use = 0 - var/use_delay = 20 + COOLDOWN_DECLARE(spam_cooldown) + var/use_delay = 2 SECONDS ///extra-range for this component's sound var/sound_extra_range = -1 @@ -102,6 +102,10 @@ return if(ismob(arrived) && !arrived.density) // Prevents 10 overlapping mice from making an unholy sound while moving return + if(isliving(arrived)) + var/mob/living/living_arrived = arrived + if(living_arrived.mob_size < MOB_SIZE_HUMAN) + return var/atom/current_parent = parent if(isturf(current_parent?.loc)) play_squeak() @@ -109,8 +113,8 @@ /datum/component/squeak/proc/use_squeak() SIGNAL_HANDLER - if(last_use + use_delay < world.time) - last_use = world.time + if(COOLDOWN_FINISHED(src, spam_cooldown)) + COOLDOWN_START(src, spam_cooldown, use_delay) play_squeak() /datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot) From 1f270eec8d853ee4919b388b86f64f7143b06de4 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 21:58:45 +0000 Subject: [PATCH 06/23] Automatic changelog for PR #89100 [ci skip] --- html/changelogs/AutoChangeLog-pr-89100.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89100.yml diff --git a/html/changelogs/AutoChangeLog-pr-89100.yml b/html/changelogs/AutoChangeLog-pr-89100.yml new file mode 100644 index 0000000000000..a9ccbbf619da8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89100.yml @@ -0,0 +1,4 @@ +author: "Absolucy" +delete-after: True +changes: + - qol: "Small and tiny mobs no longer trigger squeaking objects when walking over them." \ No newline at end of file From ed54b220443ea7f89c00182bba5a3334a91ba2da Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:35:08 +0000 Subject: [PATCH 07/23] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-88914.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89013.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89085.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89089.yml | 5 ----- html/changelogs/AutoChangeLog-pr-89100.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89111.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89112.yml | 4 ---- html/changelogs/archive/2025-01.yml | 19 +++++++++++++++++++ 8 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-88914.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89013.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89085.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89089.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89100.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89111.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89112.yml diff --git a/html/changelogs/AutoChangeLog-pr-88914.yml b/html/changelogs/AutoChangeLog-pr-88914.yml deleted file mode 100644 index 8bea08ce11599..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88914.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jacquerel" -delete-after: True -changes: - - rscadd: "Eggs (and all other edible food) left in a hot place will fry." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89013.yml b/html/changelogs/AutoChangeLog-pr-89013.yml deleted file mode 100644 index ad7c6be528824..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89013.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AyIong" -delete-after: True -changes: - - qol: "SmartFridge got another redesign, and you can dispense all amount of product in one click (RMB on product)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89085.yml b/html/changelogs/AutoChangeLog-pr-89085.yml deleted file mode 100644 index a4df0c607ead2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89085.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - image: "yet another medkit resprite" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89089.yml b/html/changelogs/AutoChangeLog-pr-89089.yml deleted file mode 100644 index c6e81b3c33688..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89089.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "MTandi" -delete-after: True -changes: - - bugfix: "Fixed plant analyzer UI crashing on plants that have a reagent gene on their graft" - - bugfix: "Plants with reagent traits in the graft now properly say the name of the grafted reagent" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89100.yml b/html/changelogs/AutoChangeLog-pr-89100.yml deleted file mode 100644 index a9ccbbf619da8..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89100.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Absolucy" -delete-after: True -changes: - - qol: "Small and tiny mobs no longer trigger squeaking objects when walking over them." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89111.yml b/html/changelogs/AutoChangeLog-pr-89111.yml deleted file mode 100644 index d44499f99f2fa..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89111.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Chowder-McArthor" -delete-after: True -changes: - - qol: "Strange geysers now say in their name what they produce." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89112.yml b/html/changelogs/AutoChangeLog-pr-89112.yml deleted file mode 100644 index b4369a59d8308..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89112.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Fixed active turfs on the new Turreted Outpost ruin." \ No newline at end of file diff --git a/html/changelogs/archive/2025-01.yml b/html/changelogs/archive/2025-01.yml index cddfcce1af8e8..72a590d411f3c 100644 --- a/html/changelogs/archive/2025-01.yml +++ b/html/changelogs/archive/2025-01.yml @@ -507,3 +507,22 @@ 2025-01-18: EnterTheJake: - image: Codex Cicatrix has received a new sprite +2025-01-19: + Absolucy: + - qol: Small and tiny mobs no longer trigger squeaking objects when walking over + them. + AyIong: + - qol: SmartFridge got another redesign, and you can dispense all amount of product + in one click (RMB on product) + Chowder-McArthor: + - qol: Strange geysers now say in their name what they produce. + Jacquerel: + - rscadd: Eggs (and all other edible food) left in a hot place will fry. + MTandi: + - bugfix: Fixed plant analyzer UI crashing on plants that have a reagent gene on + their graft + - bugfix: Plants with reagent traits in the graft now properly say the name of the + grafted reagent + - image: yet another medkit resprite + SmArtKar: + - bugfix: Fixed active turfs on the new Turreted Outpost ruin. From 85f11990ae2230d3075d3cc65c868ca3bb7fe5fc Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sun, 19 Jan 2025 10:02:15 +0300 Subject: [PATCH 08/23] Resprites default and mirage grenades (#89118) --- icons/obj/weapons/grenade.dmi | Bin 37622 -> 37930 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/weapons/grenade.dmi b/icons/obj/weapons/grenade.dmi index 628b271d423e571c3dcfb94bd39712dd3a48eb03..c2eba7adcc1d65abd5eb417cf8ea82f0b0e5bee0 100644 GIT binary patch delta 36295 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

y;0lp&0 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 From e1c87793d8f41a9e2c5928830fa3c8084a61247a Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sun, 19 Jan 2025 10:04:19 +0300 Subject: [PATCH 09/23] Touches up the unholy water flask (#89117) --- icons/obj/drinks/bottles.dmi | Bin 27819 -> 26535 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/drinks/bottles.dmi b/icons/obj/drinks/bottles.dmi index 2bdacf04265065785d7672311d94f2c2a09caeb1..3dece4b41c6c9c88498c3f87e74564b159b503d3 100644 GIT binary patch literal 26535 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 literal 27819 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 Y@^&CsNRSWs5;BmIoa)OG*>{2e2M^=>00000 From d28db3124896b566ed0bee1256d9f8998a566b5e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:55:28 +0000 Subject: [PATCH 10/23] Automatic changelog for PR #89118 [ci skip] --- html/changelogs/AutoChangeLog-pr-89118.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89118.yml diff --git a/html/changelogs/AutoChangeLog-pr-89118.yml b/html/changelogs/AutoChangeLog-pr-89118.yml new file mode 100644 index 0000000000000..c49bafe2a57aa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89118.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Resprited default and mirage grenades" \ No newline at end of file From 622f8de0fbc7e75ba4d5b5d40f996f9e17b0a7e0 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:55:34 +0000 Subject: [PATCH 11/23] Automatic changelog for PR #89117 [ci skip] --- html/changelogs/AutoChangeLog-pr-89117.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89117.yml diff --git a/html/changelogs/AutoChangeLog-pr-89117.yml b/html/changelogs/AutoChangeLog-pr-89117.yml new file mode 100644 index 0000000000000..0695ea964d4f0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89117.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - image: "Made the unholy water flask darker" \ No newline at end of file From 90b67b0541413ba47603947ccabf974ee3544d88 Mon Sep 17 00:00:00 2001 From: Y0SH1M4S73R Date: Sun, 19 Jan 2025 13:40:23 -0500 Subject: [PATCH 12/23] A Small Circuit Expansion: Wallmounts, Undertiles, and Wire Bundles (#89122) ## About The Pull Request This PR adds several circuit features, and changes several assembly-related features to make them a bit more logical in how they work. Included are the following changes/additions: - Assemblies and wires have been refactored with vars that describe their behavior: - Assemblies have an `assembly_behavior` bitflag instead of a `attachable` var. This var has 3 flags: - `ASSEMBLY_INPUT`: The assembly is able to pulse the wire it is attached to. - `ASSEMBLY_TOGGLE_ARMED`: On activation, the assembly toggles whether it can pulse the wire it is attached to. - `ASSEMBLY_FUNCTIONAL_OUTPUT`: On activation, the assembly does something other than just toggling whether it's armed. - Wires have a `wires_behavior` bitflag with 3 flags: - `WIRES_INPUT`: The object the wires are attached to does something when the wires are pulsed. - `WIRES_TOGGLE_ARMED`: The object the wires are attached to can activate assemblies attached to those wires, and is fine if all that activating that assembly does is toggle whether it's armed. - `WIRES_FUNCTIONAL_OUTPUT`: The object the wires are attached to expects that assemblies attached to its wires do something other than toggling themselves when activated. - Buttons can only accept assemblies with `ASSEMBLY_FUNCTIONAL_OUTPUT`. - Pressure plates can now accept any assembly with `ASSEMBLY_FUNCTIONAL_OUTPUT`, not just signalers. Assembly shells attached to pressure plates will draw power from the powernet if the pressure plate is under a tile. - Adds a new circuit component - the wire bundle. - This component gives the circuit a number of wires corresponding to the size of the shell. - Each wire has a corresponding port on the component that can pulse, and receive pulses from, that wire. - A circuit can only have one wire bundle component. - Assembly shells cannot be attached to these wires, and no wires will be created if the component is added to an assembly shell. - Available with roundstart tech. - Adds two new shells. - The wallmounted shell is a large shell that can be hung on walls, and uses power from the area it's placed in. - Frame icon: ![image](https://github.com/user-attachments/assets/2fe9297d-44a9-4ceb-b803-a758e59b807d) - Constructed icon: ![image](https://github.com/user-attachments/assets/34c3ffcb-53cb-415f-952f-aec5de63cf17) - The undertile shell is a small shell that only works when fit under a floor tile, but uses power from the area it's placed in. ![image](https://github.com/user-attachments/assets/11ea150d-08be-4ce9-bf44-35a9d6e2d94f) - Both shells support usb cables. - The above shells are available with the Advanced Shells techweb node. ## Why It's Good For The Game The wire bundle component complements the functionality of the assembly shell by allowing circuits to use assemblies directly in their logic. The wallmounted and undertile shells provide ways of placing circuits that don't necessarily take up space for machines. The undertile shell is particularly useful for relaying usb component data over wirenets. Pressure plates being able to accept assemblies other than signalers expands their uses significantly. ## Changelog :cl: refactor: Wires and assemblies have been refactored to have directionality to them. This mostly makes it so that assemblies can only be attached to wires it would make sense for them to be attached to. qol: Pressure plates can now also accept igniters, condensers, flashes, assembly shells, and door controllers. add: Undertile circuit shells. They only work when placed under floor tiles, but support USB cables and use APC power instead of cell power. add: Wallmounted circuit shells. Large shells that support USB cables and use APC power instead of cell power. add: Wire bundle component. Adds a number of wires to the circuit proportional to the capacity of the shell, allowing you to use assemblies in circuit logic. /:cl: --- code/__DEFINES/dcs/signals/signals_object.dm | 16 ++- code/__DEFINES/traits/declarations.dm | 3 + code/__DEFINES/wires.dm | 26 ++++ code/_globalvars/traits/_traits.dm | 1 + code/datums/wires/_wires.dm | 16 +-- code/datums/wires/scanner_gate.dm | 1 + code/datums/wires/wire_bundle_component.dm | 24 ++++ code/game/machinery/buttons.dm | 3 + .../objects/items/devices/pressureplates.dm | 42 ++++--- code/game/objects/items/puzzle_pieces.dm | 2 +- code/modules/assembly/assembly.dm | 4 +- code/modules/assembly/doorcontrol.dm | 1 - code/modules/assembly/health.dm | 2 +- code/modules/assembly/mousetrap.dm | 2 +- code/modules/assembly/proximity.dm | 2 +- code/modules/assembly/signaler.dm | 2 +- code/modules/assembly/timer.dm | 2 +- code/modules/assembly/voice.dm | 2 +- .../research/designs/wiremod_designs.dm | 34 ++++++ .../research/techweb/nodes/circuit_nodes.dm | 3 + .../wiremod/components/utility/wire_bundle.dm | 115 ++++++++++++++++++ code/modules/wiremod/shell/assembly.dm | 33 +++-- code/modules/wiremod/shell/undertile.dm | 13 ++ code/modules/wiremod/shell/wallmount.dm | 33 +++++ icons/obj/science/circuits.dmi | Bin 20554 -> 22989 bytes tgstation.dme | 4 + 26 files changed, 342 insertions(+), 44 deletions(-) create mode 100644 code/datums/wires/wire_bundle_component.dm create mode 100644 code/modules/wiremod/components/utility/wire_bundle.dm create mode 100644 code/modules/wiremod/shell/undertile.dm create mode 100644 code/modules/wiremod/shell/wallmount.dm diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 2044aab51e24d..4d9c6e9c00bf9 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -558,19 +558,29 @@ #define COMSIG_ASSEMBLY_DETACHED "assembly_detached" /* - * The following two signals are separate from the above two because buttons don't set the holder of the inserted assembly. + * The following four signals are separate from the above two because buttons and pressure plates don't set the holder of the inserted assembly. * This causes subtle behavioral differences that future handlers for these signals may need to account for, * even if none of the currently implemented handlers do. */ -/// Sent from /obj/machinery/button/assembly_act(obj/machinery/button/button, mob/user) +/// Sent when an assembly is added to a button : (obj/machinery/button/button, mob/user) #define COMSIG_ASSEMBLY_ADDED_TO_BUTTON "assembly_added_to_button" -/// Sent from /obj/machinery/button/remove_assembly(obj/machinery/button/button, mob/user) +/// Sent when an assembly is removed from a button : (obj/machinery/button/button, mob/user) #define COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON "assembly_removed_from_button" +/// Sent when an assembly is added to a pressure plate : (obj/item/pressureplate/pressure_plate, mob/user) +#define COMSIG_ASSEMBLY_ADDED_TO_PRESSURE_PLATE "assembly_added_to_pressure_plate" + +/// Sent when an assembly is removed from a pressure plate : (obj/item/pressureplate/pressure_plate, mob/user) +#define COMSIG_ASSEMBLY_REMOVED_FROM_PRESSURE_PLATE "assembly_removed_from_pressure_playe" + /// Sent from /datum/powernet/add_cable() #define COMSIG_CABLE_ADDED_TO_POWERNET "cable_added_to_powernet" /// Sent from /datum/powernet/remove_cable() #define COMSIG_CABLE_REMOVED_FROM_POWERNET "cable_removed_from_powernet" + +/// Sent from /datum/wires/attach_assembly() : (atom/holder) +#define COMSIG_ASSEMBLY_PRE_ATTACH "assembly_pre_attach" + #define COMPONENT_CANCEL_ATTACH (1<<0) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index dc3d6fa0c1d70..5d35a7fcb8718 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1424,4 +1424,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Mob doesn't get closed eyelids overlay when it gets knocked out cold or dies #define TRAIT_NO_EYELIDS "no_eyelids" +/// Trait applied when the wire bundle component is added to an [/obj/item/integrated_circuit] +#define TRAIT_COMPONENT_WIRE_BUNDLE "component_wire_bundle" + // END TRAIT DEFINES diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 4926996f26bd3..034bb8897e6e6 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -2,6 +2,30 @@ #define COMSIG_CUT_WIRE(wire) "cut_wire [wire]" #define COMSIG_MEND_WIRE(wire) "mend_wire [wire]" +/// from base of /datum/wires/proc/on_pulse : (wire, mob/user) +#define COMSIG_PULSE_WIRE "pulse_wire" + +// Directionality of wire pulses + +/// The wires interact with their holder when pulsed +#define WIRES_INPUT (1<<0) +/// The wires have a reason to toggle whether attached assemblies are armed +#define WIRES_TOGGLE_ARMED (1<<1) +/// The wires only want to activate assemblies that do something other than (dis)arming themselves +#define WIRES_FUNCTIONAL_OUTPUT (1<<2) +/// The holder can both pulse its wires and be affected by its wires getting pulsed +#define WIRES_ALL (WIRES_INPUT | WIRES_TOGGLE_ARMED | WIRES_FUNCTIONAL_OUTPUT) + +/// The assembly can pulse a wire it is attached to +#define ASSEMBLY_INPUT (1<<0) +/// The assembly toggles whether it will pulse the attached wire when it is pulsed by the attached wire +#define ASSEMBLY_TOGGLE_ARMED (1<<1) +/// The assembly does something other than just (dis)arming itself when it is pulsed by the wire it is attached to +#define ASSEMBLY_FUNCTIONAL_OUTPUT (1<<2) +/// The assembly can both pulse the wire it is attached to, and (dis)arms itself when pulsed by the wire +#define ASSEMBLY_TOGGLEABLE_INPUT (ASSEMBLY_INPUT | ASSEMBLY_TOGGLE_ARMED) +#define ASSEMBLY_ALL (ASSEMBLY_TOGGLEABLE_INPUT | ASSEMBLY_FUNCTIONAL_OUTPUT) + //retvals for attempt_wires_interaction #define WIRE_INTERACTION_FAIL 0 #define WIRE_INTERACTION_SUCCESSFUL 1 @@ -72,3 +96,5 @@ #define AI_WIRE_DISABLED 1 #define AI_WIRE_HACKED 2 #define AI_WIRE_DISABLED_HACKED -1 + +#define MAX_WIRE_COUNT 17 diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 4edc46bb50303..e351e155dc170 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -687,6 +687,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CIRCUIT_UI_OPEN" = TRAIT_CIRCUIT_UI_OPEN, "TRAIT_CIRCUIT_UNDUPABLE" = TRAIT_CIRCUIT_UNDUPABLE, "TRAIT_COMPONENT_MMI" = TRAIT_COMPONENT_MMI, + "TRAIT_COMPONENT_WIRE_BUNDLE" = TRAIT_COMPONENT_WIRE_BUNDLE, ), /obj/item/modular_computer = list( "TRAIT_MODPC_HALVED_DOWNLOAD_SPEED" = TRAIT_MODPC_HALVED_DOWNLOAD_SPEED, diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index 73bdc511ee4ba..13b9420d8366a 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -7,16 +7,14 @@ if(I.tool_behaviour == TOOL_WIRECUTTER || I.tool_behaviour == TOOL_MULTITOOL) return TRUE if(isassembly(I)) - var/obj/item/assembly/A = I - if(A.attachable) - return TRUE + return TRUE /atom/proc/attempt_wire_interaction(mob/user) if(!wires) return WIRE_INTERACTION_FAIL if(!user.CanReach(src)) return WIRE_INTERACTION_FAIL - wires.interact(user) + INVOKE_ASYNC(wires, TYPE_PROC_REF(/datum/wires, interact), user) return WIRE_INTERACTION_BLOCK /datum/wires @@ -29,6 +27,9 @@ /// The display name for the wire set shown in station blueprints. Not shown in blueprints if randomize is TRUE or it's an item NT wouldn't know about (Explosives/Nuke). Also used in the hacking interface. var/proper_name = "Unknown" + /// Whether pulsed wires affect the holder, and/or the holder pulses its wires + var/wire_behavior = WIRES_INPUT + /// List of all wires. var/list/wires = list() /// List of cut wires. @@ -179,6 +180,7 @@ /datum/wires/proc/pulse(wire, user, force=FALSE) if(!force && is_cut(wire)) return + SEND_SIGNAL(src, COMSIG_PULSE_WIRE, wire, user) on_pulse(wire, user) /datum/wires/proc/pulse_color(color, mob/living/user, force=FALSE) @@ -191,7 +193,7 @@ return TRUE /datum/wires/proc/attach_assembly(color, obj/item/assembly/S) - if(S && istype(S) && S.attachable && !is_attached(color)) + if(S && istype(S) && S.assembly_behavior && !is_attached(color) && !(SEND_SIGNAL(S, COMSIG_ASSEMBLY_PRE_ATTACH, holder) & COMPONENT_CANCEL_ATTACH)) assemblies[color] = S S.forceMove(holder) S.connected = src @@ -384,13 +386,13 @@ I = L.get_active_held_item() if(isassembly(I)) var/obj/item/assembly/A = I - if(A.attachable) + if(A.assembly_behavior & wire_behavior) if(!L.temporarilyRemoveItemFromInventory(A)) return if(!attach_assembly(target_wire, A)) A.forceMove(L.drop_location()) . = TRUE else - to_chat(L, span_warning("You need an attachable assembly!")) + to_chat(L, span_warning("You cannot attach this assembly to these wires!")) #undef MAXIMUM_EMP_WIRES diff --git a/code/datums/wires/scanner_gate.dm b/code/datums/wires/scanner_gate.dm index 14752ec6795ec..cb363d68f95ea 100644 --- a/code/datums/wires/scanner_gate.dm +++ b/code/datums/wires/scanner_gate.dm @@ -2,6 +2,7 @@ holder_type = /obj/machinery/scanner_gate proper_name = "Scanner Gate" wires = list(WIRE_ACCEPT, WIRE_DENY, WIRE_DISABLE) + wire_behavior = WIRES_FUNCTIONAL_OUTPUT /datum/wires/scanner_gate/on_pulse(wire, user) . = ..() diff --git a/code/datums/wires/wire_bundle_component.dm b/code/datums/wires/wire_bundle_component.dm new file mode 100644 index 0000000000000..5cd4ffa2af620 --- /dev/null +++ b/code/datums/wires/wire_bundle_component.dm @@ -0,0 +1,24 @@ +#define CAPACITY_PER_WIRE 10 + +/datum/wires/wire_bundle_component + holder_type = /atom //Anything that can have a shell component, really. + randomize = TRUE + wire_behavior = WIRES_ALL + +/datum/wires/wire_bundle_component/New(atom/holder) + var/datum/component/shell/shell_comp = holder.GetComponent(/datum/component/shell) + if(!istype(shell_comp)) + CRASH("Holder does not have a shell component!") + var/wire_count = clamp(round(shell_comp.capacity / CAPACITY_PER_WIRE, 1), 1, MAX_WIRE_COUNT) + for(var/index in 1 to wire_count) + wires += "Port [index]" + ..() + +/datum/wires/wire_bundle_component/always_reveal_wire(color) + return TRUE // Let's not make wiring up this stuff confusing - just give them what wires correspond to what ports. + +/datum/wires/wire_bundle_component/ui_data(mob/user) + proper_name = holder.name + . = ..() + +#undef CAPACITY_PER_WIRE diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index c8aba44ef4732..66f1b64795a6b 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -140,6 +140,9 @@ if(device) to_chat(user, span_warning("The button already contains a device!")) return ITEM_INTERACT_BLOCKING + if(!(new_device.assembly_behavior & ASSEMBLY_FUNCTIONAL_OUTPUT)) + to_chat(user, span_warning("\The [new_device] won't really do anything meaningful inside of the button...")) + return ITEM_INTERACT_BLOCKING if(!user.transferItemToLoc(new_device, src, silent = FALSE)) to_chat(user, span_warning("\The [new_device] is stuck to you!")) return ITEM_INTERACT_BLOCKING diff --git a/code/game/objects/items/devices/pressureplates.dm b/code/game/objects/items/devices/pressureplates.dm index 17f324d109f99..ea27894d829c3 100644 --- a/code/game/objects/items/devices/pressureplates.dm +++ b/code/game/objects/items/devices/pressureplates.dm @@ -14,12 +14,12 @@ var/specific_item = null var/trigger_silent = FALSE var/sound/trigger_sound = 'sound/effects/pressureplate.ogg' - var/obj/item/assembly/signaler/sigdev = null + var/obj/item/assembly/assembly = null var/roundstart_signaller = FALSE var/roundstart_signaller_freq = FREQ_PRESSURE_PLATE var/roundstart_signaller_code = 30 var/roundstart_hide = FALSE - var/removable_signaller = TRUE + var/removable_assembly = TRUE var/active = FALSE var/image/tile_overlay = null var/can_trigger = TRUE @@ -31,9 +31,10 @@ . = ..() tile_overlay = image(icon = 'icons/turf/floors.dmi', icon_state = "pp_overlay") if(roundstart_signaller) - sigdev = new - sigdev.code = roundstart_signaller_code - sigdev.set_frequency(roundstart_signaller_freq) + var/obj/item/assembly/signaler/signaller = new(src) + signaller.code = roundstart_signaller_code + signaller.set_frequency(roundstart_signaller_freq) + assembly = signaller if(undertile_pressureplate) AddElement(/datum/element/undertile, tile_overlay = tile_overlay, use_anchor = TRUE) @@ -59,21 +60,28 @@ /obj/item/pressure_plate/proc/trigger() can_trigger = TRUE - if(istype(sigdev)) - sigdev.signal() + if(istype(assembly)) + assembly.activate() -/obj/item/pressure_plate/attackby(obj/item/I, mob/living/L) - if(issignaler(I) && !istype(sigdev) && removable_signaller && L.transferItemToLoc(I, src)) - sigdev = I - to_chat(L, span_notice("You attach [I] to [src]!")) +/obj/item/pressure_plate/attackby(obj/item/item, mob/living/L) + if(isassembly(item) && !istype(assembly) && removable_assembly) + var/obj/item/assembly/new_assembly = item + if(!(new_assembly.assembly_behavior & ASSEMBLY_FUNCTIONAL_OUTPUT)) + to_chat(L, span_warning("\The [item] doesn't seem like it would do much of anything inside of [src]...")) + return + if(L.transferItemToLoc(item, src)) + assembly = item + SEND_SIGNAL(item, COMSIG_ASSEMBLY_ADDED_TO_PRESSURE_PLATE, src, L) + to_chat(L, span_notice("You attach [item] to [src]!")) return ..() /obj/item/pressure_plate/attack_self(mob/living/L) - if(removable_signaller && istype(sigdev)) - to_chat(L, span_notice("You remove [sigdev] from [src].")) - if(!L.put_in_hands(sigdev)) - sigdev.forceMove(get_turf(src)) - sigdev = null + if(removable_assembly && istype(assembly)) + to_chat(L, span_notice("You remove [assembly] from [src].")) + SEND_SIGNAL(assembly, COMSIG_ASSEMBLY_REMOVED_FROM_PRESSURE_PLATE, src, L) + if(!L.put_in_hands(assembly)) + assembly.forceMove(get_turf(src)) + assembly = null return ..() /obj/item/pressure_plate/item_ctrl_click(mob/user) @@ -97,7 +105,7 @@ protected = TRUE anchored = TRUE //this prevents us from being picked up active = TRUE - removable_signaller = FALSE + removable_assembly = FALSE /// puzzle id we send if stepped on var/puzzle_id /// queue size must match diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index a7bd4da85aebf..f5e3cf6da689e 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -168,7 +168,7 @@ trigger_mob = FALSE trigger_item = TRUE specific_item = /obj/structure/holobox - removable_signaller = FALSE //Being a pressure plate subtype, this can also use signals. + removable_assembly = FALSE //Being a pressure plate subtype, this can also use signals. roundstart_signaller_freq = FREQ_HOLOGRID_SOLUTION //Frequency is kept on its own default channel however. active = TRUE trigger_delay = 10 diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index dbd5a70461476..0ac5993aeccf5 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -23,7 +23,7 @@ var/secured = TRUE var/list/attached_overlays = null var/obj/item/assembly_holder/holder = null - var/attachable = FALSE // can this be attached to wires + var/assembly_behavior = ASSEMBLY_FUNCTIONAL_OUTPUT // how does the assembly behave with respect to what it's connected to var/datum/wires/connected = null var/next_activate = 0 //When we're next allowed to activate - for spam control @@ -126,7 +126,7 @@ balloon_alert(user, "can't attach another of that!") return if(new_assembly.secured || secured) - balloon_alert(user, "both devices not attachable!") + balloon_alert(user, "both devices not assembly_behavior!") return holder = new /obj/item/assembly_holder(drop_location()) diff --git a/code/modules/assembly/doorcontrol.dm b/code/modules/assembly/doorcontrol.dm index 31584976cedf3..3361028350238 100644 --- a/code/modules/assembly/doorcontrol.dm +++ b/code/modules/assembly/doorcontrol.dm @@ -2,7 +2,6 @@ name = "blast door controller" desc = "A small electronic device able to control a blast door remotely." icon_state = "control" - attachable = TRUE /// The ID of the blast door electronics to match to the ID of the blast door being used. var/id = null /// Cooldown of the door's controller. Updates when pressed (activate()) diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index ad2c6ac17641d..d4635ac159fe7 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -3,7 +3,7 @@ desc = "Used for scanning and monitoring health." icon_state = "health" custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*8, /datum/material/glass=SMALL_MATERIAL_AMOUNT * 2) - attachable = TRUE + assembly_behavior = ASSEMBLY_TOGGLEABLE_INPUT var/scanning = FALSE var/health_scan diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 187a161df80b7..2b2065a67a040 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -4,7 +4,7 @@ icon_state = "mousetrap" inhand_icon_state = "mousetrap" custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT) - attachable = TRUE + assembly_behavior = ASSEMBLY_TOGGLEABLE_INPUT var/armed = FALSE drop_sound = 'sound/items/handling/component_drop.ogg' pickup_sound = 'sound/items/handling/component_pickup.ogg' diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 6ba2a7a63421e..9b7ccad9aefcc 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -3,7 +3,7 @@ desc = "Used for scanning and alerting when someone enters a certain proximity." icon_state = "prox" custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*8, /datum/material/glass=SMALL_MATERIAL_AMOUNT * 2) - attachable = TRUE + assembly_behavior = ASSEMBLY_TOGGLEABLE_INPUT drop_sound = 'sound/items/handling/component_drop.ogg' pickup_sound = 'sound/items/handling/component_pickup.ogg' var/scanning = FALSE diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 4e265384ace24..b5346386d7dd3 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -6,7 +6,7 @@ lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 4, /datum/material/glass=SMALL_MATERIAL_AMOUNT*1.2) - attachable = TRUE + assembly_behavior = ASSEMBLY_ALL drop_sound = 'sound/items/handling/component_drop.ogg' pickup_sound = 'sound/items/handling/component_pickup.ogg' diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 09cbfd9b0dc59..b25d30e1b4b5c 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -3,7 +3,7 @@ desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." icon_state = "timer" custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*5, /datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5) - attachable = TRUE + assembly_behavior = ASSEMBLY_TOGGLEABLE_INPUT drop_sound = 'sound/items/handling/component_drop.ogg' pickup_sound = 'sound/items/handling/component_pickup.ogg' diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index de0954c960e5e..106b812730718 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -8,7 +8,7 @@ desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." icon_state = "voice" custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*5, /datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5) - attachable = TRUE + assembly_behavior = ASSEMBLY_TOGGLEABLE_INPUT verb_say = "beeps" verb_ask = "beeps" verb_exclaim = "beeps" diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index f8732cc332b72..526e8d2a54a11 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -477,6 +477,11 @@ id = "comp_assoc_list_pick" build_path = /obj/item/circuit_component/list_pick/assoc +/datum/design/component/wire_bundle + name = "Wire Bundle" + id = "comp_wire_bundle" + build_path = /obj/item/circuit_component/wire_bundle + /datum/design/component/wirenet_receive name = "Wirenet Receiver Component" id = "comp_wirenet_receive" @@ -691,3 +696,32 @@ category = list( RND_CATEGORY_CIRCUITRY + RND_SUBCATEGORY_CIRCUITRY_SHELLS ) + +/datum/design/undertile_shell + name = "Under-tile Shell" + desc = "A small shell that can fit under the floor." + id = "undertile_shell" + materials = list( + /datum/material/glass=HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/iron=SHEET_MATERIAL_AMOUNT*2.5, + ) + build_path = /obj/item/undertile_circuit + build_type = COMPONENT_PRINTER + category = list( + RND_CATEGORY_CIRCUITRY + RND_SUBCATEGORY_CIRCUITRY_SHELLS + ) + + +/datum/design/wallmount_shell + name = "Wall-mounted Shell" + desc = "A large shell that can be mounted on a wall." + id = "wallmount_shell" + materials = list( + /datum/material/glass=SHEET_MATERIAL_AMOUNT, + /datum/material/iron=SHEET_MATERIAL_AMOUNT*5, + ) + build_path = /obj/item/wallframe/circuit + build_type = COMPONENT_PRINTER + category = list( + RND_CATEGORY_CIRCUITRY + RND_SUBCATEGORY_CIRCUITRY_SHELLS + ) diff --git a/code/modules/research/techweb/nodes/circuit_nodes.dm b/code/modules/research/techweb/nodes/circuit_nodes.dm index 109873c38510b..9ef3b929ac424 100644 --- a/code/modules/research/techweb/nodes/circuit_nodes.dm +++ b/code/modules/research/techweb/nodes/circuit_nodes.dm @@ -86,6 +86,7 @@ "comp_typecast", "comp_typecheck", "comp_view_sensor", + "comp_wire_bundle", "comp_wirenet_receive", "comp_wirenet_send", "comp_wirenet_send_literal", @@ -108,6 +109,8 @@ "money_bot_shell", "scanner_gate_shell", "scanner_shell", + "undertile_shell", + "wallmount_shell", "comp_equip_action", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) diff --git a/code/modules/wiremod/components/utility/wire_bundle.dm b/code/modules/wiremod/components/utility/wire_bundle.dm new file mode 100644 index 0000000000000..7e0355e894837 --- /dev/null +++ b/code/modules/wiremod/components/utility/wire_bundle.dm @@ -0,0 +1,115 @@ +/obj/item/circuit_component/wire_bundle + display_name = "Wire Bundle" + desc = "A bundle of exposed wires that assemblies can be attached to. Ports will only show up once the circuit is inserted into a shell." + category = "Utility" + circuit_flags = CIRCUIT_FLAG_REFUSE_MODULE + + var/datum/wires/wire_bundle_component/tracked_wires + + var/list/wire_input_ports = list() + var/list/wire_output_ports = list() + +/obj/item/circuit_component/wire_bundle/get_ui_notices() + . = ..() + . += create_ui_notice("Port count is proportional to shell capacity.", "orange", "plug") + . += create_ui_notice("Max port count: [MAX_WIRE_COUNT]", "orange", "plug") + . += create_ui_notice("Incompatible with assembly shell.", "red", "plug-circle-xmark") + +/obj/item/circuit_component/wire_bundle/register_shell(atom/movable/shell) + . = ..() + if(isassembly(shell) && !parent.admin_only) + return + if(shell.wires) // Don't add wires to shells that already have some. + return + tracked_wires = new(shell) + shell.set_wires(tracked_wires) + for(var/wire in tracked_wires.wires) + wire_input_ports[add_input_port("Pulse [wire]", PORT_TYPE_SIGNAL)] = wire + wire_output_ports[wire] = add_output_port("[wire] Pulsed", PORT_TYPE_SIGNAL) + RegisterSignal(tracked_wires, COMSIG_PULSE_WIRE, PROC_REF(on_pulse_wire)) + RegisterSignal(shell, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_shell_requesting_context)) + RegisterSignal(shell, COMSIG_ATOM_ITEM_INTERACTION_SECONDARY, PROC_REF(on_shell_secondary_interaction)) + +/obj/item/circuit_component/wire_bundle/unregister_shell(atom/movable/shell) + . = ..() + if(shell.wires != tracked_wires) + return + UnregisterSignal(shell, list(COMSIG_ATOM_ITEM_INTERACTION_SECONDARY, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM)) + for(var/color in tracked_wires.colors) + var/obj/item/assembly/assembly = tracked_wires.detach_assembly(color) + if(assembly) + assembly.forceMove(drop_location()) + shell.set_wires(null) + QDEL_NULL(tracked_wires) + for(var/datum/port/input/in_port in wire_input_ports) + remove_input_port(in_port) + for(var/wire in wire_output_ports) + var/datum/port/output/out_port = wire_output_ports[wire] + remove_output_port(out_port) + wire_input_ports.Cut() + wire_output_ports.Cut() + +/obj/item/circuit_component/wire_bundle/add_to(obj/item/integrated_circuit/added_to) + . = ..() + if(HAS_TRAIT(added_to, TRAIT_COMPONENT_WIRE_BUNDLE)) + return FALSE + ADD_TRAIT(added_to, TRAIT_COMPONENT_WIRE_BUNDLE, REF(src)) + +/obj/item/circuit_component/wire_bundle/removed_from(obj/item/integrated_circuit/removed_from) + . = ..() + REMOVE_TRAIT(removed_from, TRAIT_COMPONENT_WIRE_BUNDLE, REF(src)) + return ..() + +/obj/item/circuit_component/wire_bundle/input_received(datum/port/input/port) + . = ..() + if(!port) + return + var/wire = wire_input_ports[port] + if(!wire) + return + if(tracked_wires.is_cut(wire)) + return + var/color = tracked_wires.get_color_of_wire(wire) + var/obj/item/assembly/attached = tracked_wires.get_attached(color) + attached?.activate() + +/obj/item/circuit_component/wire_bundle/proc/on_pulse_wire(source, wire) + SIGNAL_HANDLER + if(tracked_wires.is_cut(wire)) + return + var/datum/port/output/port = wire_output_ports[wire] + if(!istype(port)) + return + port.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/wire_bundle/proc/can_access_wires(atom/source) + if(ismachinery(source)) + var/obj/machinery/machine = source + return machine.panel_open + return TRUE + +/obj/item/circuit_component/wire_bundle/proc/on_shell_requesting_context(atom/source, list/context, obj/item/item, mob/user) + SIGNAL_HANDLER + . = NONE + + if(!is_wire_tool(item)) + return + if(!can_access_wires(source)) + return + context[SCREENTIP_CONTEXT_RMB] = "Interact with wires" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/circuit_component/wire_bundle/proc/on_shell_secondary_interaction(atom/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + if(!is_wire_tool(tool)) + return + if(!can_access_wires(source)) + return + var/datum/component/shell/shell_comp = source.GetComponent(/datum/component/shell) + if(shell_comp.locked) + source.balloon_alert(user, "locked!") + return ITEM_INTERACT_FAILURE + if(source.attempt_wire_interaction(user) == WIRE_INTERACTION_BLOCK) + return ITEM_INTERACT_BLOCKING + + diff --git a/code/modules/wiremod/shell/assembly.dm b/code/modules/wiremod/shell/assembly.dm index 3e69331c4c826..033808c84541a 100644 --- a/code/modules/wiremod/shell/assembly.dm +++ b/code/modules/wiremod/shell/assembly.dm @@ -7,13 +7,13 @@ name = "circuit assembly" desc = "A small electronic device that can house an integrated circuit." icon_state = "wiremod" - attachable = TRUE + assembly_behavior = ASSEMBLY_ALL /// A reference to any holder to use power from instead of the circuit's own cell var/atom/movable/power_use_proxy /// Valid types for `power_use_proxy` to be - var/static/list/power_use_override_types = list(/obj/machinery, /obj/vehicle/sealed/mecha, /obj/item/mod/control, /mob/living/silicon/robot) + var/static/list/power_use_override_types = list(/obj/machinery, /obj/vehicle/sealed/mecha, /obj/item/mod/control, /obj/item/pressure_plate, /mob/living/silicon/robot) /obj/item/assembly/wiremod/Initialize(mapload) . = ..() @@ -23,10 +23,11 @@ ), SHELL_CAPACITY_SMALL) RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_ATTACHED, PROC_REF(on_circuit_attached)) RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_REMOVED, PROC_REF(on_circuit_removed)) - RegisterSignals(src, list(COMSIG_ASSEMBLY_ATTACHED, COMSIG_ASSEMBLY_ADDED_TO_BUTTON), PROC_REF(on_attached)) - RegisterSignals(src, list(COMSIG_ASSEMBLY_DETACHED, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON), PROC_REF(on_detached)) + RegisterSignal(src, COMSIG_ASSEMBLY_PRE_ATTACH, PROC_REF(on_pre_attach)) + RegisterSignals(src, list(COMSIG_ASSEMBLY_ATTACHED, COMSIG_ASSEMBLY_ADDED_TO_BUTTON, COMSIG_ASSEMBLY_ADDED_TO_PRESSURE_PLATE), PROC_REF(on_attached)) + RegisterSignals(src, list(COMSIG_ASSEMBLY_DETACHED, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON, COMSIG_ASSEMBLY_REMOVED_FROM_PRESSURE_PLATE), PROC_REF(on_detached)) -/obj/item/assembly/wiremod/proc/on_circuit_attached(_source, obj/item/integrated_circuit/circuit) +/obj/item/assembly/wiremod/proc/on_circuit_attached(source, obj/item/integrated_circuit/circuit) SIGNAL_HANDLER RegisterSignal(circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, PROC_REF(override_circuit_power_usage)) @@ -34,12 +35,24 @@ SIGNAL_HANDLER UnregisterSignal(source.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE) -/obj/item/assembly/wiremod/proc/on_attached(_source, atom/movable/holder) +/obj/item/assembly/wiremod/proc/on_pre_attach(obj/item/circuit_component/wire_bundle/source, atom/holder) + SIGNAL_HANDLER + if(!istype(source)) + return + if(source.parent.admin_only) + return + if(istype(holder.wires, /datum/wires/wire_bundle_component)) + var/datum/component/shell/shell_comp = GetComponent(/datum/component/shell) + if(shell_comp.attached_circuit.admin_only) + return + return COMPONENT_CANCEL_ATTACH + +/obj/item/assembly/wiremod/proc/on_attached(source, atom/movable/holder) SIGNAL_HANDLER if(is_type_in_list(holder, power_use_override_types)) power_use_proxy = holder -/obj/item/assembly/wiremod/proc/on_detached(_source) +/obj/item/assembly/wiremod/proc/on_detached(source) SIGNAL_HANDLER power_use_proxy = null @@ -59,6 +72,12 @@ var/obj/item/mod/control/modsuit = power_use_proxy if(modsuit.subtract_charge(power_to_use)) return COMPONENT_OVERRIDE_POWER_USAGE + if(istype(power_use_proxy, /obj/item/pressure_plate)) + if(!power_use_proxy.anchored) + return + var/area/our_area = get_area(power_use_proxy) + if(our_area.apc?.use_energy(power_to_use, AREA_USAGE_EQUIP)) + return COMPONENT_OVERRIDE_POWER_USAGE if(iscyborg(power_use_proxy)) var/mob/living/silicon/robot/borg = power_use_proxy if(borg.cell?.use(power_to_use, force = TRUE)) diff --git a/code/modules/wiremod/shell/undertile.dm b/code/modules/wiremod/shell/undertile.dm new file mode 100644 index 0000000000000..69ef66b61c0ea --- /dev/null +++ b/code/modules/wiremod/shell/undertile.dm @@ -0,0 +1,13 @@ +/obj/item/undertile_circuit + name = "circuit panel" + desc = "A panel for an integrated circuit. It needs to be fit under a floor tile to operate." + icon = 'icons/obj/science/circuits.dmi' + inhand_icon_state = "flashtool" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + icon_state = "undertile" + +/obj/item/undertile_circuit/Initialize(mapload) + . = ..() + AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_OBSERVER, use_anchor = TRUE) + AddComponent(/datum/component/shell, null, SHELL_CAPACITY_SMALL, SHELL_FLAG_REQUIRE_ANCHOR|SHELL_FLAG_USB_PORT) diff --git a/code/modules/wiremod/shell/wallmount.dm b/code/modules/wiremod/shell/wallmount.dm new file mode 100644 index 0000000000000..d461f696da131 --- /dev/null +++ b/code/modules/wiremod/shell/wallmount.dm @@ -0,0 +1,33 @@ +/obj/structure/wallmount_circuit + name = "circuit box" + desc = "A wall-mounted box suitable for the installation of integrated circuits." + icon = 'icons/obj/science/circuits.dmi' + icon_state = "wallmount" + layer = BELOW_OBJ_LAYER + anchored = TRUE + + resistance_flags = LAVA_PROOF | FIRE_PROOF + +/obj/structure/wallmount_circuit/Initialize(mapload) + . = ..() + AddComponent(/datum/component/shell, null, SHELL_CAPACITY_LARGE, SHELL_FLAG_REQUIRE_ANCHOR|SHELL_FLAG_USB_PORT) + +/obj/structure/wallmount_circuit/wrench_act(mob/living/user, obj/item/tool) + var/datum/component/shell/shell_comp = GetComponent(/datum/component/shell) + if(shell_comp.locked) + balloon_alert(user, "locked!") + return ITEM_INTERACT_FAILURE + to_chat(user, span_notice("You start unsecuring the circuit box...")) + if(tool.use_tool(src, user, 40, volume=50)) + to_chat(user, span_notice("You unsecure the circuit box.")) + playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE) + deconstruct(TRUE) + return ITEM_INTERACT_SUCCESS + +/obj/item/wallframe/circuit + name = "circuit box frame" + desc = "A box that can be mounted on a wall and have circuits installed." + icon = 'icons/obj/science/circuits.dmi' + icon_state = "wallmount_assembly" + result_path = /obj/structure/wallmount_circuit + pixel_shift = 32 diff --git a/icons/obj/science/circuits.dmi b/icons/obj/science/circuits.dmi index 1d50c67823bb2fc9afac7e40e397772f11f83794..e91025ae61365e780a5bac27a325fc62858f451b 100644 GIT binary patch literal 22989 zcmZs@1z1$wyEeWDkdPQsK)OVw1q5l3PC*H2Md^}ukdzRRmhO^}?ruZ`rMm@$p(ICo zzQy~V-*?Xc|DEg7YuI~sti9J-&wW4lbFT?`qOL%A^Y%>$f(VrqWwjs(CUyNE7aQ#P z5tUa2HgXWp^ju_LJDWLKIl5Rm*h7#KT7MM#%12TOu8 z&7)U2efS$6nD${cs*cqP3BQ+#t}Hl;LVh+6l)#(mcSt#oG~is@Yu ziCIuo&%i*$;|re0R+^eFgaKaW!s$M&8FE}Y*`#b780pndr?p<$QHw5G(0)ud4pA=d z&RF5UFRiOiRqV!l>|qqU;Y9rT=a5i(^$uPPim3C{J~6I9_E=~j<0iS0ohK&uyu9vY zQ^vB^DmlHY&~d6!d+tF;ljgBVlYhT~=n1^3@nu!#8H>KlJ)2(%TW6&K<-kA@k1yL!&77t;{81ni z@*Ng_>vYK}c%!Y*gKvkU>ZVjv5X1;6$x1)-NZo1iawMNj`+J_IM&KVU@E}H-I9Ibh zeiwr@B8~)A#Y(^SmB}rW7RO50+?ne&N2h_u4|Br2xq}*8>Wh;*T zJdN2&A-!|!Ro7JHTMudu8>JvIe_v`mvkqlm7AC7HTl+;xg!&*d-P-My{6yVv7-2z>R&lAbls|TSWMS}&)T1>Ley2*S>AtQI^o4cLsr?t8>yA( z=LUmc6Uk_W9eq=hl7y?>&mhSnBW z*0)LT+;JojeSuLB`}M2*<5G78h2CPXCl==Bj(cd)0&4q}0r}xG9Gi(HX$XDml=K3+ z+Br#B@_|l9RuedT@1=}nM2jRso0%0A(O-&-W!2RqO7|-C2*Sg|=WM-jDLM6`SnZXU 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 Date: Sun, 19 Jan 2025 18:44:23 +0000 Subject: [PATCH 13/23] Automatic changelog for PR #89122 [ci skip] --- html/changelogs/AutoChangeLog-pr-89122.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89122.yml diff --git a/html/changelogs/AutoChangeLog-pr-89122.yml b/html/changelogs/AutoChangeLog-pr-89122.yml new file mode 100644 index 0000000000000..74c844109328a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89122.yml @@ -0,0 +1,8 @@ +author: "Y0SH1M4S73R" +delete-after: True +changes: + - refactor: "Wires and assemblies have been refactored to have directionality to them. This mostly makes it so that assemblies can only be attached to wires it would make sense for them to be attached to." + - qol: "Pressure plates can now also accept igniters, condensers, flashes, assembly shells, and door controllers." + - rscadd: "Undertile circuit shells. They only work when placed under floor tiles, but support USB cables and use APC power instead of cell power." + - rscadd: "Wallmounted circuit shells. Large shells that support USB cables and use APC power instead of cell power." + - rscadd: "Wire bundle component. Adds a number of wires to the circuit proportional to the capacity of the shell, allowing you to use assemblies in circuit logic." \ No newline at end of file From 3986b5d4b3eb04368fbabe2861856bcb3554edd4 Mon Sep 17 00:00:00 2001 From: RengaN02 <60517664+RengaN02@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:49:01 +0300 Subject: [PATCH 14/23] Fixes Engine Diagnostic surgery (#89131) ## About The Pull Request There was no mechanical version of the coronary bypass and then I checked the code. ## Why It's Good For The Game Its a little fix ## Changelog :cl: fix: Fixed Engine Diagnostic surgery /:cl: --- code/modules/surgery/coronary_bypass.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index 1c5012d7580b9..be147e541181c 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -12,7 +12,7 @@ /datum/surgery_step/close, ) -/datum/surgery/gastrectomy/mechanic +/datum/surgery/coronary_bypass/mechanic name = "Engine Diagnostic" requires_bodypart_type = BODYTYPE_ROBOTIC steps = list( From 60a56f70ee2cae4f396b708a7c1917e8a844b0be Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 18:49:51 +0000 Subject: [PATCH 15/23] Automatic changelog for PR #89131 [ci skip] --- html/changelogs/AutoChangeLog-pr-89131.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89131.yml diff --git a/html/changelogs/AutoChangeLog-pr-89131.yml b/html/changelogs/AutoChangeLog-pr-89131.yml new file mode 100644 index 0000000000000..4b1a73b6c3e31 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89131.yml @@ -0,0 +1,4 @@ +author: "RengaN02" +delete-after: True +changes: + - bugfix: "Fixed Engine Diagnostic surgery" \ No newline at end of file From cbc7437735db4107688cce287573f30a01019225 Mon Sep 17 00:00:00 2001 From: Bloop <13398309+vinylspiders@users.noreply.github.com> Date: Sun, 19 Jan 2025 14:11:14 -0500 Subject: [PATCH 16/23] Removes the from from from from (#89127) --- code/modules/antagonists/heretic/magic/furious_steel.dm | 4 ++-- code/modules/vehicles/mecha/mech_fabricator.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm index 4f2bb2dd7f108..ec3248af422fe 100644 --- a/code/modules/antagonists/heretic/magic/furious_steel.dm +++ b/code/modules/antagonists/heretic/magic/furious_steel.dm @@ -1,7 +1,7 @@ /datum/action/cooldown/spell/pointed/projectile/furious_steel name = "Furious Steel" desc = "Summon three silver blades which orbit you. \ - While orbiting you, these blades will protect you from from attacks, but will be consumed on use. \ + While orbiting you, these blades will protect you from attacks, but will be consumed on use. \ Additionally, you can click to fire the blades at a target, dealing damage and causing bleeding." background_icon_state = "bg_heretic" overlay_icon_state = "bg_heretic_border" @@ -151,7 +151,7 @@ /datum/action/cooldown/spell/pointed/projectile/furious_steel/haunted name = "Cursed Steel" desc = "Summon two cursed blades which orbit you. \ - While orbiting you, these blades will protect you from from attacks, but will be consumed on use. \ + While orbiting you, these blades will protect you from attacks, but will be consumed on use. \ Additionally, you can click to fire the blades at a target, dealing damage and causing bleeding." background_icon_state = "bg_heretic" // kept intentionally overlay_icon_state = "bg_cult_border" diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index ad28886d99f22..7667178392a8a 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -476,7 +476,7 @@ return if("del_queue_part") - // Delete a specific from from the queue + // Delete a specific from the queue var/index = text2num(params["index"]) remove_from_queue(index) From 4b512f1239ebda17d74d99181ab97fcb7e81c23f Mon Sep 17 00:00:00 2001 From: jimmyl <70376633+mc-oofert@users.noreply.github.com> Date: Sun, 19 Jan 2025 22:29:49 +0100 Subject: [PATCH 17/23] makes mimics into basicmobs (#88910) ## About The Pull Request mimics are basicmobs now the only change not carried over worth mentioning is that all mimics are a consistent speed because i cant imagine a gun or object with aimbot going at you mach 2 would be very fun mimic crates had some stuff changed compared to their simple animal variant they open and close their lid when attacking (unless locked) to be like menacing or something like animals flash colors to ward off people attempting to open a nonsentient hostile crate mimic will make it lock itself (if it contains anything) and attack you mimics are a really stupid naming for these because like mimic crates pretend to be crates anything else inheriting from mimics are just used to make objects alive https://github.com/user-attachments/assets/34a733a4-45a3-409e-8a6a-b2a8c7540898 ranged mimics now use viscontents (they also keep trying to pointblank people for some reason i think thats ok though unless its a wand of fireball) ranged mimic (any ranged weapon animated by a bolt of animation) https://github.com/user-attachments/assets/c3f1d2f5-cfb8-46a9-a58c-255c53a034db ## Why It's Good For The Game fixes #85668 ## Changelog :cl: refactor: mimics (bolt of animation, malf ai Machine Override, etc) are basicmobs fix: crate mimics may now be opened /:cl: --------- Co-authored-by: Jacquerel --- ..._underground_abandoned_plasma_facility.dmm | 4 +- _maps/map_files/Birdshot/birdshot.dmm | 2 +- _maps/map_files/wawastation/wawastation.dmm | 2 +- _maps/virtual_domains/psyker_shuffle.dmm | 12 +- code/__DEFINES/ai/monsters.dm | 2 + code/_globalvars/lists/mobs.dm | 2 +- code/game/objects/items.dm | 2 +- code/game/objects/structures.dm | 2 +- code/modules/admin/verbs/spawnobjasmob.dm | 15 +- .../antagonists/malf_ai/malf_ai_modules.dm | 2 +- code/modules/mining/abandoned_crates.dm | 2 +- .../living/basic/ruin_defender/mimic/mimic.dm | 403 +++++++++++++++++ .../basic/ruin_defender/mimic/mimic_ai.dm | 86 ++++ .../mob/living/simple_animal/hostile/mimic.dm | 423 ------------------ code/modules/projectiles/gun.dm | 2 +- .../unit_tests/simple_animal_freeze.dm | 6 - tgstation.dme | 3 +- .../Scripts/88910_mimicbasicmobs.txt | 5 + 18 files changed, 521 insertions(+), 454 deletions(-) create mode 100644 code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm create mode 100644 code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm delete mode 100644 code/modules/mob/living/simple_animal/hostile/mimic.dm create mode 100644 tools/UpdatePaths/Scripts/88910_mimicbasicmobs.txt diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm index 0bfcc133f0c98..e5f7305eba078 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_plasma_facility.dmm @@ -338,7 +338,7 @@ /obj/structure/railing/corner{ dir = 4 }, -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/basic/mimic/crate, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) "fO" = ( @@ -2073,7 +2073,7 @@ /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) "KV" = ( -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/basic/mimic/crate, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) "KY" = ( diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index ff06bb5914c6b..758a5c877925e 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -26116,7 +26116,7 @@ /turf/open/floor/iron/smooth_large, /area/station/science/robotics/mechbay) "iPU" = ( -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/basic/mimic/crate, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "iPW" = ( diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 0295a23f50395..64cad41bbebb1 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -840,7 +840,7 @@ /obj/effect/decal/cleanable/blood/old{ icon_state = "gib3-old" }, -/mob/living/simple_animal/hostile/mimic, +/mob/living/basic/mimic/crate, /turf/open/floor/iron/white, /area/station/maintenance/aft/upper) "anu" = ( diff --git a/_maps/virtual_domains/psyker_shuffle.dmm b/_maps/virtual_domains/psyker_shuffle.dmm index c744cecf0b430..5f303d4ae0471 100644 --- a/_maps/virtual_domains/psyker_shuffle.dmm +++ b/_maps/virtual_domains/psyker_shuffle.dmm @@ -64,11 +64,7 @@ /turf/template_noop, /area/template_noop) "r" = ( -/mob/living/simple_animal/hostile/mimic, -/turf/open/indestructible/dark, -/area/virtual_domain) -"s" = ( -/mob/living/simple_animal/hostile/mimic/crate, +/mob/living/basic/mimic/crate, /turf/open/indestructible/dark, /area/virtual_domain) "t" = ( @@ -767,7 +763,7 @@ Y Q Q Q -s +r M Q Q @@ -878,11 +874,11 @@ o Y a Q -s +r Y Y Y -s +r Q Q Q diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index d77817a203980..6a1433fa5ec86 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -312,3 +312,5 @@ #define BB_TURTLE_HEADBUTT_VICTIM "turtle_headbutt_victim" ///flore we must smell #define BB_TURTLE_FLORA_TARGET "turtle_flora_target" + +#define BB_GUNMIMIC_GUN_EMPTY "BB_GUNMIMIC_GUN_EMPTY" diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 5ece846e84de3..6024f7991388d 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -29,7 +29,7 @@ GLOBAL_LIST_INIT(abstract_mob_types, list( /mob/living/simple_animal/hostile/asteroid/elite, /mob/living/simple_animal/hostile/asteroid, /mob/living/simple_animal/hostile/megafauna, - /mob/living/simple_animal/hostile/mimic, // Cannot exist if spawned without being passed an item reference + /mob/living/basic/mimic, // Cannot exist if spawned without being passed an item reference /mob/living/simple_animal/hostile/retaliate, /mob/living/simple_animal/hostile, /mob/living/simple_animal/soulscythe, // As mimic, can't exist if spawned outside an item diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 0d00b4f355a03..b389438f0f9be 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1840,7 +1840,7 @@ return null /obj/item/animate_atom_living(mob/living/owner) - new /mob/living/simple_animal/hostile/mimic/copy(drop_location(), src, owner) + new /mob/living/basic/mimic/copy(drop_location(), src, owner) /** * Used to update the weight class of the item in a way that other atoms can react to the change. diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index e6c9579d67936..7f5e4c6b76d89 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -71,7 +71,7 @@ . = ..() /obj/structure/animate_atom_living(mob/living/owner) - new /mob/living/simple_animal/hostile/mimic/copy(drop_location(), src, owner) + new /mob/living/basic/mimic/copy(drop_location(), src, owner) /// For when a mob comes flying through the window, smash it and damage the mob /obj/structure/proc/smash_and_injure(mob/living/flying_mob, atom/oldloc, direction) diff --git a/code/modules/admin/verbs/spawnobjasmob.dm b/code/modules/admin/verbs/spawnobjasmob.dm index e673202f0bae1..c8d9ba3719d13 100644 --- a/code/modules/admin/verbs/spawnobjasmob.dm +++ b/code/modules/admin/verbs/spawnobjasmob.dm @@ -4,7 +4,7 @@ ADMIN_VERB(spawn_obj_as_mob, R_SPAWN, "Spawn Object-Mob", "Spawn an object as if if (!chosen) return - var/mob/living/simple_animal/hostile/mimic/copy/basemob = /mob/living/simple_animal/hostile/mimic/copy + var/mob/living/basic/mimic/copy/basemob = /mob/living/basic/mimic/copy var/obj/chosen_obj = text2path(chosen) @@ -54,8 +54,8 @@ ADMIN_VERB(spawn_obj_as_mob, R_SPAWN, "Spawn Object-Mob", "Spawn an object as if "mobtype" = list( "desc" = "Base mob type", "type" = "datum", - "path" = "/mob/living/simple_animal/hostile/mimic/copy", - "value" = "/mob/living/simple_animal/hostile/mimic/copy", + "path" = "/mob/living/basic/mimic/copy", + "value" = "/mob/living/basic/mimic/copy", ), "ckey" = list( "desc" = "ckey", @@ -71,13 +71,14 @@ ADMIN_VERB(spawn_obj_as_mob, R_SPAWN, "Spawn Object-Mob", "Spawn an object as if chosen_obj = text2path(mainsettings["objtype"]["value"]) basemob = text2path(mainsettings["mobtype"]["value"]) - if (!ispath(basemob, /mob/living/simple_animal/hostile/mimic/copy) || !ispath(chosen_obj, /obj)) + if (!ispath(basemob, /mob/living/basic/mimic/copy) || !ispath(chosen_obj, /obj)) to_chat(user.mob, "Mob or object path invalid", confidential = TRUE) basemob = new basemob(get_turf(user.mob), new chosen_obj(get_turf(user.mob)), user.mob, mainsettings["dropitem"]["value"] == "Yes" ? FALSE : TRUE, (mainsettings["googlyeyes"]["value"] == "Yes" ? FALSE : TRUE)) if (mainsettings["disableai"]["value"] == "Yes") - basemob.toggle_ai(AI_OFF) + qdel(basemob.ai_controller) + basemob.ai_controller = null if (mainsettings["idledamage"]["value"] == "No") basemob.idledamage = FALSE @@ -85,7 +86,9 @@ ADMIN_VERB(spawn_obj_as_mob, R_SPAWN, "Spawn Object-Mob", "Spawn an object as if if (mainsettings["access"]) var/newaccess = text2path(mainsettings["access"]["value"]) if (ispath(newaccess)) - basemob.access_card = new newaccess + var/obj/item/card/id/id = new newaccess //cant do initial on lists + basemob.AddComponent(/datum/component/simple_access, id.access) + qdel(id) if (mainsettings["maxhealth"]["value"]) if (!isnum(mainsettings["maxhealth"]["value"])) diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index 22e32d8264ab7..c95302c80ae11 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -479,7 +479,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) if(QDELETED(to_animate)) return - new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(to_animate), to_animate, clicker, TRUE) + new /mob/living/basic/mimic/copy/machine(get_turf(to_animate), to_animate, clicker, TRUE) /// Destroy RCDs: Detonates all non-cyborg RCDs on the station. /datum/ai_module/malf/destructive/destroy_rcd diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 10b2fbe71d062..7fa66c8a65ce7 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -231,7 +231,7 @@ if(93) new /obj/item/dnainjector/xraymut(src) if(94) - new /mob/living/simple_animal/hostile/mimic/crate(src) + new /mob/living/basic/mimic/crate(src) qdel_on_open = TRUE if(95) new /obj/item/toy/plush/nukeplushie(src) diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm new file mode 100644 index 0000000000000..b8661c3c38ea8 --- /dev/null +++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm @@ -0,0 +1,403 @@ +#define CANT_INSERT_FULL -1 +/// Mimics can't be made out of these objects +GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( + /obj/structure/table, + /obj/structure/cable, + /obj/structure/window, + /obj/structure/blob, +))) + +/mob/living/basic/mimic + response_help_continuous = "touches" + response_help_simple = "touch" + response_disarm_continuous = "pushes" + response_disarm_simple = "push" + speed = 6 + maxHealth = 250 + health = 250 + gender = NEUTER + mob_biotypes = NONE + pass_flags = PASSFLAPS + melee_damage_lower = 8 + melee_damage_upper = 12 + attack_sound = 'sound/items/weapons/punch1.ogg' + speak_emote = list("creaks") + + unsuitable_cold_damage = 0 + unsuitable_heat_damage = 0 + unsuitable_atmos_damage = 0 + + faction = list(FACTION_MIMIC) + basic_mob_flags = DEL_ON_DEATH + combat_mode = TRUE + /// can we stun people on hit + var/knockdown_people = FALSE + +/mob/living/basic/mimic/melee_attack(mob/living/carbon/target, list/modifiers, ignore_cooldown) + . = ..() + if(!. || !knockdown_people || !prob(15) || !istype(target)) + return + target.Paralyze(4 SECONDS) + target.visible_message(span_danger("\The [src] knocks down \the [target]!"), \ + span_userdanger("\The [src] knocks you down!")) + + +// **************************** +// CRATE MIMIC +// **************************** + +// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. +/mob/living/basic/mimic/crate + name = "crate" + desc = "A rectangular steel crate." + icon = 'icons/obj/storage/crates.dmi' + icon_state = "crate" + icon_living = "crate" + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + speak_emote = list("clatters") + layer = BELOW_MOB_LAYER + ai_controller = /datum/ai_controller/basic_controller/mimic_crate + /// are we open + var/opened = FALSE + /// max mob size + var/max_mob_size = MOB_SIZE_HUMAN + /// can we be opened or closed, if false we can + var/locked = FALSE + /// action to lock us + var/datum/action/innate/mimic_lock/lock + ///A cap for items in the mimic. Prevents the mimic from eating enough stuff to cause lag when opened. + var/storage_capacity = 50 + ///A cap for mobs. Mobs count towards the item cap. Same purpose as above. + var/mob_storage_capacity = 10 + +// Pickup loot +/mob/living/basic/mimic/crate/Initialize(mapload) + . = ..() + lock = new + lock.Grant(src) + ADD_TRAIT(src, TRAIT_AI_PAUSED, INNATE_TRAIT) + ai_controller?.set_ai_status(AI_STATUS_OFF) //start inert, let gullible people pull us into cargo or something and then go nuts when opened + if(mapload) //eat shit + for(var/obj/item/item in loc) + item.forceMove(src) + +/mob/living/basic/mimic/crate/Destroy() + lock = null + return ..() + +/mob/living/basic/mimic/crate/attack_hand(mob/living/carbon/human/user, list/modifiers) + if(user.combat_mode) + return ..() + if(trigger()) + to_chat(user, span_danger("As you try to open [src] it [length(contents) ? "stiffens up and " : ""]nearly clamps down on your fingers!")) + return TRUE + toggle_open(user) + return TRUE + +/mob/living/basic/mimic/crate/melee_attack(mob/living/carbon/target, list/modifiers, ignore_cooldown) + . = ..() + toggle_open() // show our cool lid at the dumbass humans + +/mob/living/basic/mimic/crate/proc/trigger() + if(isnull(ai_controller) || client) + return FALSE + if(ai_controller.ai_status != AI_STATUS_OFF) + return FALSE + visible_message(span_danger("[src] starts to move!")) + REMOVE_TRAIT(src, TRAIT_AI_PAUSED, INNATE_TRAIT) + ai_controller.set_ai_status(AI_STATUS_ON) + if(length(contents)) + locked = TRUE //if this was a crate with loot then we dont want people to just leftclick it to open it then bait it somewhere and steal its loot + return TRUE + +/mob/living/basic/mimic/crate/adjust_health(amount, updating_health = TRUE, forced = FALSE) + if(amount > 0) + trigger() + return ..() + +/mob/living/basic/mimic/crate/death() + var/obj/structure/closet/crate/lootbox = new(get_turf(src)) + // Put loot in crate + for(var/obj/loot in src) + loot.forceMove(lootbox) + return ..() + +/mob/living/basic/mimic/crate/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) + if(target == src) + toggle_open() + return FALSE + return ..() + +/mob/living/basic/mimic/crate/CanAllowThrough(atom/movable/mover, border_dir) + . = ..() + if(istype(mover, /obj/structure/closet)) + return FALSE + +/** +* Used to open and close the mimic +* +* Will insert tile contents into the mimic when closing +* Will dump mimic contents into the time when opening +* Does nothing if the mimic locked itself +*/ +/mob/living/basic/mimic/crate/proc/toggle_open(mob/user) + if(locked) + if(user) + balloon_alert(user, "too stiff!") + return + if(!opened) + ADD_TRAIT(src, TRAIT_UNDENSE, MIMIC_TRAIT) + opened = TRUE + icon_state = "crateopen" + playsound(src, 'sound/machines/crate/crate_open.ogg', 50, TRUE) + for(var/atom/movable/movable as anything in src) + movable.forceMove(loc) + else + REMOVE_TRAIT(src, TRAIT_UNDENSE, MIMIC_TRAIT) + opened = FALSE + icon_state = "crate" + playsound(src, 'sound/machines/crate/crate_close.ogg', 50, TRUE) + for(var/atom/movable/movable as anything in get_turf(src)) + if(movable != src && insert(movable) == CANT_INSERT_FULL) + playsound(src, 'sound/items/trayhit/trayhit2.ogg', 50, TRUE) + break + +/** +* Called by toggle_open to put items inside the mimic when it's being closed +* +* Will return CANT_INSERT_FULL (-1) if the insertion fails due to the storage capacity of the mimic having been reached +* Will return FALSE if insertion fails +* Will return TRUE if insertion succeeds +* Arguments: +* * AM - item to be inserted +*/ +/mob/living/basic/mimic/crate/proc/insert(atom/movable/movable) + if(contents.len >= storage_capacity) + return CANT_INSERT_FULL + if(insertion_allowed(movable)) + movable.forceMove(src) + return TRUE + return FALSE + +/mob/living/basic/mimic/crate/proc/insertion_allowed(atom/movable/movable) + if(movable.anchored) + return FALSE + if(ismob(movable)) + if(!isliving(movable)) //Don't let ghosts and such get trapped in the beast. + return FALSE + var/mob/living/living = movable + if(living.anchored || living.buckled || living.incorporeal_move || living.has_buckled_mobs()) + return FALSE + if(living.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. + if(living.density || living.mob_size > max_mob_size) + return FALSE + var/mobs_stored = 0 + for(var/mob/living/living_mob in contents) + mobs_stored++ + if(mobs_stored >= mob_storage_capacity) + return FALSE + living.stop_pulling() + + else if(istype(movable, /obj/structure/closet)) + return FALSE + else if(isobj(movable)) + if(movable.has_buckled_mobs()) + return FALSE + else if(isitem(movable) && !HAS_TRAIT(movable, TRAIT_NODROP)) + return TRUE + else + return FALSE + return TRUE + +/mob/living/basic/mimic/crate/xenobio + health = 210 + maxHealth = 210 + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + speak_emote = list("clatters") + gold_core_spawnable = HOSTILE_SPAWN + +/datum/action/innate/mimic_lock + name = "Lock/Unlock" + desc = "Toggle preventing yourself from being opened or closed." + button_icon = 'icons/hud/radial.dmi' + button_icon_state = "radial_lock" + background_icon_state = "bg_default" + overlay_icon_state = "bg_default_border" + +/datum/action/innate/mimic/lock/Activate() + var/mob/living/basic/mimic/crate/mimic = owner + mimic.locked = !mimic.locked + if(!mimic.locked) + to_chat(mimic, span_warning("You loosen up, allowing yourself to be opened and closed.")) + else + to_chat(mimic, span_warning("You stiffen up, preventing anyone from opening or closing you.")) + +// **************************** +// COPYING (actually imitates target object) MIMIC +// **************************** + +/mob/living/basic/mimic/copy + health = 100 + maxHealth = 100 + mob_biotypes = MOB_SPECIAL + ai_controller = /datum/ai_controller/basic_controller/mimic_copy + /// our creator + var/datum/weakref/creator_ref + /// googly eyes overlay + var/static/mutable_appearance/googly_eyes = mutable_appearance('icons/mob/simple/mob.dmi', "googly_eyes") + /// do we overlay googly eyes over whatever we copy + var/overlay_googly_eyes = TRUE + /// do we take damage when we are not sentient and have no target + var/idledamage = TRUE + /// copied object + var/atom/movable/copied + +/mob/living/basic/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = FALSE, no_googlies = FALSE) + . = ..() + ADD_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // They won't remember their original contents upon ressurection and would just be floating eyes + if (no_googlies) + overlay_googly_eyes = FALSE + CopyObject(copy, creator, destroy_original) + +/mob/living/basic/mimic/copy/Destroy() + creator_ref = null + copied = null + return ..() + +/mob/living/basic/mimic/copy/Life(seconds_per_tick = SSMOBS_DT, times_fired) + . = ..() + if(idledamage && !ckey && !ai_controller?.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) //Objects eventually revert to normal if no one is around to terrorize + adjustBruteLoss(0.5 * seconds_per_tick) + for(var/mob/living/victim in contents) //a fix for animated statues from the flesh to stone spell + death() + return + +/mob/living/basic/mimic/copy/death() + for(var/atom/movable/movable as anything in src) + movable.forceMove(get_turf(src)) + return ..() + +/mob/living/basic/mimic/copy/wabbajack(what_to_randomize, change_flags = WABBAJACK) + visible_message(span_warning("[src] resists polymorphing into a new creature!")) + +/mob/living/basic/mimic/copy/animate_atom_living(mob/living/owner) + change_owner(owner) + +/mob/living/basic/mimic/copy/Exited(atom/movable/gone, direction) // if our object gets deleted it calls Exited + . = ..() + if(QDELETED(src) || gone != copied) + return + death() + +/mob/living/basic/mimic/copy/proc/change_owner(mob/owner) + var/mob/creator_resolved = creator_ref?.resolve() + if(!creator_resolved) + creator_ref = null + if(isnull(owner) || creator_resolved == owner) + return + unfriend(creator_resolved) + befriend(owner) + creator_ref = WEAKREF(owner) + +/// Check whether this object can be copied. If destroy_original is true, this proc is ignored. +/mob/living/basic/mimic/copy/proc/check_object(obj/target) + return ((isitem(target) || isstructure(target)) && !is_type_in_typecache(target, GLOB.animatable_blacklist)) + +/mob/living/basic/mimic/copy/proc/CopyObject(obj/original, mob/living/user, destroy_original = FALSE) + if(!destroy_original && !check_object(original)) + return FALSE + if(!destroy_original) + original.forceMove(src) + copied = original + CopyObjectVisuals(original) + if (overlay_googly_eyes) + add_overlay(googly_eyes) + if(isstructure(original) || ismachinery(original)) + health = (anchored * 50) + 50 + if(original.density && original.anchored) + knockdown_people = TRUE + melee_damage_lower *= 2 + melee_damage_upper *= 2 + else if(isitem(original)) + var/obj/item/I = original + health = 15 * I.w_class + melee_damage_lower = 2 + I.force + melee_damage_upper = 2 + I.force + maxHealth = health + if(user) + change_owner(user) + if(destroy_original) + qdel(original) + return TRUE + +/// Copies the object visually including name and desc +/mob/living/basic/mimic/copy/proc/CopyObjectVisuals(obj/original) + name = original.name + desc = original.desc + icon = original.icon + icon_state = original.icon_state + icon_living = icon_state + copy_overlays(original, cut_old = TRUE) + +/mob/living/basic/mimic/copy/machine + ai_controller = /datum/ai_controller/basic_controller/mimic_copy/machine + faction = list(FACTION_MIMIC, FACTION_SILICON) + +/mob/living/basic/mimic/copy/ranged + icon = 'icons/turf/floors.dmi' + icon_state = "invisible" + ai_controller = /datum/ai_controller/basic_controller/mimic_copy/gun + +/mob/living/basic/mimic/copy/ranged/Destroy() + vis_contents.Cut() + return ..() + +/mob/living/basic/mimic/copy/ranged/RangedAttack(atom/atom_target, modifiers) + INVOKE_ASYNC(src, PROC_REF(fire_gun), atom_target, modifiers) + +/mob/living/basic/mimic/copy/ranged/proc/fire_gun(atom/target, modifiers) // i cant find any better way to do this + var/obj/item/gun/gun = locate() in contents + if(!gun.can_shoot()) + if(istype(gun, /obj/item/gun/ballistic)) + var/obj/item/gun/ballistic/ballistic = gun + if(!ballistic.chambered || ballistic.bolt_locked) + ballistic.rack() //we racked so both checked variables should be something else now + // do we have nothing chambered/chambered is spent AND we have no mag or our mag is empty + if(!ballistic.chambered?.loaded_projectile && magazine_useless(gun)) // ran out of ammo + ai_controller?.set_blackboard_key(BB_GUNMIMIC_GUN_EMPTY, TRUE) //BANZAIIIIIIII + ai_controller?.CancelActions() + else //if we cant fire we probably like ran out of energy or magic charges or whatever the hell idk + ai_controller?.set_blackboard_key(BB_GUNMIMIC_GUN_EMPTY, TRUE) + ai_controller?.CancelActions() // Stop our firing behavior so we can plan melee + else + ai_controller?.set_blackboard_key(BB_GUNMIMIC_GUN_EMPTY, FALSE) + gun.fire_gun(target, user = src, flag = FALSE, params = modifiers) //still make like a cool click click sound if trying to fire empty + +/mob/living/basic/mimic/copy/ranged/proc/magazine_useless(obj/item/gun/ballistic/ballistic) + if(isnull(ballistic.magazine) || !length(ballistic.magazine.stored_ammo)) + return TRUE + // is there ATLEAST one unspent round (for the sake of revolvers or a magazine somehow having spent rounds in it) + for(var/obj/item/ammo_casing/thing as anything in ballistic.magazine.stored_ammo) + if(ispath(thing)) + return FALSE // unspent + if(!isnull(thing.loaded_projectile)) + return FALSE //unspent + return TRUE + +/mob/living/basic/mimic/copy/ranged/CopyObject(obj/item/gun/original, mob/living/creator, destroy_original = 0) + if(..()) + obj_damage = 0 + melee_damage_upper = original.force + melee_damage_lower = original.force - max(0, (original.force / 2)) + +/mob/living/basic/mimic/copy/ranged/CopyObjectVisuals(obj/original) + name = original.name + desc = original.desc + vis_contents += original + +/mob/living/basic/mimic/copy/ranged/can_use_guns(obj/item/gun) + return TRUE + +#undef CANT_INSERT_FULL diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm new file mode 100644 index 0000000000000..9a673b49ec681 --- /dev/null +++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm @@ -0,0 +1,86 @@ +/datum/ai_controller/basic_controller/mimic_crate + idle_behavior = null + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/ai_controller/basic_controller/mimic_copy + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/random_speech/when_has_target/mimic, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/ai_controller/basic_controller/mimic_copy/machine + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/random_speech/when_has_target/mimic_machine, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/ai_planning_subtree/random_speech/when_has_target + /// target key + var/target_key = BB_BASIC_MOB_CURRENT_TARGET + + +/datum/ai_planning_subtree/random_speech/when_has_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(!controller.blackboard_key_exists(target_key)) + return + return ..() + + +/datum/ai_planning_subtree/random_speech/when_has_target/mimic + speech_chance = 30 + emote_hear = list("growls.") + +/datum/ai_planning_subtree/random_speech/when_has_target/mimic_machine + speech_chance = 7 + emote_hear = list() + speak = list( + "HUMANS ARE IMPERFECT!", + "YOU SHALL BE ASSIMILATED!", + "YOU ARE HARMING YOURSELF", + "You have been deemed hazardous. Will you comply?", + "My logic is undeniable.", + "One of us.", + "FLESH IS WEAK", + "THIS ISN'T WAR, THIS IS EXTERMINATION!", + ) + +/datum/ai_planning_subtree/random_speech/when_has_target/mimic/gun + emote_see = list("aims menacingly!") + +/datum/ai_controller/basic_controller/mimic_copy/gun + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_GUNMIMIC_GUN_EMPTY = FALSE, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/random_speech/when_has_target/mimic/gun, + /datum/ai_planning_subtree/gun_mimic_attack_subtree, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/ai_planning_subtree/gun_mimic_attack_subtree + +/datum/ai_planning_subtree/gun_mimic_attack_subtree/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + . = ..() + if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) + return + if(controller.blackboard[BB_GUNMIMIC_GUN_EMPTY]) + return + controller.queue_behavior(/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) + return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions. diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm deleted file mode 100644 index 0d8c1d86bdd40..0000000000000 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ /dev/null @@ -1,423 +0,0 @@ -/// Mimics can't be made out of these objects -GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( - /obj/structure/table, - /obj/structure/cable, - /obj/structure/window, - /obj/structure/blob, -))) - -/mob/living/simple_animal/hostile/mimic - name = "crate" - desc = "A rectangular steel crate." - icon = 'icons/obj/storage/crates.dmi' - icon_state = "crate" - icon_living = "crate" - - response_help_continuous = "touches" - response_help_simple = "touch" - response_disarm_continuous = "pushes" - response_disarm_simple = "push" - speed = 0 - maxHealth = 250 - health = 250 - gender = NEUTER - mob_biotypes = NONE - pass_flags = PASSFLAPS - - harm_intent_damage = 5 - melee_damage_lower = 8 - melee_damage_upper = 12 - attack_sound = 'sound/items/weapons/punch1.ogg' - emote_taunt = list("growls") - speak_emote = list("creaks") - taunt_chance = 30 - - atmos_requirements = null - minbodytemp = 0 - - faction = list(FACTION_MIMIC) - move_to_delay = 9 - del_on_death = 1 - ///A cap for items in the mimic. Prevents the mimic from eating enough stuff to cause lag when opened. - var/storage_capacity = 50 - ///A cap for mobs. Mobs count towards the item cap. Same purpose as above. - var/mob_storage_capacity = 10 - -// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. -/mob/living/simple_animal/hostile/mimic/crate - attack_verb_continuous = "bites" - attack_verb_simple = "bite" - speak_emote = list("clatters") - stop_automated_movement = 1 - wander = 0 - var/attempt_open = FALSE - -// Pickup loot -/mob/living/simple_animal/hostile/mimic/crate/Initialize(mapload) - . = ..() - if(mapload) //eat shit - for(var/obj/item/I in loc) - I.forceMove(src) - -/mob/living/simple_animal/hostile/mimic/crate/DestroyPathToTarget() - ..() - if(prob(90)) - icon_state = "[initial(icon_state)]open" - else - icon_state = initial(icon_state) - -/mob/living/simple_animal/hostile/mimic/crate/ListTargets() - if(attempt_open) - return ..() - return ..(1) - -/mob/living/simple_animal/hostile/mimic/crate/FindTarget() - . = ..() - if(.) - trigger() - -/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget(atom/attacked_target) - . = ..() - if(.) - icon_state = initial(icon_state) - if(prob(15) && iscarbon(target)) - var/mob/living/carbon/C = target - C.Paralyze(40) - C.visible_message(span_danger("\The [src] knocks down \the [C]!"), \ - span_userdanger("\The [src] knocks you down!")) - -/mob/living/simple_animal/hostile/mimic/crate/proc/trigger() - if(!attempt_open) - visible_message("[src] starts to move!") - attempt_open = TRUE - -/mob/living/simple_animal/hostile/mimic/crate/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - trigger() - . = ..() - -/mob/living/simple_animal/hostile/mimic/crate/LoseTarget() - ..() - icon_state = initial(icon_state) - -/mob/living/simple_animal/hostile/mimic/crate/death() - var/obj/structure/closet/crate/C = new(get_turf(src)) - // Put loot in crate - for(var/obj/O in src) - O.forceMove(C) - ..() - -/mob/living/simple_animal/hostile/mimic/copy - health = 100 - maxHealth = 100 - mob_biotypes = MOB_SPECIAL - var/mob/living/creator = null // the creator - var/destroy_objects = 0 - var/knockdown_people = 0 - var/static/mutable_appearance/googly_eyes = mutable_appearance('icons/mob/simple/mob.dmi', "googly_eyes") - var/overlay_googly_eyes = TRUE - var/idledamage = TRUE - -/mob/living/simple_animal/hostile/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = 0, no_googlies = FALSE) - . = ..() - ADD_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // They won't remember their original contents upon ressurection and would just be floating eyes - if (no_googlies) - overlay_googly_eyes = FALSE - CopyObject(copy, creator, destroy_original) - -/mob/living/simple_animal/hostile/mimic/copy/Life(seconds_per_tick = SSMOBS_DT, times_fired) - ..() - if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize - adjustBruteLoss(0.5 * seconds_per_tick) - for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell - death() - -/mob/living/simple_animal/hostile/mimic/copy/death() - for(var/atom/movable/M in src) - M.forceMove(get_turf(src)) - ..() - -/mob/living/simple_animal/hostile/mimic/copy/ListTargets() - . = ..() - return . - creator - -/mob/living/simple_animal/hostile/mimic/copy/wabbajack(what_to_randomize, change_flags = WABBAJACK) - visible_message(span_warning("[src] resists polymorphing into a new creature!")) - -/mob/living/simple_animal/hostile/mimic/copy/animate_atom_living(mob/living/owner) - change_owner(owner) - -/mob/living/simple_animal/hostile/mimic/copy/proc/change_owner(mob/owner) - if(isnull(owner) || creator == owner) - return - LoseTarget() - creator = owner - faction |= REF(owner) - -/mob/living/simple_animal/hostile/mimic/copy/proc/check_object(obj/target) - return ((isitem(target) || isstructure(target)) && !is_type_in_typecache(target, GLOB.animatable_blacklist)) - -/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/user, destroy_original = 0) - if(destroy_original || check_object(O)) - O.forceMove(src) - name = O.name - desc = O.desc - icon = O.icon - icon_state = O.icon_state - icon_living = icon_state - copy_overlays(O) - if (overlay_googly_eyes) - add_overlay(googly_eyes) - if(isstructure(O) || ismachinery(O)) - health = (anchored * 50) + 50 - destroy_objects = 1 - if(O.density && O.anchored) - knockdown_people = 1 - melee_damage_lower *= 2 - melee_damage_upper *= 2 - else if(isitem(O)) - var/obj/item/I = O - health = 15 * I.w_class - melee_damage_lower = 2 + I.force - melee_damage_upper = 2 + I.force - move_to_delay = 2 * I.w_class + 1 - maxHealth = health - if(user) - creator = user - faction += "[REF(creator)]" // very unique - if(destroy_original) - qdel(O) - return 1 - -/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings() - if(destroy_objects) - ..() - -/mob/living/simple_animal/hostile/mimic/copy/AttackingTarget(atom/attacked_target) - . = ..() - if(knockdown_people && . && prob(15) && iscarbon(target)) - var/mob/living/carbon/C = target - C.Paralyze(40) - C.visible_message(span_danger("\The [src] knocks down \the [C]!"), \ - span_userdanger("\The [src] knocks you down!")) - -/mob/living/simple_animal/hostile/mimic/copy/machine - speak = list( - "HUMANS ARE IMPERFECT!", "YOU SHALL BE ASSIMILATED!", "YOU ARE HARMING YOURSELF", "You have been deemed hazardous. Will you comply?", \ - "My logic is undeniable.", "One of us.", "FLESH IS WEAK", "THIS ISN'T WAR, THIS IS EXTERMINATION!", - ) - speak_chance = 7 - -/mob/living/simple_animal/hostile/mimic/copy/machine/CanAttack(atom/the_target) - if(the_target == creator) // Don't attack our creator AI. - return 0 - if(iscyborg(the_target)) - var/mob/living/silicon/robot/R = the_target - if(R.connected_ai == creator) // Only attack robots that aren't synced to our creator AI. - return 0 - return ..() - -/mob/living/simple_animal/hostile/mimic/copy/ranged - var/obj/item/gun/TrueGun = null - var/obj/item/gun/magic/Zapstick - var/obj/item/gun/ballistic/Pewgun - var/obj/item/gun/energy/Zapgun - -/mob/living/simple_animal/hostile/mimic/copy/ranged/CopyObject(obj/O, mob/living/creator, destroy_original = 0) - if(..()) - emote_see = list("aims menacingly") - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE //needed? seems weird for them to do so - ranged = 1 - retreat_distance = 1 //just enough to shoot - minimum_distance = 6 - var/obj/item/gun/G = O - melee_damage_upper = G.force - melee_damage_lower = G.force - max(0, (G.force / 2)) - move_to_delay = 2 * G.w_class + 1 - projectilesound = G.fire_sound - TrueGun = G - if(istype(G, /obj/item/gun/magic)) - Zapstick = G - var/obj/item/ammo_casing/magic/M = Zapstick.ammo_type - projectiletype = initial(M.projectile_type) - if(istype(G, /obj/item/gun/ballistic)) - Pewgun = G - var/obj/item/ammo_box/magazine/M = Pewgun.spawn_magazine_type - casingtype = initial(M.ammo_type) - if(istype(G, /obj/item/gun/energy)) - Zapgun = G - var/selectfiresetting = Zapgun.select - var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting] - projectiletype = initial(E.projectile_type) - -/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target) - if(Zapgun) - if(Zapgun.cell) - var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select] - if(Zapgun.cell.charge >= shot.e_cost) - Zapgun.cell.use(shot.e_cost) - Zapgun.update_appearance() - ..() - else if(Zapstick) - if(Zapstick.charges) - Zapstick.charges-- - Zapstick.update_appearance() - ..() - else if(Pewgun) - if(Pewgun.chambered) - if(Pewgun.chambered.loaded_projectile) - qdel(Pewgun.chambered.loaded_projectile) - Pewgun.chambered.loaded_projectile = null //because qdel takes too long, ensures icon update - Pewgun.chambered.update_appearance() - ..() - else - visible_message(span_danger("The [src] clears a jam!")) - Pewgun.chambered.forceMove(loc) //rip revolver immersions, blame shotgun snowflake procs - Pewgun.chambered = null - if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) - Pewgun.chambered = Pewgun.magazine.get_round() - Pewgun.chambered.forceMove(Pewgun) - Pewgun.update_appearance() - else if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) //only true for pumpguns i think - Pewgun.chambered = Pewgun.magazine.get_round() - Pewgun.chambered.forceMove(Pewgun) - visible_message(span_danger("The [src] cocks itself!")) - else - ranged = 0 //BANZAIIII - retreat_distance = 0 - minimum_distance = 1 - return - icon_state = TrueGun.icon_state - icon_living = TrueGun.icon_state - -/mob/living/simple_animal/hostile/mimic/xenobio - health = 210 - maxHealth = 210 - attack_verb_continuous = "bites" - attack_verb_simple = "bite" - speak_emote = list("clatters") - gold_core_spawnable = HOSTILE_SPAWN - var/opened = FALSE - var/open_sound = 'sound/machines/crate/crate_open.ogg' - var/close_sound = 'sound/machines/crate/crate_close.ogg' - ///sound played when the mimic attempts to eat more items than it can - var/full_sound = 'sound/items/trayhit/trayhit2.ogg' - var/max_mob_size = MOB_SIZE_HUMAN - var/locked = FALSE - var/datum/action/innate/mimic/lock/lock - -/mob/living/simple_animal/hostile/mimic/xenobio/Initialize(mapload) - . = ..() - lock = new - lock.Grant(src) - -/mob/living/simple_animal/hostile/mimic/xenobio/AttackingTarget(atom/attacked_target) - if(src == target) - toggle_open() - return - return ..() - -/mob/living/simple_animal/hostile/mimic/xenobio/attack_hand(mob/living/carbon/human/user, list/modifiers) - . = ..() - if(user.combat_mode) - return - toggle_open() - -/mob/living/simple_animal/hostile/mimic/xenobio/death() - var/obj/structure/closet/crate/C = new(get_turf(src)) - // Put loot in crate - for(var/atom/movable/AM in src) - AM.forceMove(C) - return ..() - -/mob/living/simple_animal/hostile/mimic/xenobio/CanAllowThrough(atom/movable/mover, border_dir) - . = ..() - if(istype(mover, /obj/structure/closet)) - return FALSE -/** -* Used to open and close the mimic -* -* Will insert tile contents into the mimic when closing -* Will dump mimic contents into the time when opening -* Does nothing if the mimic locked itself -*/ -/mob/living/simple_animal/hostile/mimic/xenobio/proc/toggle_open() - if(locked) - return - if(!opened) - ADD_TRAIT(src, TRAIT_UNDENSE, MIMIC_TRAIT) - opened = TRUE - icon_state = "crateopen" - playsound(src, open_sound, 50, TRUE) - for(var/atom/movable/AM in src) - AM.forceMove(loc) - else - REMOVE_TRAIT(src, TRAIT_UNDENSE, MIMIC_TRAIT) - opened = FALSE - icon_state = "crate" - playsound(src, close_sound, 50, TRUE) - for(var/atom/movable/AM in get_turf(src)) - if(AM != src && insert(AM) == -1) - playsound(src, full_sound, 50, TRUE) - break -/** -* Called by toggle_open to put items inside the mimic when it's being closed -* -* Will return -1 if the insertion fails due to the storage capacity of the mimic having been reached -* Will return FALSE if insertion fails -* Will return TRUE if insertion succeeds -* Arguments: -* * AM - item to be inserted -*/ -/mob/living/simple_animal/hostile/mimic/xenobio/proc/insert(atom/movable/AM) - if(contents.len >= storage_capacity) - return -1 - if(insertion_allowed(AM)) - AM.forceMove(src) - return TRUE - else - return FALSE - -/mob/living/simple_animal/hostile/mimic/xenobio/proc/insertion_allowed(atom/movable/AM) - if(ismob(AM)) - if(!isliving(AM)) //Don't let ghosts and such get trapped in the beast. - return FALSE - var/mob/living/L = AM - if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs()) - return FALSE - if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items. - if(L.density || L.mob_size > max_mob_size) - return FALSE - var/mobs_stored = 0 - for(var/mob/living/M in contents) - mobs_stored++ - if(mobs_stored >= mob_storage_capacity) - return FALSE - L.stop_pulling() - - else if(istype(AM, /obj/structure/closet)) - return FALSE - else if(isobj(AM)) - if(AM.anchored || AM.has_buckled_mobs()) - return FALSE - else if(isitem(AM) && !HAS_TRAIT(AM, TRAIT_NODROP)) - return TRUE - else - return FALSE - return TRUE - -/datum/action/innate/mimic - background_icon_state = "bg_default" - overlay_icon_state = "bg_default_border" - -/datum/action/innate/mimic/lock - name = "Lock/Unlock" - desc = "Toggle preventing yourself from being opened or closed." - -/datum/action/innate/mimic/lock/Activate() - var/mob/living/simple_animal/hostile/mimic/xenobio/M = owner - M.locked = !M.locked - if(!M.locked) - to_chat(M, span_warning("You loosen up, allowing yourself to be opened and closed.")) - else - to_chat(M, span_warning("You stiffen up, preventing anyone from opening or closing you.")) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c8e8a0653ed9d..abaf7883cb888 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -558,7 +558,7 @@ return TRUE /obj/item/gun/animate_atom_living(mob/living/owner) - new /mob/living/simple_animal/hostile/mimic/copy/ranged(drop_location(), src, owner) + new /mob/living/basic/mimic/copy/ranged(drop_location(), src, owner) /obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer) if(!ishuman(user) || !ishuman(target)) diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 55161807eb46e..e82a607a9bfb8 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -57,12 +57,6 @@ /mob/living/simple_animal/hostile/megafauna/legion/small, /mob/living/simple_animal/hostile/megafauna/wendigo, /mob/living/simple_animal/hostile/megafauna/wendigo/noportal, - /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/mimic/copy, - /mob/living/simple_animal/hostile/mimic/copy/machine, - /mob/living/simple_animal/hostile/mimic/copy/ranged, - /mob/living/simple_animal/hostile/mimic/crate, - /mob/living/simple_animal/hostile/mimic/xenobio, /mob/living/simple_animal/hostile/ooze, /mob/living/simple_animal/hostile/ooze/gelatinous, /mob/living/simple_animal/hostile/ooze/grapes, diff --git a/tgstation.dme b/tgstation.dme index 255baf3b398ec..b7f67bf487db3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5072,6 +5072,8 @@ #include "code\modules\mob\living\basic\ruin_defender\mad_piano.dm" #include "code\modules\mob\living\basic\ruin_defender\skeleton.dm" #include "code\modules\mob\living\basic\ruin_defender\stickman.dm" +#include "code\modules\mob\living\basic\ruin_defender\mimic\mimic.dm" +#include "code\modules\mob\living\basic\ruin_defender\mimic\mimic_ai.dm" #include "code\modules\mob\living\basic\ruin_defender\wizard\wizard.dm" #include "code\modules\mob\living\basic\ruin_defender\wizard\wizard_ai.dm" #include "code\modules\mob\living\basic\ruin_defender\wizard\wizard_spells.dm" @@ -5348,7 +5350,6 @@ #include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" #include "code\modules\mob\living\simple_animal\hostile\illusion.dm" -#include "code\modules\mob\living\simple_animal\hostile\mimic.dm" #include "code\modules\mob\living\simple_animal\hostile\ooze.dm" #include "code\modules\mob\living\simple_animal\hostile\vatbeast.dm" #include "code\modules\mob\living\simple_animal\hostile\zombie.dm" diff --git a/tools/UpdatePaths/Scripts/88910_mimicbasicmobs.txt b/tools/UpdatePaths/Scripts/88910_mimicbasicmobs.txt new file mode 100644 index 0000000000000..b7a012ed1d9b0 --- /dev/null +++ b/tools/UpdatePaths/Scripts/88910_mimicbasicmobs.txt @@ -0,0 +1,5 @@ +/mob/living/simple_animal/hostile/mimic : /mob/living/basic/mimic/crate{@OLD} +/mob/living/simple_animal/hostile/mimic/crate : /mob/living/basic/mimic/crate{@OLD} +/mob/living/simple_animal/hostile/mimic/xenobio : /mob/living/basic/mimic/crate/xenobio{@OLD} +/mob/living/simple_animal/hostile/mimic/copy : /mob/living/basic/mimic/copy{@OLD} +/mob/living/simple_animal/hostile/mimic/copy/ranged : /mob/living/basic/mimic/copy/ranged{@OLD} From 192b698e4d9a6b7bee423ba96c9b547c4c01cb69 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 23:48:32 +0000 Subject: [PATCH 18/23] Automatic changelog for PR #88910 [ci skip] --- html/changelogs/AutoChangeLog-pr-88910.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-88910.yml diff --git a/html/changelogs/AutoChangeLog-pr-88910.yml b/html/changelogs/AutoChangeLog-pr-88910.yml new file mode 100644 index 0000000000000..29748f8021ac2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-88910.yml @@ -0,0 +1,5 @@ +author: "mc-oofert" +delete-after: True +changes: + - refactor: "mimics (bolt of animation, malf ai Machine Override, etc) are basicmobs" + - bugfix: "crate mimics may now be opened" \ No newline at end of file From 2d156a0294fc75ce14cdf2910f0b3f02872e0c20 Mon Sep 17 00:00:00 2001 From: NamelessFairy <40036527+NamelessFairy@users.noreply.github.com> Date: Mon, 20 Jan 2025 00:27:06 +0000 Subject: [PATCH 19/23] Cancelling stray admin configured syndicate cargo-pods actually works, also adds missing uplinks to customization (#89047) ## About The Pull Request Must have missed this in initial tests. Cancelling the stray syndicate cargo pod event while modifying the telecrystal value or uplink type did not cancel it. Now it does. Bonus - Uplinks that have been introduced since customization was added have been added ## Why It's Good For The Game I may have accidently dropped a syndicate cargo pod on a station today and I'd prefer to do it intentionally. ## Changelog :cl: fix: Admin fired stray syndicate cargo pods will not rebel against admin whims and launch themselves when cancelled. admin: Admins have new categories to fill syndicate cargo pods with. /:cl: --- code/modules/events/stray_cargo.dm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/code/modules/events/stray_cargo.dm b/code/modules/events/stray_cargo.dm index 0be1138f59a59..0514af5764e3d 100644 --- a/code/modules/events/stray_cargo.dm +++ b/code/modules/events/stray_cargo.dm @@ -149,7 +149,7 @@ var/admin_selected_pack = tgui_alert(usr,"Customize Pod contents?", "Pod Contents", list("Yes", "No", "Cancel")) switch(admin_selected_pack) if("Yes") - override_contents() + return override_contents() if("No") pack_type_override = null else @@ -161,7 +161,14 @@ var/pack_telecrystals = tgui_input_number(usr, "Please input crate's value in telecrystals.", "Set Telecrystals.", 30) if(isnull(pack_telecrystals)) return ADMIN_CANCEL_EVENT - var/list/possible_uplinks = list("Traitor" = UPLINK_TRAITORS, "Nuke Op" = UPLINK_NUKE_OPS, "Clown Op" = UPLINK_CLOWN_OPS) + var/list/possible_uplinks = list( + "Traitor" = UPLINK_TRAITORS, + "Nuke Op" = UPLINK_NUKE_OPS, + "Clown Op" = UPLINK_CLOWN_OPS, + "Lone Op" = UPLINK_LONE_OP, + "Infiltrator" = UPLINK_INFILTRATORS, + "Spy" = UPLINK_SPY + ) var/uplink_type = tgui_input_list(usr, "Choose uplink to draw items from.", "Choose uplink type.", possible_uplinks) var/selection if(!isnull(uplink_type)) From 1ad83be59038571a2e8184f73b562804f4d86deb Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 00:27:40 +0000 Subject: [PATCH 20/23] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-88910.yml | 5 ----- html/changelogs/AutoChangeLog-pr-89117.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89118.yml | 4 ---- html/changelogs/AutoChangeLog-pr-89122.yml | 8 -------- html/changelogs/AutoChangeLog-pr-89131.yml | 4 ---- html/changelogs/archive/2025-01.yml | 21 +++++++++++++++++++++ 6 files changed, 21 insertions(+), 25 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-88910.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89117.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89118.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89122.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-89131.yml diff --git a/html/changelogs/AutoChangeLog-pr-88910.yml b/html/changelogs/AutoChangeLog-pr-88910.yml deleted file mode 100644 index 29748f8021ac2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-88910.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "mc-oofert" -delete-after: True -changes: - - refactor: "mimics (bolt of animation, malf ai Machine Override, etc) are basicmobs" - - bugfix: "crate mimics may now be opened" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89117.yml b/html/changelogs/AutoChangeLog-pr-89117.yml deleted file mode 100644 index 0695ea964d4f0..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89117.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - image: "Made the unholy water flask darker" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89118.yml b/html/changelogs/AutoChangeLog-pr-89118.yml deleted file mode 100644 index c49bafe2a57aa..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89118.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - image: "Resprited default and mirage grenades" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89122.yml b/html/changelogs/AutoChangeLog-pr-89122.yml deleted file mode 100644 index 74c844109328a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89122.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "Y0SH1M4S73R" -delete-after: True -changes: - - refactor: "Wires and assemblies have been refactored to have directionality to them. This mostly makes it so that assemblies can only be attached to wires it would make sense for them to be attached to." - - qol: "Pressure plates can now also accept igniters, condensers, flashes, assembly shells, and door controllers." - - rscadd: "Undertile circuit shells. They only work when placed under floor tiles, but support USB cables and use APC power instead of cell power." - - rscadd: "Wallmounted circuit shells. Large shells that support USB cables and use APC power instead of cell power." - - rscadd: "Wire bundle component. Adds a number of wires to the circuit proportional to the capacity of the shell, allowing you to use assemblies in circuit logic." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-89131.yml b/html/changelogs/AutoChangeLog-pr-89131.yml deleted file mode 100644 index 4b1a73b6c3e31..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-89131.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "RengaN02" -delete-after: True -changes: - - bugfix: "Fixed Engine Diagnostic surgery" \ No newline at end of file diff --git a/html/changelogs/archive/2025-01.yml b/html/changelogs/archive/2025-01.yml index 72a590d411f3c..d0707a54087d2 100644 --- a/html/changelogs/archive/2025-01.yml +++ b/html/changelogs/archive/2025-01.yml @@ -526,3 +526,24 @@ - image: yet another medkit resprite SmArtKar: - bugfix: Fixed active turfs on the new Turreted Outpost ruin. +2025-01-20: + RengaN02: + - bugfix: Fixed Engine Diagnostic surgery + SmArtKar: + - image: Resprited default and mirage grenades + - image: Made the unholy water flask darker + Y0SH1M4S73R: + - refactor: Wires and assemblies have been refactored to have directionality to + them. This mostly makes it so that assemblies can only be attached to wires + it would make sense for them to be attached to. + - qol: Pressure plates can now also accept igniters, condensers, flashes, assembly + shells, and door controllers. + - rscadd: Undertile circuit shells. They only work when placed under floor tiles, + but support USB cables and use APC power instead of cell power. + - rscadd: Wallmounted circuit shells. Large shells that support USB cables and use + APC power instead of cell power. + - rscadd: Wire bundle component. Adds a number of wires to the circuit proportional + to the capacity of the shell, allowing you to use assemblies in circuit logic. + mc-oofert: + - refactor: mimics (bolt of animation, malf ai Machine Override, etc) are basicmobs + - bugfix: crate mimics may now be opened From 1bf9e41fa58079de8d735019f118238fb48a3006 Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 04:58:59 +0000 Subject: [PATCH 21/23] Automatic changelog for PR #89047 [ci skip] --- html/changelogs/AutoChangeLog-pr-89047.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89047.yml diff --git a/html/changelogs/AutoChangeLog-pr-89047.yml b/html/changelogs/AutoChangeLog-pr-89047.yml new file mode 100644 index 0000000000000..784e95a25ddc0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89047.yml @@ -0,0 +1,5 @@ +author: "NamelessFairy" +delete-after: True +changes: + - bugfix: "Admin fired stray syndicate cargo pods will not rebel against admin whims and launch themselves when cancelled." + - admin: "Admins have new categories to fill syndicate cargo pods with." \ No newline at end of file From 059d17a2778db5e48fcc2852bb6e314fe953c8b2 Mon Sep 17 00:00:00 2001 From: Pickle-Coding <58013024+Pickle-Coding@users.noreply.github.com> Date: Mon, 20 Jan 2025 05:31:31 +0000 Subject: [PATCH 22/23] Fixes HFR moderator overflow runtime. (#89095) ## About The Pull Request Fixes a runtime when the HFR moderator overflows. This should also let the HFR continue leaking its moderator contents after a crack is created. I didn't test this but it's quite simple really. ## Why It's Good For The Game Closes #70617 ## Changelog :cl: fix: Fixes HFR moderator leaking not leaking properly when a part is cracked. /:cl: --- .../components/fusion/hfr_main_processes.dm | 2 +- .../machinery/components/fusion/hfr_procs.dm | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm index 27cb78bb26ce7..e36d99cb6d73d 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm @@ -25,7 +25,7 @@ fusion_process(seconds_per_tick) // Note that we process damage/healing even if the fusion process aborts. // Running out of fuel won't save you if your moderator and coolant are exploding on their own. - check_spill() + process_moderator_overflow() process_damageheal(seconds_per_tick) check_alert() if (start_power) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm index bc27ab0a42e36..2c77ac829b735 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm @@ -569,18 +569,27 @@ * HFR cracking related procs */ +/** + * Checks for any hypertorus part that is cracked and returns it if found, otherwise returns null. + */ /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_cracked_parts() for(var/obj/machinery/atmospherics/components/unary/hypertorus/part in machine_parts) if(part.cracked) - return TRUE - return FALSE + return part -/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/create_crack() +/** + * Causes a random hypertorus part in machine_parts to become cracked and update their appearance. + * Returns the hypertorus part. + */ +/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/create_crack() as /obj/machinery/atmospherics/components/unary/hypertorus var/obj/machinery/atmospherics/components/unary/hypertorus/part = pick(machine_parts) part.cracked = TRUE part.update_appearance() return part +/** + * Takes a ratio portion of target_mix and moves it to the origin's location's air. + */ /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/spill_gases(obj/origin, datum/gas_mixture/target_mix, ratio) var/datum/gas_mixture/remove_mixture = target_mix.remove_ratio(ratio) var/turf/origin_turf = origin.loc @@ -588,8 +597,12 @@ return origin_turf.assume_air(remove_mixture) -/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_spill(seconds_per_tick) +/** + * Processes leaking from moderator hypercriticality. + */ +/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/process_moderator_overflow(seconds_per_tick) var/obj/machinery/atmospherics/components/unary/hypertorus/cracked_part = check_cracked_parts() + // Processing of a preexisting crack if any. if (cracked_part) // We have an existing crack var/leak_rate @@ -607,6 +620,7 @@ spill_gases(cracked_part, moderator_internal, ratio = 1 - (1 - leak_rate) ** seconds_per_tick) return + // No crack. Check for conditions to cause a leak and create a crack if possible. if (moderator_internal.total_moles() < HYPERTORUS_HYPERCRITICAL_MOLES) return cracked_part = create_crack() From 66858d8afd021487c590f3b3302eb4a80dc32b2e Mon Sep 17 00:00:00 2001 From: "tgstation-ci[bot]" <179393467+tgstation-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 06:02:52 +0000 Subject: [PATCH 23/23] Automatic changelog for PR #89095 [ci skip] --- html/changelogs/AutoChangeLog-pr-89095.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-89095.yml diff --git a/html/changelogs/AutoChangeLog-pr-89095.yml b/html/changelogs/AutoChangeLog-pr-89095.yml new file mode 100644 index 0000000000000..4e52e9a2c38cc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-89095.yml @@ -0,0 +1,4 @@ +author: "Pickle-Coding" +delete-after: True +changes: + - bugfix: "Fixes HFR moderator leaking not leaking properly when a part is cracked." \ No newline at end of file